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.
 
 
 
 
 

419 lines
13 KiB

  1. #include "test.h"
  2. #include <stdio.h>
  3. #include "scalarmul.h"
  4. #include "ec_point.h"
  5. #include "p448.h"
  6. #include "crandom.h"
  7. /* 0 = succeed, 1 = inval, -1 = fail */
  8. static int
  9. single_scalarmul_compatibility_test (
  10. const struct p448_t *base,
  11. const word_t *scalar,
  12. int nbits
  13. ) {
  14. struct tw_extensible_t text, work;
  15. struct p448_t mont, ct, vl, vt;
  16. int ret = 0, i;
  17. mask_t succ, succm;
  18. const struct p448_t
  19. sqrt_d_minus_1 = {{
  20. U58LE(0xd2e21836749f46),
  21. U58LE(0x888db42b4f0179),
  22. U58LE(0x5a189aabdeea38),
  23. U58LE(0x51e65ca6f14c06),
  24. U58LE(0xa49f7b424d9770),
  25. U58LE(0xdcac4628c5f656),
  26. U58LE(0x49443b8748734a),
  27. U58LE(0x12fec0c0b25b7a)
  28. }};
  29. succ = deserialize_and_twist_approx(&text, &sqrt_d_minus_1, base);
  30. succm = montgomery_ladder(&mont,base,scalar,nbits,1);
  31. if (succ != succm) {
  32. youfail();
  33. printf(" Deserialize_and_twist_approx succ=%d, montgomery_ladder succ=%d\n",
  34. (int)-succ, (int)-succm);
  35. printf(" nbits = %d\n", nbits);
  36. p448_print(" base", base);
  37. scalar_print(" scal", scalar, (nbits+WORD_BITS-1)/WORD_BITS);
  38. return -1;
  39. }
  40. if (!succ) {
  41. return 1;
  42. }
  43. struct { int n,t,s; } params[] = {{5,5,18},{3,5,30},{4,4,28},{1,2,224}};
  44. const int nparams = sizeof(params)/sizeof(params[0]);
  45. struct fixed_base_table_t fbt;
  46. struct p448_t fbout[nparams], wout[6];
  47. memset(&fbt, 0, sizeof(fbt));
  48. memset(&fbout, 0, sizeof(fbout));
  49. memset(&wout, 0, sizeof(wout));
  50. /* compute using combs */
  51. for (i=0; i<nparams; i++) {
  52. int n=params[i].n, t=params[i].t, s=params[i].s;
  53. succ = precompute_fixed_base(&fbt, &text, n, t, s, NULL);
  54. if (!succ) {
  55. youfail();
  56. printf(" Failed to precompute_fixed_base(%d,%d,%d)\n", n, t, s);
  57. continue;
  58. }
  59. succ = scalarmul_fixed_base(&work, scalar, nbits, &fbt);
  60. destroy_fixed_base(&fbt);
  61. if (!succ) {
  62. youfail();
  63. printf(" Failed to scalarmul_fixed_base(%d,%d,%d)\n", n, t, s);
  64. continue;
  65. }
  66. untwist_and_double_and_serialize(&fbout[i], &work);
  67. }
  68. /* compute using precomp wNAF */
  69. for (i=0; i<=5; i++) {
  70. struct tw_niels_t pre[1<<i];
  71. succ = precompute_fixed_base_wnaf(pre, &text, i);
  72. if (!succ) {
  73. youfail();
  74. printf(" Failed to precompute_fixed_base_wnaf(%d)\n", i);
  75. continue;
  76. }
  77. scalarmul_fixed_base_wnaf_vt(&work, scalar, nbits, pre, i);
  78. untwist_and_double_and_serialize(&wout[i], &work);
  79. }
  80. mask_t consistent = MASK_SUCCESS;
  81. if (nbits == 448) {
  82. /* window methods currently only work on 448 bits. */
  83. copy_tw_extensible(&work, &text);
  84. scalarmul(&work, scalar);
  85. untwist_and_double_and_serialize(&ct, &work);
  86. copy_tw_extensible(&work, &text);
  87. scalarmul_vlook(&work, scalar);
  88. untwist_and_double_and_serialize(&vl, &work);
  89. copy_tw_extensible(&work, &text);
  90. scalarmul_vt(&work, scalar);
  91. untwist_and_double_and_serialize(&vt, &work);
  92. /* check consistency mont vs window */
  93. consistent &= p448_eq(&mont, &ct);
  94. consistent &= p448_eq(&mont, &vl);
  95. consistent &= p448_eq(&mont, &vt);
  96. }
  97. /* check consistency mont vs combs */
  98. for (i=0; i<nparams; i++) {
  99. consistent &= p448_eq(&mont,&fbout[i]);
  100. }
  101. /* check consistency mont vs wNAF */
  102. for (i=0; i<6; i++) {
  103. consistent &= p448_eq(&mont,&wout[i]);
  104. }
  105. /* If inconsistent, complain. */
  106. if (!consistent) {
  107. youfail();
  108. printf(" Failed scalarmul consistency test with nbits=%d.\n",nbits);
  109. p448_print(" base", base);
  110. scalar_print(" scal", scalar, (nbits+WORD_BITS-1)/WORD_BITS);
  111. p448_print(" mont", &mont);
  112. for (i=0; i<nparams; i++) {
  113. printf(" With n=%d, t=%d, s=%d:\n", params[i].n, params[i].t, params[i].s);
  114. p448_print(" out ", &fbout[i]);
  115. }
  116. for (i=0; i<6; i++) {
  117. printf(" With w=%d:\n",i);
  118. p448_print(" wNAF", &wout[i]);
  119. }
  120. if (nbits == 448) {
  121. p448_print(" ct ", &ct);
  122. p448_print(" vl ", &vl);
  123. p448_print(" vt ", &vt);
  124. }
  125. ret = -1;
  126. }
  127. return ret;
  128. }
  129. static int
  130. single_linear_combo_test (
  131. const struct p448_t *base1,
  132. const word_t *scalar1,
  133. int nbits1,
  134. const struct p448_t *base2,
  135. const word_t *scalar2,
  136. int nbits2
  137. ) {
  138. /* MAGIC */
  139. const struct p448_t
  140. sqrt_d_minus_1 = {{
  141. U58LE(0xd2e21836749f46),
  142. U58LE(0x888db42b4f0179),
  143. U58LE(0x5a189aabdeea38),
  144. U58LE(0x51e65ca6f14c06),
  145. U58LE(0xa49f7b424d9770),
  146. U58LE(0xdcac4628c5f656),
  147. U58LE(0x49443b8748734a),
  148. U58LE(0x12fec0c0b25b7a)
  149. }};
  150. struct tw_extensible_t text1, text2, working;
  151. struct tw_pniels_t pn;
  152. struct p448_t result_comb, result_combo, result_wnaf;
  153. mask_t succ =
  154. deserialize_and_twist_approx(&text1, &sqrt_d_minus_1, base1)
  155. & deserialize_and_twist_approx(&text2, &sqrt_d_minus_1, base2);
  156. if (!succ) return 1;
  157. struct fixed_base_table_t t1, t2;
  158. struct tw_niels_t wnaf[32];
  159. memset(&t1,0,sizeof(t1));
  160. memset(&t2,0,sizeof(t2));
  161. succ = precompute_fixed_base(&t1, &text1, 5, 5, 18, NULL);
  162. succ &= precompute_fixed_base(&t2, &text2, 6, 3, 25, NULL);
  163. succ &= precompute_fixed_base_wnaf(wnaf, &text2, 5);
  164. if (!succ) {
  165. destroy_fixed_base(&t1);
  166. destroy_fixed_base(&t2);
  167. return -1;
  168. }
  169. /* use the dedicated wNAF linear combo algorithm */
  170. copy_tw_extensible(&working, &text1);
  171. linear_combo_var_fixed_vt(&working, scalar1, nbits1, scalar2, nbits2, wnaf, 5);
  172. untwist_and_double_and_serialize(&result_wnaf, &working);
  173. /* use the dedicated combs algorithm */
  174. succ &= linear_combo_combs_vt(&working, scalar1, nbits1, &t1, scalar2, nbits2, &t2);
  175. untwist_and_double_and_serialize(&result_combo, &working);
  176. /* use two combs */
  177. succ &= scalarmul_fixed_base(&working, scalar1, nbits1, &t1);
  178. convert_tw_extensible_to_tw_pniels(&pn, &working);
  179. succ &= scalarmul_fixed_base(&working, scalar2, nbits2, &t2);
  180. add_tw_pniels_to_tw_extensible(&working, &pn);
  181. untwist_and_double_and_serialize(&result_comb, &working);
  182. mask_t consistent = MASK_SUCCESS;
  183. consistent &= p448_eq(&result_combo, &result_wnaf);
  184. consistent &= p448_eq(&result_comb, &result_wnaf);
  185. if (!succ || !consistent) {
  186. youfail();
  187. printf(" Failed linear combo consistency test with nbits=%d,%d.\n",nbits1,nbits2);
  188. p448_print(" base1", base1);
  189. scalar_print(" scal1", scalar1, (nbits1+WORD_BITS-1)/WORD_BITS);
  190. p448_print(" base2", base2);
  191. scalar_print(" scal2", scalar2, (nbits1+WORD_BITS-1)/WORD_BITS);
  192. p448_print(" combs", &result_comb);
  193. p448_print(" combo", &result_combo);
  194. p448_print(" wNAFs", &result_wnaf);
  195. return -1;
  196. }
  197. destroy_fixed_base(&t1);
  198. destroy_fixed_base(&t2);
  199. return 0;
  200. }
  201. /* 0 = succeed, 1 = inval, -1 = fail */
  202. static int
  203. single_scalarmul_commutativity_test (
  204. const struct p448_t *base,
  205. const word_t *scalar1,
  206. int nbits1,
  207. int ned1,
  208. const word_t *scalar2,
  209. int nbits2,
  210. int ned2
  211. ) {
  212. struct p448_t m12, m21, tmp1, tmp2;
  213. mask_t succ12a = montgomery_ladder(&tmp1,base,scalar1,nbits1,ned1);
  214. mask_t succ12b = montgomery_ladder(&m12,&tmp1,scalar2,nbits2,ned2);
  215. mask_t succ21a = montgomery_ladder(&tmp2,base,scalar2,nbits2,ned2);
  216. mask_t succ21b = montgomery_ladder(&m21,&tmp2,scalar1,nbits1,ned1);
  217. mask_t succ12 = succ12a & succ12b, succ21 = succ21a & succ21b;
  218. if (succ12 != succ21) {
  219. youfail();
  220. printf(" Failed scalarmul commutativity test with (nbits,ned) = (%d,%d), (%d,%d).\n",
  221. nbits1,ned1,nbits2,ned2);
  222. p448_print(" base", base);
  223. p448_print(" tmp1", &tmp1);
  224. p448_print(" tmp2", &tmp2);
  225. scalar_print(" sca1", scalar1, (nbits1+WORD_BITS-1)/WORD_BITS);
  226. scalar_print(" sca2", scalar2, (nbits1+WORD_BITS-1)/WORD_BITS);
  227. printf(" good = ((%d,%d),(%d,%d))\n", (int)-succ12a,
  228. (int)-succ12b, (int)-succ21a, (int)-succ21b);
  229. return -1;
  230. } else if (!succ12) {
  231. // printf(" (nbits,ned) = (%d,%d), (%d,%d).\n", nbits1,ned1,nbits2,ned2);
  232. // printf(" succ = (%d,%d), (%d,%d).\n", (int)-succ12a, (int)-succ12b, (int)-succ21a, (int)-succ21b);
  233. return 1;
  234. }
  235. mask_t consistent = p448_eq(&m12,&m21);
  236. if (consistent) {
  237. return 0;
  238. } else {
  239. youfail();
  240. printf(" Failed scalarmul commutativity test with (nbits,ned) = (%d,%d), (%d,%d).\n",
  241. nbits1,ned1,nbits2,ned2);
  242. p448_print(" base", base);
  243. scalar_print(" sca1", scalar1, (nbits1+WORD_BITS-1)/WORD_BITS);
  244. scalar_print(" sca2", scalar2, (nbits1+WORD_BITS-1)/WORD_BITS);
  245. p448_print(" m12 ", &m12);
  246. p448_print(" m21 ", &m21);
  247. return -1;
  248. }
  249. }
  250. int test_scalarmul_commutativity () {
  251. int i,j,k,got;
  252. struct crandom_state_t crand;
  253. crandom_init_from_buffer(&crand, "scalarmul_commutativity_test RNG");
  254. for (i=0; i<=448; i+=7) {
  255. for (j=0; j<=448; j+=7) {
  256. got = 0;
  257. for (k=0; k<128 && !got; k++) {
  258. uint8_t ser[56];
  259. word_t scalar1[7], scalar2[7];
  260. crandom_generate(&crand, ser, sizeof(ser));
  261. crandom_generate(&crand, (uint8_t *)scalar1, sizeof(scalar1));
  262. crandom_generate(&crand, (uint8_t *)scalar2, sizeof(scalar2));
  263. p448_t base;
  264. mask_t succ = p448_deserialize(&base, ser);
  265. if (!succ) continue;
  266. int ret = single_scalarmul_commutativity_test (&base, scalar1, i, i%3, scalar2, j, j%3);
  267. got = !ret;
  268. if (ret == -1) return -1;
  269. }
  270. if (!got) {
  271. youfail();
  272. printf(" Unlikely: rejected 128 scalars in a row.\n");
  273. return -1;
  274. }
  275. }
  276. }
  277. return 0;
  278. }
  279. int test_linear_combo () {
  280. int i,j,k,got;
  281. struct crandom_state_t crand;
  282. crandom_init_from_buffer(&crand, "scalarmul_linear_combos_test RNG");
  283. for (i=0; i<=448; i+=7) {
  284. for (j=0; j<=448; j+=7) {
  285. got = 0;
  286. for (k=0; k<128 && !got; k++) {
  287. uint8_t ser[56];
  288. word_t scalar1[7], scalar2[7];
  289. crandom_generate(&crand, (uint8_t *)scalar1, sizeof(scalar1));
  290. crandom_generate(&crand, (uint8_t *)scalar2, sizeof(scalar2));
  291. p448_t base1;
  292. crandom_generate(&crand, ser, sizeof(ser));
  293. mask_t succ = p448_deserialize(&base1, ser);
  294. if (!succ) continue;
  295. p448_t base2;
  296. crandom_generate(&crand, ser, sizeof(ser));
  297. succ = p448_deserialize(&base2, ser);
  298. if (!succ) continue;
  299. int ret = single_linear_combo_test (&base1, scalar1, i, &base2, scalar2, j);
  300. got = !ret;
  301. if (ret == -1) return -1;
  302. }
  303. if (!got) {
  304. youfail();
  305. printf(" Unlikely: rejected 128 scalars in a row.\n");
  306. return -1;
  307. }
  308. }
  309. }
  310. return 0;
  311. }
  312. int test_scalarmul_compatibility () {
  313. int i,j,k,got;
  314. struct crandom_state_t crand;
  315. crandom_init_from_buffer(&crand, "scalarmul_compatibility_test RNG");
  316. for (i=0; i<=448; i+=7) {
  317. for (j=0; j<=20; j++) {
  318. got = 0;
  319. for (k=0; k<128 && !got; k++) {
  320. uint8_t ser[56];
  321. word_t scalar[7];
  322. crandom_generate(&crand, ser, sizeof(ser));
  323. crandom_generate(&crand, (uint8_t *)scalar, sizeof(scalar));
  324. p448_t base;
  325. mask_t succ = p448_deserialize(&base, ser);
  326. if (!succ) continue;
  327. int ret = single_scalarmul_compatibility_test (&base, scalar, i);
  328. got = !ret;
  329. if (ret == -1) return -1;
  330. }
  331. if (!got) {
  332. youfail();
  333. printf(" Unlikely: rejected 128 scalars in a row.\n");
  334. return -1;
  335. }
  336. }
  337. }
  338. return 0;
  339. }