mirror of https://github.com/0intro/conterm
62 lines
1.2 KiB
C
62 lines
1.2 KiB
C
#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;
|
|
}
|