dsagen.c 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  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. //
  31. // This isn't very efficient. If anyone has a better
  32. // idea, mail presotto@closedmind.org
  33. exp = mpnew(0);
  34. g = mpnew(0);
  35. r = mpnew(0);
  36. mpsub(pub->p, mpone, exp);
  37. mpdiv(exp, pub->q, exp, r);
  38. if(mpcmp(r, mpzero) != 0)
  39. sysfatal("dsagen foul up");
  40. while(1){
  41. mprand(bits, genrandom, g);
  42. mpmod(g, pub->p, g);
  43. mpexp(g, exp, pub->p, pub->alpha);
  44. if(mpcmp(pub->alpha, mpone) != 0)
  45. break;
  46. }
  47. mpfree(g);
  48. mpfree(exp);
  49. // create the secret key
  50. mprand(bits, genrandom, priv->secret);
  51. mpmod(priv->secret, pub->p, priv->secret);
  52. mpexp(pub->alpha, priv->secret, pub->p, pub->key);
  53. return priv;
  54. }