twistpoint_fp2.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. /*
  2. * File: dclxvi-20130329/twistpoint_fp2.c
  3. * Author: Ruben Niederhagen, Peter Schwabe
  4. * Public Domain
  5. */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include "mydouble.h"
  9. extern "C" {
  10. #include "fpe.h"
  11. #include "fp2e.h"
  12. }
  13. #include "twistpoint_fp2.h"
  14. //#include "scalar_512.h"
  15. //////////////////////////////////////////////////////////////////////////////////////////////////////////
  16. // Point initialization and deletion functions
  17. //////////////////////////////////////////////////////////////////////////////////////////////////////////
  18. // Global dummies usable by all curvepoints:
  19. // Set the coordinates of a twistpoint_fp2_t by copying the coordinates from another twistpoint_fp2
  20. void twistpoint_fp2_set(twistpoint_fp2_t rop, const twistpoint_fp2_t op)
  21. {
  22. fp2e_set(rop->m_x, op->m_x);
  23. fp2e_set(rop->m_y, op->m_y);
  24. fp2e_set(rop->m_z, op->m_z);
  25. fp2e_setzero(rop->m_t);
  26. }
  27. void twistpoint_fp2_setneutral(twistpoint_fp2_t rop)
  28. {
  29. fp2e_setone(rop->m_x);
  30. fp2e_setone(rop->m_y);
  31. fp2e_setzero(rop->m_z);
  32. fp2e_setzero(rop->m_t);
  33. }
  34. // Addition of two points, op2 is assumed to be in affine coordinates
  35. // For the algorithm see e.g. DA Peter Schwabe
  36. /*
  37. void twistpoint_fp2_mixadd(twistpoint_fp2_t rop, const twistpoint_fp2_t op1, const twistpoint_fp2_t op2)
  38. {
  39. fp2e_t tfpe1, tfpe2, tfpe3, tfpe4, tfpe5, tfpe6, tfpe7, tfpe8, tfpe9; // Temporary variables needed for intermediary results
  40. fp2e_square(tfpe1, op1->m_z);
  41. fp2e_mul(tfpe2, op1->m_z, tfpe1);
  42. fp2e_mul(tfpe3, op2->m_x, tfpe1);
  43. fp2e_mul(tfpe4, op2->m_y, tfpe2);
  44. fp2e_sub(tfpe5, tfpe3, op1->m_x);
  45. fp2e_short_coeffred(tfpe5);
  46. fp2e_sub(tfpe6, tfpe4, op1->m_y);
  47. fp2e_square(tfpe7, tfpe5);
  48. fp2e_mul(tfpe8, tfpe7, tfpe5);
  49. fp2e_mul(tfpe9, op1->m_x, tfpe7);
  50. fp2e_double(tfpe1, tfpe9);
  51. fp2e_add(tfpe1, tfpe1, tfpe8);
  52. fp2e_square(rop->m_x, tfpe6);
  53. fp2e_sub(rop->m_x, rop->m_x, tfpe1);
  54. fp2e_short_coeffred(rop->m_x);
  55. fp2e_sub(tfpe1, tfpe9, rop->m_x);
  56. fp2e_mul(tfpe2, tfpe1, tfpe6);
  57. fp2e_mul(tfpe3, op1->m_y, tfpe8);
  58. fp2e_sub(rop->m_y, tfpe2, tfpe3);
  59. fp2e_short_coeffred(rop->m_y);
  60. fp2e_mul(rop->m_z, op1->m_z, tfpe5);
  61. }
  62. */
  63. #ifndef COMPLETE_ADDITION
  64. void twistpoint_fp2_double(twistpoint_fp2_t rop, const twistpoint_fp2_t op)
  65. {
  66. fp2e_t tfpe1, tfpe2, tfpe3, tfpe4; // Temporary variables needed for intermediary results
  67. fp2e_square(tfpe1, op->m_y);
  68. fp2e_mul(tfpe2, tfpe1, op->m_x);
  69. fp2e_double(tfpe2, tfpe2);
  70. fp2e_double(tfpe2, tfpe2);
  71. fp2e_square(tfpe3, tfpe1);
  72. fp2e_double(tfpe3, tfpe3);
  73. fp2e_double(tfpe3, tfpe3);
  74. fp2e_double(tfpe3, tfpe3);
  75. fp2e_square(tfpe4, op->m_x);
  76. fp2e_triple(tfpe4, tfpe4);
  77. fp2e_short_coeffred(tfpe4);
  78. fp2e_square(rop->m_x, tfpe4);
  79. fp2e_double(tfpe1, tfpe2);
  80. fp2e_sub(rop->m_x, rop->m_x, tfpe1);
  81. fp2e_short_coeffred(rop->m_x);
  82. fp2e_sub(tfpe1, tfpe2, rop->m_x);
  83. fp2e_short_coeffred(tfpe1);
  84. fp2e_mul(rop->m_z, op->m_y, op->m_z);
  85. fp2e_double(rop->m_z, rop->m_z);
  86. fp2e_mul(rop->m_y, tfpe4, tfpe1);
  87. fp2e_sub(rop->m_y, rop->m_y, tfpe3);
  88. fp2e_short_coeffred(rop->m_y);
  89. }
  90. void twistpoint_fp2_add_vartime(twistpoint_fp2_t rop, const twistpoint_fp2_t op1, const twistpoint_fp2_t op2)
  91. {
  92. if(fp2e_iszero(op1->m_z))
  93. twistpoint_fp2_set(rop,op2);
  94. else if(fp2e_iszero(op2->m_z))
  95. twistpoint_fp2_set(rop,op1);
  96. else
  97. {
  98. //See http://www.hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/addition/add-2007-bl.op3
  99. fp2e_t z1z1, z2z2, r, v, s1, s2, u1, u2, h, i, j, t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14;
  100. //Z1Z1 = Z1^2
  101. fp2e_square(z1z1, op1->m_z);
  102. //Z2Z2 = Z2^2
  103. fp2e_square(z2z2, op2->m_z);
  104. //U1 = X1*Z2Z2
  105. fp2e_mul(u1, op1->m_x, z2z2);
  106. //U2 = X2*Z1Z1
  107. fp2e_mul(u2, op2->m_x, z1z1);
  108. //t0 = Z2*Z2Z2
  109. fp2e_mul(t0, op2->m_z, z2z2);
  110. //S1 = Y1*t0
  111. fp2e_mul(s1,op1->m_y,t0);
  112. //t1 = Z1*Z1Z1
  113. fp2e_mul(t1,op1->m_z, z1z1);
  114. //S2 = Y2*t1
  115. fp2e_mul(s2,op2->m_y,t1);
  116. if(fp2e_iseq(u1,u2))
  117. {
  118. if(fp2e_iseq(s1,s2))
  119. twistpoint_fp2_double(rop,op1);
  120. else
  121. twistpoint_fp2_setneutral(rop);
  122. }
  123. //H = U2-U1
  124. fp2e_sub(h,u2,u1);
  125. //t2 = 2*H
  126. fp2e_add(t2, h, h);
  127. //I = t2^2
  128. fp2e_short_coeffred(t2);
  129. fp2e_square(i,t2);
  130. //J = H*I
  131. fp2e_mul(j,h,i);
  132. //t3 = S2-S1
  133. fp2e_sub(t3,s2,s1);
  134. //r = 2*t3
  135. fp2e_add(r,t3,t3);
  136. //V = U1*I
  137. fp2e_mul(v,u1,i);
  138. //t4 = r^2
  139. fp2e_short_coeffred(r);
  140. fp2e_square(t4,r);
  141. //t5 = 2*V
  142. fp2e_add(t5,v,v);
  143. //t6 = t4-J
  144. fp2e_sub(t6,t4,j);
  145. //X3 = t6-t5
  146. fp2e_sub(rop->m_x,t6,t5);
  147. fp2e_short_coeffred(rop->m_x);
  148. //t7 = V-X3
  149. fp2e_sub(t7,v,rop->m_x);
  150. //t8 = S1*J
  151. fp2e_mul(t8,s1,j);
  152. //t9 = 2*t8
  153. fp2e_add(t9,t8,t8);
  154. //t10 = r*t7
  155. fp2e_mul(t10,r,t7);
  156. //Y3 = t10-t9
  157. fp2e_sub(rop->m_y,t10,t9);
  158. fp2e_short_coeffred(rop->m_y);
  159. //t11 = Z1+Z2
  160. fp2e_add(t11,op1->m_z,op2->m_z);
  161. //t12 = t11^2
  162. fp2e_short_coeffred(t11);
  163. fp2e_square(t12,t11);
  164. //t13 = t12-Z1Z1
  165. fp2e_sub(t13,t12,z1z1);
  166. //t14 = t13-Z2Z2
  167. fp2e_sub(t14,t13,z2z2);
  168. //Z3 = t14*H
  169. fp2e_short_coeffred(t14);
  170. fp2e_mul(rop->m_z,t14,h);
  171. fp2e_short_coeffred(rop->m_z);
  172. }
  173. }
  174. // Transform Jacobian to Affine Coordinates (z=1)
  175. void twistpoint_fp2_makeaffine(twistpoint_fp2_t point)
  176. {
  177. //signature;
  178. if (!fp2e_iszero(point->m_z))
  179. {
  180. fp2e_t tfpe1;
  181. fp2e_invert(tfpe1, point->m_z);
  182. fp2e_mul(point->m_x, point->m_x, tfpe1);
  183. fp2e_mul(point->m_x, point->m_x, tfpe1);
  184. fp2e_mul(point->m_y, point->m_y, tfpe1);
  185. fp2e_mul(point->m_y, point->m_y, tfpe1);
  186. fp2e_mul(point->m_y, point->m_y, tfpe1);
  187. fp2e_setone(point->m_z);
  188. }
  189. }
  190. #endif
  191. static void twistpoint_fp2_add_nocheck(twistpoint_fp2_t rop, const twistpoint_fp2_t op1, const twistpoint_fp2_t op2)
  192. {
  193. //See http://www.hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/addition/add-2007-bl.op3
  194. fp2e_t z1z1, z2z2, r, v, s1, s2, u1, u2, h, i, j, t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14;
  195. //Z1Z1 = Z1^2
  196. fp2e_square(z1z1, op1->m_z);
  197. //Z2Z2 = Z2^2
  198. fp2e_square(z2z2, op2->m_z);
  199. //U1 = X1*Z2Z2
  200. fp2e_mul(u1, op1->m_x, z2z2);
  201. //U2 = X2*Z1Z1
  202. fp2e_mul(u2, op2->m_x, z1z1);
  203. //t0 = Z2*Z2Z2
  204. fp2e_mul(t0, op2->m_z, z2z2);
  205. //S1 = Y1*t0
  206. fp2e_mul(s1,op1->m_y,t0);
  207. //t1 = Z1*Z1Z1
  208. fp2e_mul(t1,op1->m_z, z1z1);
  209. //S2 = Y2*t1
  210. fp2e_mul(s2,op2->m_y,t1);
  211. //H = U2-U1
  212. fp2e_sub(h,u2,u1);
  213. //t2 = 2*H
  214. fp2e_add(t2, h, h);
  215. //I = t2^2
  216. fp2e_short_coeffred(t2);
  217. fp2e_square(i,t2);
  218. //J = H*I
  219. fp2e_mul(j,h,i);
  220. //t3 = S2-S1
  221. fp2e_sub(t3,s2,s1);
  222. //r = 2*t3
  223. fp2e_add(r,t3,t3);
  224. //V = U1*I
  225. fp2e_mul(v,u1,i);
  226. //t4 = r^2
  227. fp2e_short_coeffred(r);
  228. fp2e_square(t4,r);
  229. //t5 = 2*V
  230. fp2e_add(t5,v,v);
  231. //t6 = t4-J
  232. fp2e_sub(t6,t4,j);
  233. //X3 = t6-t5
  234. fp2e_sub(rop->m_x,t6,t5);
  235. fp2e_short_coeffred(rop->m_x);
  236. //t7 = V-X3
  237. fp2e_sub(t7,v,rop->m_x);
  238. //t8 = S1*J
  239. fp2e_mul(t8,s1,j);
  240. //t9 = 2*t8
  241. fp2e_add(t9,t8,t8);
  242. //t10 = r*t7
  243. fp2e_mul(t10,r,t7);
  244. //Y3 = t10-t9
  245. fp2e_sub(rop->m_y,t10,t9);
  246. fp2e_short_coeffred(rop->m_y);
  247. //t11 = Z1+Z2
  248. fp2e_add(t11,op1->m_z,op2->m_z);
  249. //t12 = t11^2
  250. fp2e_short_coeffred(t11);
  251. fp2e_square(t12,t11);
  252. //t13 = t12-Z1Z1
  253. fp2e_sub(t13,t12,z1z1);
  254. //t14 = t13-Z2Z2
  255. fp2e_sub(t14,t13,z2z2);
  256. //Z3 = t14*H
  257. fp2e_short_coeffred(h);
  258. fp2e_mul(rop->m_z,t14,h);
  259. fp2e_short_coeffred(rop->m_z);
  260. }
  261. /*
  262. void twistpoint_fp2_scalarmult_vartime_old(twistpoint_fp2_t rop, const twistpoint_fp2_t op, const scalar_t scalar, const unsigned int scalar_bitsize)
  263. {
  264. size_t i;
  265. twistpoint_fp2_t r;
  266. twistpoint_fp2_set(r, op);
  267. for(i = scalar_bitsize-1; i > 0; i--)
  268. {
  269. twistpoint_fp2_double(r, r);
  270. if(scalar_getbit(scalar, i - 1))
  271. twistpoint_fp2_mixadd(r, r, op);
  272. }
  273. twistpoint_fp2_set(rop, r);
  274. }
  275. */
  276. static void choose_t(twistpoint_fp2_t t, struct twistpoint_fp2_struct *pre, signed char b)
  277. {
  278. if(b>0)
  279. *t = pre[b-1];
  280. else
  281. {
  282. *t = pre[-b-1];
  283. twistpoint_fp2_neg(t,t);
  284. }
  285. }
  286. void twistpoint_fp2_scalarmult_vartime(twistpoint_fp2_t rop, const twistpoint_fp2_t op, const scalar_t scalar)
  287. {
  288. signed char s[65];
  289. int i;
  290. twistpoint_fp2_t t;
  291. struct twistpoint_fp2_struct pre[8];
  292. scalar_window4(s,scalar);
  293. /*
  294. for(i=0;i<64;i++)
  295. printf("%d ",s[i]);
  296. printf("\n");
  297. */
  298. pre[0] = *op; // P
  299. twistpoint_fp2_double(&pre[1], &pre[0]); // 2P
  300. twistpoint_fp2_add_vartime(&pre[2], &pre[0], &pre[1]); // 3P
  301. twistpoint_fp2_double(&pre[3], &pre[1]); // 4P
  302. twistpoint_fp2_add_vartime(&pre[4], &pre[0], &pre[3]); // 5P
  303. twistpoint_fp2_double(&pre[5], &pre[2]); // 6P
  304. twistpoint_fp2_add_vartime(&pre[6], &pre[0], &pre[5]); // 7P
  305. twistpoint_fp2_double(&pre[7], &pre[3]); // 8P
  306. i = 64;
  307. while(!s[i]&&i>0) i--;
  308. if(!s[i])
  309. twistpoint_fp2_setneutral(rop);
  310. else
  311. {
  312. choose_t(rop,pre,s[i]);
  313. i--;
  314. for(;i>=0;i--)
  315. {
  316. twistpoint_fp2_double(rop, rop);
  317. twistpoint_fp2_double(rop, rop);
  318. twistpoint_fp2_double(rop, rop);
  319. twistpoint_fp2_double(rop, rop);
  320. if(s[i])
  321. {
  322. choose_t(t,pre,s[i]);
  323. twistpoint_fp2_add_vartime(rop,rop,t);
  324. }
  325. }
  326. }
  327. }
  328. // Negate a point, store in rop:
  329. void twistpoint_fp2_neg(twistpoint_fp2_t rop, const twistpoint_fp2_t op)
  330. {
  331. if (fp2e_iszero(op->m_z))
  332. {
  333. twistpoint_fp2_set(rop,op);
  334. }
  335. else
  336. {
  337. fp2e_t tfpe1;
  338. fp2e_neg(tfpe1, op->m_y);
  339. fp2e_set(rop->m_x, op->m_x);
  340. fp2e_set(rop->m_y, tfpe1);
  341. fp2e_set(rop->m_z, op->m_z);
  342. }
  343. }
  344. void twistpoint_fp2_set_fp2e(twistpoint_fp2_t rop, const fp2e_t x, const fp2e_t y, const fp2e_t z)
  345. {
  346. fp2e_set(rop->m_x, x);
  347. fp2e_set(rop->m_y, y);
  348. fp2e_set(rop->m_z, z);
  349. fp2e_setzero(rop->m_t);
  350. }
  351. void twistpoint_fp2_affineset_fp2e(twistpoint_fp2_t rop, const fp2e_t x, const fp2e_t y)
  352. {
  353. fp2e_set(rop->m_x, x);
  354. fp2e_set(rop->m_y, y);
  355. fp2e_setone(rop->m_z);
  356. fp2e_setzero(rop->m_t);
  357. }
  358. // Print a point:
  359. void twistpoint_fp2_print(FILE *outfile, const twistpoint_fp2_t point)
  360. {
  361. fprintf(outfile, "______________Twist______________\n\nX = ");
  362. fp2e_print(outfile, point->m_x);
  363. fprintf(outfile, "\n\nY = ");
  364. fp2e_print(outfile, point->m_y);
  365. fprintf(outfile, "\n\nZ = ");
  366. fp2e_print(outfile, point->m_z);
  367. fprintf(outfile, "\n_________________________________\n");
  368. }