ref: 5b2f81a5670fed4cdee3c64e89b2014125051707
dir: /sys/src/libsec/port/egsign.c/
#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; }