|  | #include "os.h" | 
|  | #include <mp.h> | 
|  | #include <libsec.h> | 
|  |  | 
|  | 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; | 
|  | } |