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