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.
 
 
 
 
 

416 lines
13 KiB

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