rsagen.c 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "os.h"
  10. #include <mp.h>
  11. #include <libsec.h>
  12. static void
  13. genrand(mpint *p, int n)
  14. {
  15. mpdigit x;
  16. // generate n random bits with high set
  17. mpbits(p, n);
  18. genrandom((uint8_t*)p->p, (n+7)/8);
  19. p->top = (n+Dbits-1)/Dbits;
  20. x = 1;
  21. x <<= ((n-1)%Dbits);
  22. p->p[p->top-1] &= (x-1);
  23. p->p[p->top-1] |= x;
  24. }
  25. RSApriv*
  26. rsagen(int nlen, int elen, int rounds)
  27. {
  28. mpint *p, *q, *e, *d, *phi, *n, *t1, *t2, *kp, *kq, *c2;
  29. RSApriv *rsa;
  30. p = mpnew(nlen/2);
  31. q = mpnew(nlen/2);
  32. n = mpnew(nlen);
  33. e = mpnew(elen);
  34. d = mpnew(0);
  35. phi = mpnew(nlen);
  36. // create the prime factors and euclid's function
  37. genstrongprime(p, nlen/2, rounds);
  38. genstrongprime(q, nlen - mpsignif(p) + 1, rounds);
  39. mpmul(p, q, n);
  40. mpsub(p, mpone, e);
  41. mpsub(q, mpone, d);
  42. mpmul(e, d, phi);
  43. // find an e relatively prime to phi
  44. t1 = mpnew(0);
  45. t2 = mpnew(0);
  46. genrand(e, elen);
  47. for(;;){
  48. mpextendedgcd(e, phi, d, t1, t2);
  49. if(mpcmp(d, mpone) == 0)
  50. break;
  51. mpadd(mpone, e, e);
  52. }
  53. mpfree(t1);
  54. mpfree(t2);
  55. // d = e**-1 mod phi
  56. mpinvert(e, phi, d);
  57. // compute chinese remainder coefficient
  58. c2 = mpnew(0);
  59. mpinvert(p, q, c2);
  60. // for crt a**k mod p == (a**(k mod p-1)) mod p
  61. kq = mpnew(0);
  62. kp = mpnew(0);
  63. mpsub(p, mpone, phi);
  64. mpmod(d, phi, kp);
  65. mpsub(q, mpone, phi);
  66. mpmod(d, phi, kq);
  67. rsa = rsaprivalloc();
  68. rsa->pub.ek = e;
  69. rsa->pub.n = n;
  70. rsa->dk = d;
  71. rsa->kp = kp;
  72. rsa->kq = kq;
  73. rsa->p = p;
  74. rsa->q = q;
  75. rsa->c2 = c2;
  76. mpfree(phi);
  77. return rsa;
  78. }