1 #include "os.h" 2 #include <mp.h> 3 #include <libsec.h> 4 5 DSApriv* 6 dsagen(DSApub *opub) 7 { 8 DSApub *pub; 9 DSApriv *priv; 10 mpint *exp; 11 mpint *g; 12 mpint *r; 13 int bits; 14 15 priv = dsaprivalloc(); 16 pub = &priv->pub; 17 18 if(opub != nil){ 19 pub->p = mpcopy(opub->p); 20 pub->q = mpcopy(opub->q); 21 } else { 22 pub->p = mpnew(0); 23 pub->q = mpnew(0); 24 DSAprimes(pub->q, pub->p, nil); 25 } 26 bits = Dbits*pub->p->top; 27 28 pub->alpha = mpnew(0); 29 pub->key = mpnew(0); 30 priv->secret = mpnew(0); 31 32 // find a generator alpha of the multiplicative 33 // group Z*p, i.e., of order n = p-1. We use the 34 // fact that q divides p-1 to reduce the exponent. 35 exp = mpnew(0); 36 g = mpnew(0); 37 r = mpnew(0); 38 mpsub(pub->p, mpone, exp); 39 mpdiv(exp, pub->q, exp, r); 40 if(mpcmp(r, mpzero) != 0) 41 sysfatal("dsagen foul up"); 42 while(1){ 43 mprand(bits, genrandom, g); 44 mpmod(g, pub->p, g); 45 mpexp(g, exp, pub->p, pub->alpha); 46 if(mpcmp(pub->alpha, mpone) != 0) 47 break; 48 } 49 mpfree(g); 50 mpfree(exp); 51 52 // create the secret key 53 mprand(bits, genrandom, priv->secret); 54 mpmod(priv->secret, pub->p, priv->secret); 55 mpexp(pub->alpha, priv->secret, pub->p, pub->key); 56 57 return priv; 58 } 59