Example #1
0
// use extended gcd to find the multiplicative inverse
// res = b**-1 mod m
void
mpinvert(mpint *b, mpint *m, mpint *res)
{
	mpint *dc1, *dc2;	// don't care

	dc1 = mpnew(0);
	dc2 = mpnew(0);
	mpextendedgcd(b, m, dc1, res, dc2);
	if(mpcmp(dc1, mpone) != 0)
		abort();
	mpmod(res, m, res);
	mpfree(dc1);
	mpfree(dc2);
}
Example #2
0
DSAsig*
dsasign(DSApriv *priv, mpint *m)
{
	DSApub *pub = &priv->pub;
	DSAsig *sig;
	mpint *qm1, *k, *kinv, *r, *s;
	mpint *q = pub->q, *p = pub->p, *alpha = pub->alpha;
	int qlen = mpsignif(q);

	qm1 = mpnew(0);
	kinv = mpnew(0);
	r = mpnew(0);
	s = mpnew(0);
	k = mpnew(0);
	mpsub(pub->q, mpone, qm1);

	// find a k that has an inverse mod q
	while(1){
		mprand(qlen, genrandom, k);
		if((mpcmp(mpone, k) > 0) || (mpcmp(k, qm1) >= 0))
			continue;
		mpextendedgcd(k, q, r, kinv, s);
		if(mpcmp(r, mpone) != 0)
			continue;
		break;
	}

  	// make kinv positive
	mpmod(kinv, qm1, kinv);

	// r = ((alpha**k) mod p) mod q
	mpexp(alpha, k, p, r);
	mpmod(r, q, r);

	// s = (kinv*(m + ar)) mod q
	mpmul(r, priv->secret, s);
	mpadd(s, m, s);
	mpmul(s, kinv, s);
	mpmod(s, q, s);

	sig = dsasigalloc();
	sig->r = r;
	sig->s = s;
	mpfree(qm1);
	mpfree(k);
	mpfree(kinv);
	return sig;
}
Example #3
0
int
dsaverify(DSApub *pub, DSAsig *sig, mpint *m)
{
	int rv = -1;
	mpint *u1, *u2, *v, *sinv;

	if(sig->r->sign < 0 || mpcmp(sig->r, pub->q) >= 0)
		return rv;
	if(sig->s->sign < 0 || mpcmp(sig->s, pub->q) >= 0)
		return rv;
	u1 = mpnew(0);
	u2 = mpnew(0);
	v = mpnew(0);
	sinv = mpnew(0);

	// find (s**-1) mod q, make sure it exists
	mpextendedgcd(sig->s, pub->q, u1, sinv, v);
	if(mpcmp(u1, mpone) != 0)
		goto out;

	// u1 = (sinv * m) mod q, u2 = (r * sinv) mod q
	mpmul(sinv, m, u1);
	mpmod(u1, pub->q, u1);
	mpmul(sig->r, sinv, u2);
	mpmod(u2, pub->q, u2);

	// v = (((alpha**u1)*(key**u2)) mod p) mod q
	mpexp(pub->alpha, u1, pub->p, sinv);
	mpexp(pub->key, u2, pub->p, v);
	mpmul(sinv, v, v);
	mpmod(v, pub->p, v);
	mpmod(v, pub->q, v);

	if(mpcmp(v, sig->r) == 0)
		rv = 0;
out:
	mpfree(v);
	mpfree(u1);
	mpfree(u2);
	mpfree(sinv);
	return rv;
}
Example #4
0
RSApriv*
rsagen(int nlen, int elen, int rounds)
{
	mpint *p, *q, *e, *d, *phi, *n, *t1, *t2, *kp, *kq, *c2;
	RSApriv *rsa;

	p = mpnew(nlen/2);
	q = mpnew(nlen/2);
	n = mpnew(nlen);
	e = mpnew(elen);
	d = mpnew(0);
	phi = mpnew(nlen);

	// create the prime factors and euclid's function
	genprime(p, nlen/2, rounds);
	genprime(q, nlen - mpsignif(p) + 1, rounds);
	mpmul(p, q, n);
	mpsub(p, mpone, e);
	mpsub(q, mpone, d);
	mpmul(e, d, phi);

	// find an e relatively prime to phi
	t1 = mpnew(0);
	t2 = mpnew(0);
	mprand(elen, genrandom, e);
	if(mpcmp(e,mptwo) <= 0)
		itomp(3, e);
	// See Menezes et al. p.291 "8.8 Note (selecting primes)" for discussion
	// of the merits of various choices of primes and exponents.  e=3 is a
	// common and recommended exponent, but doesn't necessarily work here
	// because we chose strong rather than safe primes.
	for(;;){
		mpextendedgcd(e, phi, t1, d, t2);
		if(mpcmp(t1, mpone) == 0)
			break;
		mpadd(mpone, e, e);
	}
	mpfree(t1);
	mpfree(t2);

	// compute chinese remainder coefficient
	c2 = mpnew(0);
	mpinvert(p, q, c2);

	// for crt a**k mod p == (a**(k mod p-1)) mod p
	kq = mpnew(0);
	kp = mpnew(0);
	mpsub(p, mpone, phi);
	mpmod(d, phi, kp);
	mpsub(q, mpone, phi);
	mpmod(d, phi, kq);

	rsa = rsaprivalloc();
	rsa->pub.ek = e;
	rsa->pub.n = n;
	rsa->dk = d;
	rsa->kp = kp;
	rsa->kq = kq;
	rsa->p = p;
	rsa->q = q;
	rsa->c2 = c2;

	mpfree(phi);

	return rsa;
}