#include "os.h" | |
#include <mp.h> | |
#include <libsec.h> | |
EGsig* | |
egsign(EGpriv *priv, mpint *m) | |
{ | |
EGpub *pub = &priv->pub; | |
EGsig *sig; | |
mpint *pm1, *k, *kinv, *r, *s; | |
mpint *p = pub->p, *alpha = pub->alpha; | |
int plen = mpsignif(p); | |
pm1 = mpnew(0); | |
kinv = mpnew(0); | |
r = mpnew(0); | |
s = mpnew(0); | |
k = mpnew(0); | |
mpsub(p, mpone, pm1); | |
while(1){ | |
mprand(plen, genrandom, k); | |
if((mpcmp(mpone, k) > 0) || (mpcmp(k, pm1) >= 0)) | |
continue; | |
mpextendedgcd(k, pm1, r, kinv, s); | |
if(mpcmp(r, mpone) != 0) | |
continue; | |
break; | |
} | |
mpmod(kinv, pm1, kinv); // make kinv positive | |
mpexp(alpha, k, p, r); | |
mpmul(priv->secret, r, s); | |
mpmod(s, pm1, s); | |
mpsub(m, s, s); | |
mpmul(kinv, s, s); | |
mpmod(s, pm1, s); | |
sig = egsigalloc(); | |
sig->r = r; | |
sig->s = s; | |
mpfree(pm1); | |
mpfree(k); | |
mpfree(kinv); | |
return sig; | |
} |