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.
 
 
 
 
 

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