dsagen.c 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. #include "os.h"
  2. #include <mp.h>
  3. #include <libsec.h>
  4. DSApriv*
  5. dsagen(DSApub *opub)
  6. {
  7. DSApub *pub;
  8. DSApriv *priv;
  9. mpint *exp;
  10. mpint *g;
  11. mpint *r;
  12. int bits;
  13. priv = dsaprivalloc();
  14. pub = &priv->pub;
  15. if(opub != nil){
  16. pub->p = mpcopy(opub->p);
  17. pub->q = mpcopy(opub->q);
  18. } else {
  19. pub->p = mpnew(0);
  20. pub->q = mpnew(0);
  21. DSAprimes(pub->q, pub->p, nil);
  22. }
  23. bits = Dbits*pub->p->top;
  24. pub->alpha = mpnew(0);
  25. pub->key = mpnew(0);
  26. priv->secret = mpnew(0);
  27. // find a generator alpha of the multiplicative
  28. // group Z*p, i.e., of order n = p-1. We use the
  29. // fact that q divides p-1 to reduce the exponent.
  30. exp = mpnew(0);
  31. g = mpnew(0);
  32. r = mpnew(0);
  33. mpsub(pub->p, mpone, exp);
  34. mpdiv(exp, pub->q, exp, r);
  35. if(mpcmp(r, mpzero) != 0)
  36. sysfatal("dsagen foul up");
  37. while(1){
  38. mprand(bits, genrandom, g);
  39. mpmod(g, pub->p, g);
  40. mpexp(g, exp, pub->p, pub->alpha);
  41. if(mpcmp(pub->alpha, mpone) != 0)
  42. break;
  43. }
  44. mpfree(g);
  45. mpfree(exp);
  46. // create the secret key
  47. mprand(bits, genrandom, priv->secret);
  48. mpmod(priv->secret, pub->p, priv->secret);
  49. mpexp(pub->alpha, priv->secret, pub->p, pub->key);
  50. return priv;
  51. }