dsasign.c 969 B

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. #include "os.h"
  2. #include <mp.h>
  3. #include <libsec.h>
  4. DSAsig*
  5. dsasign(DSApriv *priv, mpint *m)
  6. {
  7. DSApub *pub = &priv->pub;
  8. DSAsig *sig;
  9. mpint *qm1, *k, *kinv, *r, *s;
  10. mpint *q = pub->q, *p = pub->p, *alpha = pub->alpha;
  11. int qlen = mpsignif(q);
  12. qm1 = mpnew(0);
  13. kinv = mpnew(0);
  14. r = mpnew(0);
  15. s = mpnew(0);
  16. k = mpnew(0);
  17. mpsub(pub->q, mpone, qm1);
  18. // find a k that has an inverse mod q
  19. while(1){
  20. mprand(qlen, genrandom, k);
  21. if((mpcmp(mpone, k) > 0) || (mpcmp(k, pub->q) >= 0))
  22. continue;
  23. mpextendedgcd(k, q, r, kinv, s);
  24. if(mpcmp(r, mpone) != 0)
  25. sysfatal("dsasign: pub->q not prime");
  26. break;
  27. }
  28. // make kinv positive
  29. mpmod(kinv, pub->q, kinv);
  30. // r = ((alpha**k) mod p) mod q
  31. mpexp(alpha, k, p, r);
  32. mpmod(r, q, r);
  33. // s = (kinv*(m + ar)) mod q
  34. mpmul(r, priv->secret, s);
  35. mpadd(s, m, s);
  36. mpmul(s, kinv, s);
  37. mpmod(s, q, s);
  38. sig = dsasigalloc();
  39. sig->r = r;
  40. sig->s = s;
  41. mpfree(qm1);
  42. mpfree(k);
  43. mpfree(kinv);
  44. return sig;
  45. }