dsaprimes.c 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #include "os.h"
  2. #include <mp.h>
  3. #include <libsec.h>
  4. // NIST algorithm for generating DSA primes
  5. // Menezes et al (1997) Handbook of Applied Cryptography, p.151
  6. // q is a 160-bit prime; p is a 1024-bit prime; q divides p-1
  7. // arithmetic on unsigned ints mod 2**160, represented
  8. // as 20-byte, little-endian uchar array
  9. static void
  10. Hrand(uchar *s)
  11. {
  12. ulong *u = (ulong*)s;
  13. *u++ = fastrand();
  14. *u++ = fastrand();
  15. *u++ = fastrand();
  16. *u++ = fastrand();
  17. *u = fastrand();
  18. }
  19. static void
  20. Hincr(uchar *s)
  21. {
  22. int i;
  23. for(i=0; i<20; i++)
  24. if(++s[i]!=0)
  25. break;
  26. }
  27. // this can run for quite a while; be patient
  28. void
  29. DSAprimes(mpint *q, mpint *p, uchar seed[SHA1dlen])
  30. {
  31. int i, j, k, n = 6, b = 63;
  32. uchar s[SHA1dlen], Hs[SHA1dlen], Hs1[SHA1dlen], sj[SHA1dlen], sjk[SHA1dlen];
  33. mpint *two1023, *mb, *Vk, *W, *X, *q2;
  34. two1023 = mpnew(1024);
  35. mpleft(mpone, 1023, two1023);
  36. mb = mpnew(0);
  37. mpleft(mpone, b, mb);
  38. W = mpnew(1024);
  39. Vk = mpnew(1024);
  40. X = mpnew(0);
  41. q2 = mpnew(0);
  42. forever:
  43. do{
  44. Hrand(s);
  45. memcpy(sj, s, 20);
  46. sha1(s, 20, Hs, 0);
  47. Hincr(sj);
  48. sha1(sj, 20, Hs1, 0);
  49. for(i=0; i<20; i++)
  50. Hs[i] ^= Hs1[i];
  51. Hs[0] |= 1;
  52. Hs[19] |= 0x80;
  53. letomp(Hs, 20, q);
  54. }while(!probably_prime(q, 18));
  55. if(seed != nil) // allow skeptics to confirm computation
  56. memmove(seed, s, SHA1dlen);
  57. i = 0;
  58. j = 2;
  59. Hincr(sj);
  60. mpleft(q, 1, q2);
  61. while(i<4096){
  62. memcpy(sjk, sj, 20);
  63. for(k=0; k <= n; k++){
  64. sha1(sjk, 20, Hs, 0);
  65. letomp(Hs, 20, Vk);
  66. if(k == n)
  67. mpmod(Vk, mb, Vk);
  68. mpleft(Vk, 160*k, Vk);
  69. mpadd(W, Vk, W);
  70. Hincr(sjk);
  71. }
  72. mpadd(W, two1023, X);
  73. mpmod(X, q2, W);
  74. mpsub(W, mpone, W);
  75. mpsub(X, W, p);
  76. if(mpcmp(p, two1023)>=0 && probably_prime(p, 5))
  77. goto done;
  78. i += 1;
  79. j += n+1;
  80. for(k=0; k<n+1; k++)
  81. Hincr(sj);
  82. }
  83. goto forever;
  84. done:
  85. mpfree(q2);
  86. mpfree(X);
  87. mpfree(Vk);
  88. mpfree(W);
  89. mpfree(mb);
  90. mpfree(two1023);
  91. }