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