rsagen.c 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. #include "os.h"
  2. #include <mp.h>
  3. #include <libsec.h>
  4. RSApriv*
  5. rsagen(int nlen, int elen, int rounds)
  6. {
  7. mpint *p, *q, *e, *d, *phi, *n, *t1, *t2, *kp, *kq, *c2;
  8. RSApriv *rsa;
  9. p = mpnew(nlen/2);
  10. q = mpnew(nlen/2);
  11. n = mpnew(nlen);
  12. e = mpnew(elen);
  13. d = mpnew(0);
  14. phi = mpnew(nlen);
  15. // create the prime factors and euclid's function
  16. genprime(p, nlen/2, rounds);
  17. genprime(q, nlen - mpsignif(p) + 1, rounds);
  18. mpmul(p, q, n);
  19. mpsub(p, mpone, e);
  20. mpsub(q, mpone, d);
  21. mpmul(e, d, phi);
  22. // find an e relatively prime to phi
  23. t1 = mpnew(0);
  24. t2 = mpnew(0);
  25. mprand(elen, genrandom, e);
  26. if(mpcmp(e,mptwo) <= 0)
  27. itomp(3, e);
  28. // See Menezes et al. p.291 "8.8 Note (selecting primes)" for discussion
  29. // of the merits of various choices of primes and exponents. e=3 is a
  30. // common and recommended exponent, but doesn't necessarily work here
  31. // because we chose strong rather than safe primes.
  32. for(;;){
  33. mpextendedgcd(e, phi, t1, d, t2);
  34. if(mpcmp(t1, mpone) == 0)
  35. break;
  36. mpadd(mpone, e, e);
  37. }
  38. mpfree(t1);
  39. mpfree(t2);
  40. // compute chinese remainder coefficient
  41. c2 = mpnew(0);
  42. mpinvert(p, q, c2);
  43. // for crt a**k mod p == (a**(k mod p-1)) mod p
  44. kq = mpnew(0);
  45. kp = mpnew(0);
  46. mpsub(p, mpone, phi);
  47. mpmod(d, phi, kp);
  48. mpsub(q, mpone, phi);
  49. mpmod(d, phi, kq);
  50. rsa = rsaprivalloc();
  51. rsa->pub.ek = e;
  52. rsa->pub.n = n;
  53. rsa->dk = d;
  54. rsa->kp = kp;
  55. rsa->kq = kq;
  56. rsa->p = p;
  57. rsa->q = q;
  58. rsa->c2 = c2;
  59. mpfree(phi);
  60. return rsa;
  61. }