curvepoint_fp.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. /*
  2. * File: dclxvi-20130329/curvepoint_fp.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. }
  12. #include "curvepoint_fp.h"
  13. //#include "scalar_512.h"
  14. #include "zout.hpp"
  15. #include <typeinfo>
  16. #include <cxxabi.h>
  17. //////////////////////////////////////////////////////////////////////////////////////////////////////////
  18. // Point initialization and deletion functions
  19. //////////////////////////////////////////////////////////////////////////////////////////////////////////
  20. // Global dummies usable by all curvepoints:
  21. // Set the coordinates of a curvepoint_fp_t by copying the coordinates from another curvepoint_fp
  22. void curvepoint_fp_set(curvepoint_fp_t rop, const curvepoint_fp_t op)
  23. {
  24. fpe_set(rop->m_x, op->m_x);
  25. fpe_set(rop->m_y, op->m_y);
  26. fpe_set(rop->m_z, op->m_z);
  27. fpe_setzero(rop->m_t);
  28. }
  29. void curvepoint_fp_setneutral(curvepoint_fp_t rop)
  30. {
  31. fpe_setone(rop->m_x);
  32. fpe_setone(rop->m_y);
  33. fpe_setzero(rop->m_z);
  34. fpe_setzero(rop->m_t);
  35. }
  36. // Addition of two points, op2 is assumed to be in affine coordinates
  37. // For the algorithm see e.g. DA Peter Schwabe
  38. /*
  39. void curvepoint_fp_mixadd(curvepoint_fp_t rop, const curvepoint_fp_t op1, const curvepoint_fp_t op2)
  40. {
  41. fpe_t tfpe1, tfpe2, tfpe3, tfpe4, tfpe5, tfpe6, tfpe7, tfpe8, tfpe9; // Temporary variables needed for intermediary results
  42. fpe_square(tfpe1, op1->m_z);
  43. fpe_mul(tfpe2, op1->m_z, tfpe1);
  44. fpe_mul(tfpe3, op2->m_x, tfpe1);
  45. fpe_mul(tfpe4, op2->m_y, tfpe2);
  46. fpe_sub(tfpe5, tfpe3, op1->m_x);
  47. fpe_short_coeffred(tfpe5);
  48. fpe_sub(tfpe6, tfpe4, op1->m_y);
  49. fpe_square(tfpe7, tfpe5);
  50. fpe_mul(tfpe8, tfpe7, tfpe5);
  51. fpe_mul(tfpe9, op1->m_x, tfpe7);
  52. fpe_double(tfpe1, tfpe9);
  53. fpe_add(tfpe1, tfpe1, tfpe8);
  54. fpe_square(rop->m_x, tfpe6);
  55. fpe_sub(rop->m_x, rop->m_x, tfpe1);
  56. fpe_short_coeffred(rop->m_x);
  57. fpe_sub(tfpe1, tfpe9, rop->m_x);
  58. fpe_mul(tfpe2, tfpe1, tfpe6);
  59. fpe_mul(tfpe3, op1->m_y, tfpe8);
  60. fpe_sub(rop->m_y, tfpe2, tfpe3);
  61. fpe_short_coeffred(rop->m_y);
  62. fpe_mul(rop->m_z, op1->m_z, tfpe5);
  63. }
  64. */
  65. #ifndef COMPLETE_ADDITION //UPDATE 512
  66. int number_call=0;
  67. void curvepoint_fp_double(curvepoint_fp_t rop, const curvepoint_fp_t op)
  68. {
  69. if (number_call == 0)
  70. {
  71. signature;
  72. }
  73. number_call++;
  74. fpe_t tfpe1, tfpe2, tfpe3, tfpe4; // Temporary variables needed for intermediary results
  75. //abc;
  76. fpe_square(tfpe1, op->m_y);
  77. //xyz;
  78. //debug(301);
  79. fpe_mul(tfpe2, tfpe1, op->m_x);
  80. fpe_double(tfpe2, tfpe2);
  81. //printf("\n\n\ntfpe2="); fpe_print(stdout,tfpe2);
  82. fpe_double(tfpe2, tfpe2);
  83. fpe_square(tfpe3, tfpe1);
  84. fpe_double(tfpe3, tfpe3);
  85. fpe_double(tfpe3, tfpe3);
  86. fpe_double(tfpe3, tfpe3);
  87. fpe_square(tfpe4, op->m_x);
  88. fpe_triple(tfpe4, tfpe4);
  89. fpe_short_coeffred(tfpe4);
  90. fpe_square(rop->m_x, tfpe4);
  91. fpe_double(tfpe1, tfpe2);
  92. fpe_sub(rop->m_x, rop->m_x, tfpe1);
  93. fpe_short_coeffred(rop->m_x);
  94. fpe_sub(tfpe1, tfpe2, rop->m_x);
  95. fpe_short_coeffred(tfpe1);
  96. fpe_mul(rop->m_z, op->m_y, op->m_z);
  97. fpe_double(rop->m_z, rop->m_z);
  98. fpe_mul(rop->m_y, tfpe4, tfpe1);
  99. fpe_sub(rop->m_y, rop->m_y, tfpe3);
  100. fpe_short_coeffred(rop->m_y);
  101. //curvepoint_fp_makeaffine(rop);
  102. }
  103. // Transform Jacobian to Affine Coordinates (z=1)
  104. void curvepoint_fp_makeaffine(curvepoint_fp_t point)
  105. {
  106. //signature;
  107. if (!fpe_iszero(point->m_z))
  108. {
  109. fpe_t tfpe1;
  110. fpe_invert(tfpe1, point->m_z);
  111. fpe_mul(point->m_x, point->m_x, tfpe1);
  112. fpe_mul(point->m_x, point->m_x, tfpe1);
  113. fpe_mul(point->m_y, point->m_y, tfpe1);
  114. fpe_mul(point->m_y, point->m_y, tfpe1);
  115. fpe_mul(point->m_y, point->m_y, tfpe1);
  116. fpe_setone(point->m_z);
  117. }
  118. }
  119. #endif
  120. #ifndef COMPLETE_ADDITION //UPDATE 512
  121. void curvepoint_fp_add_vartime(curvepoint_fp_t rop, const curvepoint_fp_t op1, const curvepoint_fp_t op2)
  122. {
  123. //signature;
  124. if(fpe_iszero(op1->m_z))
  125. curvepoint_fp_set(rop,op2);
  126. else if(fpe_iszero(op2->m_z))
  127. curvepoint_fp_set(rop,op1);
  128. else
  129. {
  130. //See http://www.hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/addition/add-2007-bl.op3
  131. fpe_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;
  132. //Z1Z1 = Z1^2
  133. fpe_square(z1z1, op1->m_z);
  134. //Z2Z2 = Z2^2
  135. fpe_square(z2z2, op2->m_z);
  136. //U1 = X1*Z2Z2
  137. fpe_mul(u1, op1->m_x, z2z2);
  138. //U2 = X2*Z1Z1
  139. fpe_mul(u2, op2->m_x, z1z1);
  140. //t0 = Z2*Z2Z2
  141. fpe_mul(t0, op2->m_z, z2z2);
  142. //S1 = Y1*t0
  143. fpe_mul(s1,op1->m_y,t0);
  144. //t1 = Z1*Z1Z1
  145. fpe_mul(t1,op1->m_z, z1z1);
  146. //S2 = Y2*t1
  147. fpe_mul(s2,op2->m_y,t1);
  148. if(fpe_iseq(u1,u2))
  149. {
  150. if(fpe_iseq(s1,s2))
  151. curvepoint_fp_double(rop,op1);
  152. else
  153. curvepoint_fp_setneutral(rop);
  154. }
  155. //H = U2-U1
  156. fpe_sub(h,u2,u1);
  157. //t2 = 2*H
  158. fpe_add(t2, h, h);
  159. //I = t2^2
  160. fpe_short_coeffred(t2);
  161. fpe_square(i,t2);
  162. //J = H*I
  163. fpe_mul(j,h,i);
  164. //t3 = S2-S1
  165. fpe_sub(t3,s2,s1);
  166. //r = 2*t3
  167. fpe_add(r,t3,t3);
  168. //V = U1*I
  169. fpe_mul(v,u1,i);
  170. //t4 = r^2
  171. fpe_short_coeffred(r);
  172. fpe_square(t4,r);
  173. //t5 = 2*V
  174. fpe_add(t5,v,v);
  175. //t6 = t4-J
  176. fpe_sub(t6,t4,j);
  177. //X3 = t6-t5
  178. fpe_sub(rop->m_x,t6,t5);
  179. fpe_short_coeffred(rop->m_x);
  180. //t7 = V-X3
  181. fpe_sub(t7,v,rop->m_x);
  182. //t8 = S1*J
  183. fpe_mul(t8,s1,j);
  184. //t9 = 2*t8
  185. fpe_add(t9,t8,t8);
  186. //t10 = r*t7
  187. fpe_mul(t10,r,t7);
  188. //Y3 = t10-t9
  189. fpe_sub(rop->m_y,t10,t9);
  190. fpe_short_coeffred(rop->m_y);
  191. //t11 = Z1+Z2
  192. fpe_add(t11,op1->m_z,op2->m_z);
  193. //t12 = t11^2
  194. fpe_short_coeffred(t11);
  195. fpe_square(t12,t11);
  196. //t13 = t12-Z1Z1
  197. fpe_sub(t13,t12,z1z1);
  198. //t14 = t13-Z2Z2
  199. fpe_sub(t14,t13,z2z2);
  200. //Z3 = t14*H
  201. fpe_mul(rop->m_z,t14,h);
  202. fpe_short_coeffred(rop->m_z);
  203. }
  204. //curvepoint_fp_makeaffine(rop);
  205. }
  206. #endif
  207. static void curvepoint_fp_add_nocheck(curvepoint_fp_t rop, const curvepoint_fp_t op1, const curvepoint_fp_t op2)
  208. {
  209. //See http://www.hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/addition/add-2007-bl.op3
  210. fpe_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;
  211. //Z1Z1 = Z1^2
  212. fpe_square(z1z1, op1->m_z);
  213. //Z2Z2 = Z2^2
  214. fpe_square(z2z2, op2->m_z);
  215. //U1 = X1*Z2Z2
  216. fpe_mul(u1, op1->m_x, z2z2);
  217. //U2 = X2*Z1Z1
  218. fpe_mul(u2, op2->m_x, z1z1);
  219. //t0 = Z2*Z2Z2
  220. fpe_mul(t0, op2->m_z, z2z2);
  221. //S1 = Y1*t0
  222. fpe_mul(s1,op1->m_y,t0);
  223. //t1 = Z1*Z1Z1
  224. fpe_mul(t1,op1->m_z, z1z1);
  225. //S2 = Y2*t1
  226. fpe_mul(s2,op2->m_y,t1);
  227. //H = U2-U1
  228. fpe_sub(h,u2,u1);
  229. //t2 = 2*H
  230. fpe_add(t2, h, h);
  231. //I = t2^2
  232. fpe_short_coeffred(t2);
  233. fpe_square(i,t2);
  234. //J = H*I
  235. fpe_mul(j,h,i);
  236. //t3 = S2-S1
  237. fpe_sub(t3,s2,s1);
  238. //r = 2*t3
  239. fpe_add(r,t3,t3);
  240. //V = U1*I
  241. fpe_mul(v,u1,i);
  242. //t4 = r^2
  243. fpe_short_coeffred(r);
  244. fpe_square(t4,r);
  245. //t5 = 2*V
  246. fpe_add(t5,v,v);
  247. //t6 = t4-J
  248. fpe_sub(t6,t4,j);
  249. //X3 = t6-t5
  250. fpe_sub(rop->m_x,t6,t5);
  251. fpe_short_coeffred(rop->m_x);
  252. //t7 = V-X3
  253. fpe_sub(t7,v,rop->m_x);
  254. //t8 = S1*J
  255. fpe_mul(t8,s1,j);
  256. //t9 = 2*t8
  257. fpe_add(t9,t8,t8);
  258. //t10 = r*t7
  259. fpe_mul(t10,r,t7);
  260. //Y3 = t10-t9
  261. fpe_sub(rop->m_y,t10,t9);
  262. fpe_short_coeffred(rop->m_y);
  263. //t11 = Z1+Z2
  264. fpe_add(t11,op1->m_z,op2->m_z);
  265. //t12 = t11^2
  266. fpe_short_coeffred(t11);
  267. fpe_square(t12,t11);
  268. //t13 = t12-Z1Z1
  269. fpe_sub(t13,t12,z1z1);
  270. //t14 = t13-Z2Z2
  271. fpe_sub(t14,t13,z2z2);
  272. //Z3 = t14*H
  273. fpe_mul(rop->m_z,t14,h);
  274. fpe_short_coeffred(rop->m_z);
  275. }
  276. /*
  277. void curvepoint_fp_scalarmult_vartime_old(curvepoint_fp_t rop, const curvepoint_fp_t op, const scalar_t scalar, const unsigned int scalar_bitsize)
  278. {
  279. size_t i;
  280. curvepoint_fp_t r;
  281. curvepoint_fp_set(r, op);
  282. for(i = scalar_bitsize-1; i > 0; i--)
  283. {
  284. curvepoint_fp_double(r, r);
  285. if(scalar_getbit(scalar, i - 1))
  286. curvepoint_fp_mixadd(r, r, op);
  287. }
  288. curvepoint_fp_set(rop, r);
  289. }
  290. */
  291. static void choose_t(curvepoint_fp_t t, struct curvepoint_fp_struct *pre, signed char b)
  292. {
  293. //signature;
  294. //zout((int)b);
  295. if(b>0)
  296. *t = pre[b-1];
  297. else
  298. {
  299. *t = pre[-b-1];
  300. //printf("avant t = ");
  301. //curvepoint_fp_print(stdout,t);
  302. //printf("\n\n\n");
  303. curvepoint_fp_neg(t,t);
  304. //printf("apres t = ");
  305. //curvepoint_fp_print(stdout,t);
  306. //printf("\n\n\n");
  307. }
  308. }
  309. void curvepoint_fp_scalarmult_vartime(curvepoint_fp_t rop, const curvepoint_fp_t op, const scalar_t scalar)
  310. {
  311. signed char s[65];
  312. int i;
  313. curvepoint_fp_t t;
  314. struct curvepoint_fp_struct pre[8];
  315. //zout(__builtin_return_address(0),__builtin_return_address(1),__func__,__PRETTY_FUNCTION__);
  316. //cout << abi::__cxa_demangle(typeid(__func__).name(), 0, 0, 0);
  317. scalar_window4(s,scalar);
  318. //zout(__builtin_return_address(0),__func__);
  319. //printf("\n");
  320. //ecris(s = );
  321. //for(i=0;i<64;i++)
  322. //printf("%d ",s[i]);
  323. //printf("\n");
  324. pre[0] = *op; // P
  325. curvepoint_fp_double(&pre[1], &pre[0]); // 2P
  326. curvepoint_fp_add_vartime(&pre[2], &pre[0], &pre[1]); // 3P
  327. curvepoint_fp_double(&pre[3], &pre[1]); // 4P
  328. curvepoint_fp_add_vartime(&pre[4], &pre[0], &pre[3]); // 5P
  329. curvepoint_fp_double(&pre[5], &pre[2]); // 6P
  330. curvepoint_fp_add_vartime(&pre[6], &pre[0], &pre[5]); // 7P
  331. curvepoint_fp_double(&pre[7], &pre[3]); // 8P
  332. //printf("\n\n\nP = "); curvepoint_fp_print(stdout,&pre[0]);
  333. //printf("\n\n\n2P = "); curvepoint_fp_print(stdout,&pre[1]);
  334. //printf("\n\n\n3P = "); curvepoint_fp_print(stdout,&pre[2]);
  335. //printf("\n\n\n4P = "); curvepoint_fp_print(stdout,&pre[3]);
  336. //printf("\n\n\n5P = "); curvepoint_fp_print(stdout,&pre[4]);
  337. //printf("\n\n\n6P = "); curvepoint_fp_print(stdout,&pre[5]);
  338. //printf("\n\n\n7P = "); curvepoint_fp_print(stdout,&pre[6]);
  339. //printf("\n\n\n8P = "); curvepoint_fp_print(stdout,&pre[7]);
  340. //printf("\n\n\n");
  341. i = 64;
  342. while(!s[i]&&i>0) i--;
  343. if(!s[i])
  344. {
  345. curvepoint_fp_setneutral(rop);
  346. //printf("\n\n\n rop = ");
  347. //curvepoint_fp_print(stdout,rop);
  348. }
  349. else
  350. {
  351. choose_t(rop,pre,s[i]);
  352. i--;
  353. for(;i>=0;i--)
  354. {
  355. //printf("i = %d\n",i);
  356. curvepoint_fp_double(rop, rop);
  357. curvepoint_fp_double(rop, rop);
  358. curvepoint_fp_double(rop, rop);
  359. curvepoint_fp_double(rop, rop);
  360. if(s[i])
  361. {
  362. //printf("i=%d \t s[i] = %d\n",i,s[i]);
  363. choose_t(t,pre,s[i]);
  364. //printf("rop = ");
  365. //curvepoint_fp_print(stdout,rop);
  366. //printf("\n\n\n");
  367. //printf("t = ");
  368. //curvepoint_fp_print(stdout,t);
  369. //printf("\n\n\n");
  370. curvepoint_fp_add_vartime(rop,rop,t);
  371. }
  372. }
  373. }
  374. }
  375. // Negate a point, store in rop:
  376. void curvepoint_fp_neg(curvepoint_fp_t rop, const curvepoint_fp_t op)
  377. {
  378. if (fpe_iszero(op->m_z))
  379. {
  380. curvepoint_fp_set(rop,op);
  381. }
  382. else
  383. {
  384. fpe_t tfpe1;
  385. fpe_set(rop->m_x, op->m_x);
  386. fpe_neg(rop->m_y, op->m_y);
  387. fpe_set(rop->m_z, op->m_z);
  388. }
  389. }
  390. // Print a point:
  391. void curvepoint_fp_print(FILE *outfile, const curvepoint_fp_t point)
  392. {
  393. fprintf(outfile, "______________Curve______________\n\nX = ");
  394. fpe_print(outfile, point->m_x);
  395. fprintf(outfile, "\n\nY = ");
  396. fpe_print(outfile, point->m_y);
  397. fprintf(outfile, "\n\nZ = ");
  398. fpe_print(outfile, point->m_z);
  399. fprintf(outfile, "\n_________________________________\n");
  400. }