dh.c 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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. mpint*
  13. dh_new(DHstate *dh, mpint *p, mpint *q, mpint *g)
  14. {
  15. mpint *pm1;
  16. int n;
  17. memset(dh, 0, sizeof(*dh));
  18. if(mpcmp(g, mpone) <= 0)
  19. return nil;
  20. n = mpsignif(p);
  21. pm1 = mpnew(n);
  22. mpsub(p, mpone, pm1);
  23. dh->p = mpcopy(p);
  24. dh->g = mpcopy(g);
  25. dh->q = mpcopy(q != nil ? q : pm1);
  26. dh->x = mpnew(mpsignif(dh->q));
  27. dh->y = mpnew(n);
  28. for(;;){
  29. mpnrand(dh->q, genrandom, dh->x);
  30. mpexp(dh->g, dh->x, dh->p, dh->y);
  31. if(mpcmp(dh->y, mpone) > 0 && mpcmp(dh->y, pm1) < 0)
  32. break;
  33. }
  34. mpfree(pm1);
  35. return dh->y;
  36. }
  37. mpint*
  38. dh_finish(DHstate *dh, mpint *y)
  39. {
  40. mpint *k = nil;
  41. if(y == nil || dh->x == nil || dh->p == nil || dh->q == nil)
  42. goto Out;
  43. /* y > 1 */
  44. if(mpcmp(y, mpone) <= 0)
  45. goto Out;
  46. k = mpnew(mpsignif(dh->p));
  47. /* y < p-1 */
  48. mpsub(dh->p, mpone, k);
  49. if(mpcmp(y, k) >= 0){
  50. Bad:
  51. mpfree(k);
  52. k = nil;
  53. goto Out;
  54. }
  55. /* y**q % p == 1 if q < p-1 */
  56. if(mpcmp(dh->q, k) < 0){
  57. mpexp(y, dh->q, dh->p, k);
  58. if(mpcmp(k, mpone) != 0)
  59. goto Bad;
  60. }
  61. mpexp(y, dh->x, dh->p, k);
  62. Out:
  63. mpfree(dh->p);
  64. mpfree(dh->q);
  65. mpfree(dh->g);
  66. mpfree(dh->x);
  67. mpfree(dh->y);
  68. memset(dh, 0, sizeof(*dh));
  69. return k;
  70. }