Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

6 лет назад
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. #include <assert.h>
  2. #include "mont.h"
  3. #include "u512.h"
  4. void xDBLADD(proj *R, proj *S, proj const *P, proj const *Q, proj const *PQ, proj const *A24)
  5. {
  6. fp tmp0, tmp1, tmp2; //requires precomputation of A24=(A+2C:4C)
  7. fp_add3(&tmp0, &P->x, &P->z);
  8. fp_sub3(&tmp1, &P->x, &P->z);
  9. fp_sq2(&R->x, &tmp0);
  10. fp_sub3(&tmp2, &Q->x, &Q->z);
  11. fp_add3(&S->x, &Q->x, &Q->z);
  12. fp_mul2(&tmp0, &tmp2);
  13. fp_sq2(&R->z, &tmp1);
  14. fp_mul2(&tmp1, &S->x);
  15. fp_sub3(&tmp2, &R->x, &R->z);
  16. fp_mul2(&R->z, &A24->z);
  17. fp_mul2(&R->x, &R->z);
  18. fp_mul3(&S->x, &A24->x, &tmp2);
  19. fp_sub3(&S->z, &tmp0, &tmp1);
  20. fp_add2(&R->z, &S->x);
  21. fp_add3(&S->x, &tmp0, &tmp1);
  22. fp_mul2(&R->z, &tmp2);
  23. fp_sq1(&S->z);
  24. fp_sq1(&S->x);
  25. fp_mul2(&S->z, &PQ->x);
  26. fp_mul2(&S->x, &PQ->z);
  27. }
  28. void xDBL(proj *Q, proj const *A, proj const *P)
  29. {
  30. fp a, b, c;
  31. fp_add3(&a, &P->x, &P->z);
  32. fp_sq1(&a);
  33. fp_sub3(&b, &P->x, &P->z);
  34. fp_sq1(&b);
  35. fp_sub3(&c, &a, &b);
  36. fp_add2(&b, &b); fp_add2(&b, &b); /* multiplication by 4 */
  37. fp_mul2(&b, &A->z);
  38. fp_mul3(&Q->x, &a, &b);
  39. fp_add3(&a, &A->z, &A->z); /* multiplication by 2 */
  40. fp_add2(&a, &A->x);
  41. fp_mul2(&a, &c);
  42. fp_add2(&a, &b);
  43. fp_mul3(&Q->z, &a, &c);
  44. }
  45. void xADD(proj *S, proj const *P, proj const *Q, proj const *PQ)
  46. {
  47. fp a, b, c, d;
  48. fp_add3(&a, &P->x, &P->z);
  49. fp_sub3(&b, &P->x, &P->z);
  50. fp_add3(&c, &Q->x, &Q->z);
  51. fp_sub3(&d, &Q->x, &Q->z);
  52. fp_mul2(&a, &d);
  53. fp_mul2(&b, &c);
  54. fp_add3(&c, &a, &b);
  55. fp_sub3(&d, &a, &b);
  56. fp_sq1(&c);
  57. fp_sq1(&d);
  58. fp_mul3(&S->x, &PQ->z, &c);
  59. fp_mul3(&S->z, &PQ->x, &d);
  60. }
  61. /* Montgomery ladder. */
  62. /* P must not be the unique point of order 2. */
  63. /* not constant-time! */
  64. void xMUL(proj *Q, proj const *A, proj const *P, u512 const *k)
  65. {
  66. proj R = *P;
  67. proj A24;
  68. const proj Pcopy = *P; /* in case Q = P */
  69. Q->x = fp_1;
  70. Q->z = fp_0;
  71. fp_add3(&A24.x, &A->z, &A->z); //precomputation of A24=(A+2C:4C)
  72. fp_add3(&A24.z, &A24.x, &A24.x);
  73. fp_add2(&A24.x, &A->x);
  74. unsigned long i = 512;
  75. while (--i && !u512_bit(k, i));
  76. do {
  77. bool bit = u512_bit(k, i);
  78. if (bit) { proj T = *Q; *Q = R; R = T; } /* not constant-time */
  79. //fp_cswap(&Q->x, &R.x, bit);
  80. //fp_cswap(&Q->z, &R.z, bit);
  81. xDBLADD(Q, &R, Q, &R, &Pcopy, &A24);
  82. if (bit) { proj T = *Q; *Q = R; R = T; } /* not constant-time */
  83. //fp_cswap(&Q->x, &R.x, bit);
  84. //fp_cswap(&Q->z, &R.z, bit);
  85. } while (i--);
  86. }
  87. //simultaneous square-and-multiply, computes x^exp and y^exp
  88. void exp_by_squaring_(fp* x, fp* y, uint64_t exp)
  89. {
  90. fp result1, result2;
  91. fp_set(&result1, 1);
  92. fp_set(&result2, 1);
  93. while (exp)
  94. {
  95. if (exp & 1){
  96. fp_mul2(&result1, x);
  97. fp_mul2(&result2, y);
  98. }
  99. fp_sq1(x);
  100. fp_sq1(y);
  101. exp >>= 1;
  102. }
  103. fp_cswap(&result1, x, 1);
  104. fp_cswap(&result2, y, 1);
  105. }
  106. /* computes the isogeny with kernel point K of order k */
  107. /* returns the new curve coefficient A and the image of P */
  108. /* (obviously) not constant time in k */
  109. void xISOG(proj *A, proj *P, proj const *K, uint64_t k)
  110. {
  111. assert (k >= 3);
  112. assert (k % 2 == 1);
  113. fp tmp0, tmp1, tmp2, Psum, Pdif;
  114. proj Q, Aed, prod;
  115. fp_add3(&Aed.z, &A->z, &A->z); //compute twisted Edwards curve coefficients
  116. fp_add3(&Aed.x, &A->x, &Aed.z);
  117. fp_sub3(&Aed.z, &A->x, &Aed.z);
  118. fp_add3(&Psum, &P->x, &P->z); //precomputations
  119. fp_sub3(&Pdif, &P->x, &P->z);
  120. fp_sub3(&prod.x, &K->x, &K->z);
  121. fp_add3(&prod.z, &K->x, &K->z);
  122. fp_mul3(&tmp1, &prod.x, &Psum);
  123. fp_mul3(&tmp0, &prod.z, &Pdif);
  124. fp_add3(&Q.x, &tmp0, &tmp1);
  125. fp_sub3(&Q.z, &tmp0, &tmp1);
  126. proj M[3] = {*K};
  127. xDBL(&M[1], A, K);
  128. for (uint64_t i = 1; i < k / 2; ++i) {
  129. if (i >= 2)
  130. xADD(&M[i % 3], &M[(i - 1) % 3], K, &M[(i - 2) % 3]);
  131. fp_sub3(&tmp1, &M[i % 3].x, &M[i % 3].z);
  132. fp_add3(&tmp0, &M[i % 3].x, &M[i % 3].z);
  133. fp_mul2(&prod.x, &tmp1);
  134. fp_mul2(&prod.z, &tmp0);
  135. fp_mul2(&tmp1, &Psum);
  136. fp_mul2(&tmp0, &Pdif);
  137. fp_add3(&tmp2, &tmp0, &tmp1);
  138. fp_mul2(&Q.x, &tmp2);
  139. fp_sub3(&tmp2, &tmp0, &tmp1);
  140. fp_mul2(&Q.z, &tmp2);
  141. }
  142. // point evaluation
  143. fp_sq1(&Q.x);
  144. fp_sq1(&Q.z);
  145. fp_mul2(&P->x, &Q.x);
  146. fp_mul2(&P->z, &Q.z);
  147. //compute Aed.x^k, Aed.z^k
  148. exp_by_squaring_(&Aed.x, &Aed.z, k);
  149. //compute prod.x^8, prod.z^8
  150. fp_sq1(&prod.x);
  151. fp_sq1(&prod.x);
  152. fp_sq1(&prod.x);
  153. fp_sq1(&prod.z);
  154. fp_sq1(&prod.z);
  155. fp_sq1(&prod.z);
  156. //compute image curve parameters
  157. fp_mul2(&Aed.z, &prod.x);
  158. fp_mul2(&Aed.x, &prod.z);
  159. //compute Montgomery params
  160. fp_add3(&A->x, &Aed.x, &Aed.z);
  161. fp_sub3(&A->z, &Aed.x, &Aed.z);
  162. fp_add2(&A->x, &A->x);
  163. }