| #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; |
| } |