12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 |
- #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.
- //
- // This isn't very efficient. If anyone has a better
- // idea, mail presotto@closedmind.org
- 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;
- }
|