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 // 36 // This isn't very efficient. If anyone has a better 37 // idea, mail presotto@closedmind.org 38 exp = mpnew(0); 39 g = mpnew(0); 40 r = mpnew(0); 41 mpsub(pub->p, mpone, exp); 42 mpdiv(exp, pub->q, exp, r); 43 if(mpcmp(r, mpzero) != 0) 44 sysfatal("dsagen foul up"); 45 while(1){ 46 mprand(bits, genrandom, g); 47 mpmod(g, pub->p, g); 48 mpexp(g, exp, pub->p, pub->alpha); 49 if(mpcmp(pub->alpha, mpone) != 0) 50 break; 51 } 52 mpfree(g); 53 mpfree(exp); 54 55 // create the secret key 56 mprand(bits, genrandom, priv->secret); 57 mpmod(priv->secret, pub->p, priv->secret); 58 mpexp(pub->alpha, priv->secret, pub->p, pub->key); 59 60 return priv; 61 } 62