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