You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

189 lines
4.5 KiB

  1. #include <assert.h>
  2. #include "mont.h"
  3. void xDBLADD(proj *R, proj *S, proj const *P, proj const *Q, proj const *PQ, proj const *A24)
  4. {
  5. fp tmp0, tmp1, tmp2;
  6. fp_add3(&tmp0, &P->x, &P->z);
  7. fp_sub3(&tmp1, &P->x, &P->z);
  8. fp_sq2(&R->x, &tmp0);
  9. fp_sub3(&tmp2, &Q->x, &Q->z);
  10. fp_add3(&S->x, &Q->x, &Q->z);
  11. fp_mul2(&tmp0, &tmp2);
  12. fp_sq2(&R->z, &tmp1);
  13. fp_mul2(&tmp1, &S->x);
  14. fp_sub3(&tmp2, &R->x, &R->z);
  15. fp_mul2(&R->z, &A24->z);
  16. fp_mul2(&R->x, &R->z);
  17. fp_mul3(&S->x, &A24->x, &tmp2);
  18. fp_sub3(&S->z, &tmp0, &tmp1);
  19. fp_add2(&R->z, &S->x);
  20. fp_add3(&S->x, &tmp0, &tmp1);
  21. fp_mul2(&R->z, &tmp2);
  22. fp_sq1(&S->z);
  23. fp_sq1(&S->x);
  24. fp_mul2(&S->z, &PQ->x);
  25. fp_mul2(&S->x, &PQ->z);
  26. }
  27. void xDBL(proj *Q, proj const *A, proj const *P)
  28. {
  29. fp a, b, c;
  30. fp_add3(&a, &P->x, &P->z);
  31. fp_sq1(&a);
  32. fp_sub3(&b, &P->x, &P->z);
  33. fp_sq1(&b);
  34. fp_sub3(&c, &a, &b);
  35. fp_add2(&b, &b); fp_add2(&b, &b); /* multiplication by 4 */
  36. fp_mul2(&b, &A->z);
  37. fp_mul3(&Q->x, &a, &b);
  38. fp_add3(&a, &A->z, &A->z); /* multiplication by 2 */
  39. fp_add2(&a, &A->x);
  40. fp_mul2(&a, &c);
  41. fp_add2(&a, &b);
  42. fp_mul3(&Q->z, &a, &c);
  43. }
  44. void xADD(proj *S, proj const *P, proj const *Q, proj const *PQ)
  45. {
  46. fp a, b, c, d;
  47. fp_add3(&a, &P->x, &P->z);
  48. fp_sub3(&b, &P->x, &P->z);
  49. fp_add3(&c, &Q->x, &Q->z);
  50. fp_sub3(&d, &Q->x, &Q->z);
  51. fp_mul2(&a, &d);
  52. fp_mul2(&b, &c);
  53. fp_add3(&c, &a, &b);
  54. fp_sub3(&d, &a, &b);
  55. fp_sq1(&c);
  56. fp_sq1(&d);
  57. fp_mul3(&S->x, &PQ->z, &c);
  58. fp_mul3(&S->z, &PQ->x, &d);
  59. }
  60. /* Montgomery ladder. */
  61. /* P must not be the unique point of order 2. */
  62. /* not constant-time! */
  63. void xMUL(proj *Q, proj const *A, proj const *P, u512 const *k)
  64. {
  65. proj R = *P;
  66. proj A24;
  67. const proj Pcopy = *P; /* in case Q = P */
  68. Q->x = fp_1;
  69. Q->z = fp_0;
  70. fp_add3(&A24.x, &A->z, &A->z);
  71. fp_add3(&A24.z, &A24.x, &A24.x);
  72. fp_add2(&A24.x, &A->x);
  73. unsigned long i = 512;
  74. while (--i && !u512_bit(k, i));
  75. do {
  76. bool bit = u512_bit(k, i);
  77. if (bit) { proj T = *Q; *Q = R; R = T; } /* not constant-time */
  78. //fp_cswap(&Q->x, &R.x, bit);
  79. //fp_cswap(&Q->z, &R.z, bit);
  80. xDBLADD(Q, &R, Q, &R, &Pcopy, &A24);
  81. if (bit) { proj T = *Q; *Q = R; R = T; } /* not constant-time */
  82. //fp_cswap(&Q->x, &R.x, bit);
  83. //fp_cswap(&Q->z, &R.z, bit);
  84. } while (i--);
  85. }
  86. /* computes the isogeny with kernel point K of order k */
  87. /* returns the new curve coefficient A and the image of P */
  88. /* (obviously) not constant time in k */
  89. void xISOG(proj *A, proj *P, proj const *K, uint64_t k)
  90. {
  91. assert (k >= 3);
  92. assert (k % 2 == 1);
  93. fp tmp0, tmp1;
  94. fp T[4] = {K->z, K->x, K->x, K->z};
  95. proj Q;
  96. fp_mul3(&Q.x, &P->x, &K->x);
  97. fp_mul3(&tmp0, &P->z, &K->z);
  98. fp_sub2(&Q.x, &tmp0);
  99. fp_mul3(&Q.z, &P->x, &K->z);
  100. fp_mul3(&tmp0, &P->z, &K->x);
  101. fp_sub2(&Q.z, &tmp0);
  102. proj M[3] = {*K};
  103. xDBL(&M[1], A, K);
  104. for (uint64_t i = 1; i < k / 2; ++i) {
  105. if (i >= 2)
  106. xADD(&M[i % 3], &M[(i - 1) % 3], K, &M[(i - 2) % 3]);
  107. fp_mul3(&tmp0, &M[i % 3].x, &T[0]);
  108. fp_mul3(&tmp1, &M[i % 3].z, &T[1]);
  109. fp_add3(&T[0], &tmp0, &tmp1);
  110. fp_mul2(&T[1], &M[i % 3].x);
  111. fp_mul3(&tmp0, &M[i % 3].z, &T[2]);
  112. fp_mul3(&tmp1, &M[i % 3].x, &T[3]);
  113. fp_add3(&T[2], &tmp0, &tmp1);
  114. fp_mul2(&T[3], &M[i % 3].z);
  115. fp_mul3(&tmp0, &P->x, &M[i % 3].x);
  116. fp_mul3(&tmp1, &P->z, &M[i % 3].z);
  117. fp_sub2(&tmp0, &tmp1);
  118. fp_mul2(&Q.x, &tmp0);
  119. fp_mul3(&tmp0, &P->x, &M[i % 3].z);
  120. fp_mul3(&tmp1, &P->z, &M[i % 3].x);
  121. fp_sub2(&tmp0, &tmp1);
  122. fp_mul2(&Q.z, &tmp0);
  123. }
  124. fp_mul2(&T[0], &T[1]);
  125. fp_add2(&T[0], &T[0]); /* multiplication by 2 */
  126. fp_sq1(&T[1]);
  127. fp_mul2(&T[2], &T[3]);
  128. fp_add2(&T[2], &T[2]); /* multiplication by 2 */
  129. fp_sq1(&T[3]);
  130. /* Ax := T[1] * T[3] * Ax - 3 * Az * (T[1] * T[2] - T[0] * T[3]) */
  131. fp_mul3(&tmp0, &T[1], &T[2]);
  132. fp_mul3(&tmp1, &T[0], &T[3]);
  133. fp_sub2(&tmp0, &tmp1);
  134. fp_mul2(&tmp0, &A->z);
  135. fp_add3(&tmp1, &tmp0, &tmp0); fp_add2(&tmp0, &tmp1); /* multiplication by 3 */
  136. fp_mul3(&tmp1, &T[1], &T[3]);
  137. fp_mul2(&tmp1, &A->x);
  138. fp_sub3(&A->x, &tmp1, &tmp0);
  139. /* Az := Az * T[3]^2 */
  140. fp_sq1(&T[3]);
  141. fp_mul2(&A->z, &T[3]);
  142. /* X := X * Xim^2, Z := Z * Zim^2 */
  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. }