mpeuclid.c 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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. // extended euclid
  12. //
  13. // For a and b it solves, d = gcd(a,b) and finds x and y s.t.
  14. // ax + by = d
  15. //
  16. // Handbook of Applied Cryptography, Menezes et al, 1997, pg 67
  17. void
  18. mpeuclid(mpint *a, mpint *b, mpint *d, mpint *x, mpint *y)
  19. {
  20. mpint *tmp, *x0, *x1, *x2, *y0, *y1, *y2, *q, *r;
  21. if(a->sign<0 || b->sign<0)
  22. sysfatal("mpeuclid: negative arg");
  23. if(mpcmp(a, b) < 0){
  24. tmp = a;
  25. a = b;
  26. b = tmp;
  27. tmp = x;
  28. x = y;
  29. y = tmp;
  30. }
  31. if(b->top == 0){
  32. mpassign(a, d);
  33. mpassign(mpone, x);
  34. mpassign(mpzero, y);
  35. return;
  36. }
  37. a = mpcopy(a);
  38. b = mpcopy(b);
  39. x0 = mpnew(0);
  40. x1 = mpcopy(mpzero);
  41. x2 = mpcopy(mpone);
  42. y0 = mpnew(0);
  43. y1 = mpcopy(mpone);
  44. y2 = mpcopy(mpzero);
  45. q = mpnew(0);
  46. r = mpnew(0);
  47. while(b->top != 0 && b->sign > 0){
  48. // q = a/b
  49. // r = a mod b
  50. mpdiv(a, b, q, r);
  51. // x0 = x2 - qx1
  52. mpmul(q, x1, x0);
  53. mpsub(x2, x0, x0);
  54. // y0 = y2 - qy1
  55. mpmul(q, y1, y0);
  56. mpsub(y2, y0, y0);
  57. // rotate values
  58. tmp = a;
  59. a = b;
  60. b = r;
  61. r = tmp;
  62. tmp = x2;
  63. x2 = x1;
  64. x1 = x0;
  65. x0 = tmp;
  66. tmp = y2;
  67. y2 = y1;
  68. y1 = y0;
  69. y0 = tmp;
  70. }
  71. mpassign(a, d);
  72. mpassign(x2, x);
  73. mpassign(y2, y);
  74. mpfree(x0);
  75. mpfree(x1);
  76. mpfree(x2);
  77. mpfree(y0);
  78. mpfree(y1);
  79. mpfree(y2);
  80. mpfree(q);
  81. mpfree(r);
  82. mpfree(a);
  83. mpfree(b);
  84. }