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