#include "os.h" | |
#include <mp.h> | |
#include <libsec.h> | |
DSAsig* | |
dsasign(DSApriv *priv, mpint *m) | |
{ | |
DSApub *pub = &priv->pub; | |
DSAsig *sig; | |
mpint *qm1, *k, *kinv, *r, *s; | |
mpint *q = pub->q, *p = pub->p, *alpha = pub->alpha; | |
int qlen = mpsignif(q); | |
qm1 = mpnew(0); | |
kinv = mpnew(0); | |
r = mpnew(0); | |
s = mpnew(0); | |
k = mpnew(0); | |
mpsub(pub->q, mpone, qm1); | |
// find a k that has an inverse mod q | |
while(1){ | |
mprand(qlen, genrandom, k); | |
if((mpcmp(mpone, k) > 0) || (mpcmp(k, pub->q) >= 0)) | |
continue; | |
mpextendedgcd(k, q, r, kinv, s); | |
if(mpcmp(r, mpone) != 0) | |
sysfatal("dsasign: pub->q not prime"); | |
break; | |
} | |
// make kinv positive | |
mpmod(kinv, pub->q, kinv); | |
// r = ((alpha**k) mod p) mod q | |
mpexp(alpha, k, p, r); | |
mpmod(r, q, r); | |
// s = (kinv*(m + ar)) mod q | |
mpmul(r, priv->secret, s); | |
mpadd(s, m, s); | |
mpmul(s, kinv, s); | |
mpmod(s, q, s); | |
sig = dsasigalloc(); | |
sig->r = r; | |
sig->s = s; | |
mpfree(qm1); | |
mpfree(k); | |
mpfree(kinv); | |
return sig; | |
} |