xref: /plan9/sys/src/cmd/unix/drawterm/libsec/dsagen.c (revision 8ccd4a6360d974db7bd7bbd4f37e7018419ea908)
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