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
12 KiB

  1. #include "test.h"
  2. #include <stdio.h>
  3. #include "ec_point.h"
  4. #include "magic.h"
  5. #include "field.h"
  6. #include "crandom.h"
  7. static void
  8. failprint_ext (
  9. const struct extensible_t *a
  10. ) {
  11. field_a_t zi, scaled;
  12. field_print(" x", a->x);
  13. field_print(" y", a->y);
  14. field_print(" z", a->z);
  15. field_inverse(zi, a->z);
  16. field_mul(scaled, zi, a->x);
  17. field_print(" X", scaled);
  18. field_mul(scaled, zi, a->y);
  19. field_print(" Y", scaled);
  20. printf("\n");
  21. }
  22. static void
  23. failprint_tw_ext (
  24. const struct tw_extensible_t *a
  25. ) {
  26. failprint_ext((const struct extensible_t *)a);
  27. }
  28. static mask_t
  29. fail_if_different (
  30. const struct extensible_t *a,
  31. const struct extensible_t *b,
  32. const char *faildescr,
  33. const char *adescr,
  34. const char *bdescr
  35. ) {
  36. mask_t succ = eq_extensible(a, b);
  37. if (!succ) {
  38. youfail();
  39. printf(" %s\n", faildescr);
  40. printf("\n %s:\n", adescr);
  41. failprint_ext(a);
  42. printf("\n %s:\n", bdescr);
  43. failprint_ext(b);
  44. }
  45. return succ;
  46. }
  47. static mask_t
  48. validate_ext(
  49. const struct extensible_t *ext,
  50. int evenness,
  51. const char *description
  52. ) {
  53. mask_t succ = validate_extensible(ext), succ2;
  54. const char *error = "Point isn't on the curve.";
  55. if (evenness > 0) {
  56. succ2 = is_even_pt(ext);
  57. if (succ &~ succ2) error = "Point isn't even.";
  58. succ &= succ2;
  59. } else if (evenness < 0) {
  60. succ2 = is_even_pt(ext);
  61. if (succ &~ succ2) error = "Point is even but shouldn't be.";
  62. succ &= succ2;
  63. } /* FUTURE: quadness */
  64. if (~succ) {
  65. youfail();
  66. printf(" %s\n", error);
  67. printf(" %s\n", description);
  68. failprint_ext(ext);
  69. }
  70. return succ;
  71. }
  72. static mask_t
  73. validate_tw_ext(
  74. const struct tw_extensible_t *ext,
  75. int evenness,
  76. const char *description
  77. ) {
  78. mask_t succ = validate_tw_extensible(ext), succ2;
  79. const char *error = "Point isn't on the twisted curve.";
  80. if (evenness > 0) {
  81. succ2 = is_even_tw(ext);
  82. if (succ &~ succ2) error = "Point isn't even.";
  83. succ &= succ2;
  84. } else if (evenness < 0) {
  85. succ2 = is_even_tw(ext);
  86. if (succ &~ succ2) error = "Point is even but shouldn't be.";
  87. succ &= succ2;
  88. } /* FUTURE: quadness */
  89. if (~succ) {
  90. youfail();
  91. printf(" %s\n", error);
  92. printf(" %s\n", description);
  93. failprint_tw_ext(ext);
  94. }
  95. return succ;
  96. }
  97. static mask_t
  98. fail_if_different_tw (
  99. const struct tw_extensible_t *a,
  100. const struct tw_extensible_t *b,
  101. const char *faildescr,
  102. const char *adescr,
  103. const char *bdescr
  104. ) {
  105. return fail_if_different(
  106. (const struct extensible_t *)a, (const struct extensible_t *)b,
  107. faildescr,adescr,bdescr
  108. );
  109. }
  110. static int
  111. add_double_test (
  112. const struct affine_t *base1,
  113. const struct affine_t *base2
  114. ) {
  115. mask_t succ = MASK_SUCCESS;
  116. struct extensible_t exb;
  117. struct tw_extensible_t text1, text2, texta, textb;
  118. struct tw_pniels_t pn;
  119. /* Convert to ext */
  120. convert_affine_to_extensible(&exb, base1);
  121. succ &= validate_ext(&exb,0,"base1");
  122. twist_and_double(&text1, &exb);
  123. succ &= validate_tw_ext(&text1,2,"iso1");
  124. convert_affine_to_extensible(&exb, base2);
  125. succ &= validate_ext(&exb,0,"base2");
  126. twist_and_double(&text2, &exb);
  127. succ &= validate_tw_ext(&text2,2,"iso2");
  128. /* a + b == b + a? */
  129. convert_tw_extensible_to_tw_pniels(&pn, &text1);
  130. copy_tw_extensible(&texta, &text2);
  131. add_tw_pniels_to_tw_extensible(&texta, &pn);
  132. convert_tw_extensible_to_tw_pniels(&pn, &text2);
  133. copy_tw_extensible(&textb, &text1);
  134. add_tw_pniels_to_tw_extensible(&textb, &pn);
  135. succ &= fail_if_different_tw(&texta,&textb,"Addition commutativity","a+b","b+a");
  136. copy_tw_extensible(&textb, &text2);
  137. add_tw_pniels_to_tw_extensible(&textb, &pn);
  138. copy_tw_extensible(&texta, &text2);
  139. double_tw_extensible(&texta);
  140. succ &= fail_if_different_tw(&texta,&textb,"Doubling test","2b","b+b");
  141. if (~succ) {
  142. printf(" Bases were:\n");
  143. field_print(" x1", base1->x);
  144. field_print(" y1", base1->y);
  145. field_print(" x2", base2->x);
  146. field_print(" y2", base2->y);
  147. }
  148. return succ ? 0 : -1;
  149. }
  150. static int
  151. single_twisting_test (
  152. const struct affine_t *base
  153. ) {
  154. struct extensible_t exb, ext, tmpext;
  155. struct tw_extensible_t text, text2;
  156. mask_t succ = MASK_SUCCESS;
  157. convert_affine_to_extensible(&exb, base);
  158. succ &= validate_ext(&exb,0,"base");
  159. /* check: dual . iso = 4 */
  160. twist_and_double(&text, &exb);
  161. succ &= validate_tw_ext(&text,2,"iso");
  162. untwist_and_double(&ext, &text);
  163. succ &= validate_ext(&ext,2,"dual.iso");
  164. copy_extensible(&tmpext,&exb);
  165. double_extensible(&tmpext);
  166. succ &= validate_ext(&tmpext,1,"2*base");
  167. double_extensible(&tmpext);
  168. succ &= validate_ext(&tmpext,2,"4*base");
  169. succ &= fail_if_different(&ext,&tmpext,"Isogeny and dual","Dual . iso","4*base");
  170. /* check: twist and serialize */
  171. test_only_twist(&text, &exb);
  172. succ &= validate_tw_ext(&text,0,"tot");
  173. mask_t evt = is_even_tw(&text), evb = is_even_pt(&exb);
  174. if (evt != evb) {
  175. youfail();
  176. printf(" Different evenness from twist base: %d, twist: %d\n", (int)-evt, (int)-evb);
  177. succ = 0;
  178. } /* FUTURE: quadness */
  179. field_a_t sera,serb;
  180. untwist_and_double_and_serialize(sera,&text);
  181. copy_extensible(&tmpext,&exb);
  182. double_extensible(&tmpext);
  183. serialize_extensible(serb,&tmpext);
  184. /* check that their (doubled; FUTURE?) serializations are equal */
  185. if (~field_eq(sera,serb)) {
  186. youfail();
  187. printf(" Different serialization from twist + double ()\n");
  188. field_print(" t", sera);
  189. field_print(" b", serb);
  190. succ = 0;
  191. }
  192. untwist_and_double(&ext, &text);
  193. succ &= validate_ext(&tmpext,1,"dual.tot");
  194. twist_and_double(&text2, &ext);
  195. succ &= validate_tw_ext(&text2,2,"iso.dual.tot");
  196. double_tw_extensible(&text);
  197. succ &= validate_tw_ext(&text,1,"2*tot");
  198. double_tw_extensible(&text);
  199. succ &= validate_tw_ext(&text,2,"4*tot");
  200. succ &= fail_if_different_tw(&text,&text2,"Dual and isogeny","4*tot","iso.dual.tot");
  201. if (~succ) {
  202. printf(" Base was:\n");
  203. field_print(" x", base->x);
  204. field_print(" y", base->y);
  205. }
  206. return succ ? 0 : -1;
  207. }
  208. int test_decaf (void) {
  209. struct affine_t base;
  210. struct tw_affine_t tw_base;
  211. field_a_t serf;
  212. struct crandom_state_t crand;
  213. crandom_init_from_buffer(&crand, "my test_decaf random initializer");
  214. int i, hits = 0, fails = 0;
  215. for (i=0; i<1000; i++) {
  216. uint8_t ser[FIELD_BYTES];
  217. crandom_generate(&crand, ser, sizeof(ser));
  218. #if (FIELD_BITS % 8)
  219. ser[FIELD_BYTES-1] &= (1<<(FIELD_BITS%8)) - 1;
  220. #endif
  221. ser[0] &= ~1;
  222. mask_t succ = field_deserialize(serf, ser);
  223. if (!succ) {
  224. youfail();
  225. printf(" Unlikely: fail at field_deserialize\n");
  226. return -1;
  227. }
  228. succ &= decaf_deserialize_affine(&base, serf, 0);
  229. if (!succ) continue;
  230. hits++;
  231. field_a_t serf2;
  232. struct extensible_t ext;
  233. convert_affine_to_extensible(&ext, &base);
  234. decaf_serialize_extensible(serf2, &ext);
  235. if (~validate_affine(&base)) {
  236. youfail();
  237. printf("Invalid decaf deser:\n");
  238. field_print(" s", serf);
  239. field_print(" x", base.x);
  240. field_print(" y", base.y);
  241. fails ++;
  242. } else if (~field_eq(serf, serf2)) {
  243. youfail();
  244. printf("Fail round-trip through decaf ser:\n");
  245. field_print(" s", serf);
  246. field_print(" x", base.x);
  247. field_print(" y", base.y);
  248. printf(" deser is %s\n", validate_affine(&base) ? "valid" : "invalid");
  249. field_print(" S", serf2);
  250. fails ++;
  251. } else if (~is_even_pt(&ext)) {
  252. youfail();
  253. printf("Decaf deser isn't even:\n");
  254. field_print(" s", serf);
  255. field_print(" x", base.x);
  256. field_print(" y", base.y);
  257. fails ++;
  258. }
  259. succ = decaf_deserialize_tw_affine(&tw_base, serf, 0);
  260. struct tw_extensible_t tw_ext, tw_ext2;
  261. convert_tw_affine_to_tw_extensible(&tw_ext, &tw_base);
  262. decaf_serialize_tw_extensible(serf2, &tw_ext);
  263. twist_even(&tw_ext2, &ext);
  264. if (~validate_tw_extensible(&tw_ext)) {
  265. youfail();
  266. printf("Invalid decaf tw deser:\n");
  267. field_print(" s", serf);
  268. field_print(" x", tw_base.x);
  269. field_print(" y", tw_base.y);
  270. fails ++;
  271. } else if (~field_eq(serf, serf2)) {
  272. youfail();
  273. printf("Fail round-trip through decaf ser:\n");
  274. field_print(" s", serf);
  275. field_print(" x", tw_base.x);
  276. field_print(" y", tw_base.y);
  277. printf(" tw deser is %s\n", validate_tw_extensible(&tw_ext) ? "valid" : "invalid");
  278. field_print(" S", serf2);
  279. fails ++;
  280. } else if (~is_even_tw(&tw_ext)) {
  281. youfail();
  282. printf("Decaf tw deser isn't even:\n");
  283. field_print(" s", serf);
  284. field_print(" x", tw_base.x);
  285. field_print(" y", tw_base.y);
  286. fails ++;
  287. } else if (~decaf_eq_tw_extensible(&tw_ext,&tw_ext2)) {
  288. youfail();
  289. printf("Decaf tw doesn't equal ext:\n");
  290. field_print(" s", serf);
  291. field_print(" x1", base.x);
  292. field_print(" y1", base.y);
  293. field_print(" x2", tw_base.x);
  294. field_print(" y2", tw_base.y);
  295. field_print(" X2", tw_ext2.x);
  296. field_print(" Y2", tw_ext2.y);
  297. fails ++;
  298. }
  299. }
  300. if (hits < 350) {
  301. youfail();
  302. printf(" Unlikely: only %d successes in decaf_deser\n", hits);
  303. return -1;
  304. } else if (fails) {
  305. return -1;
  306. } else {
  307. return 0;
  308. }
  309. }
  310. int test_pointops (void) {
  311. struct affine_t base, pbase;
  312. field_a_t serf;
  313. struct crandom_state_t crand;
  314. crandom_init_from_buffer(&crand, "test_pointops random initializer");
  315. struct extensible_t ext_base;
  316. if (!validate_affine(&goldilocks_base_point)) {
  317. youfail();
  318. printf(" Base point isn't on the curve.\n");
  319. return -1;
  320. }
  321. convert_affine_to_extensible(&ext_base, &goldilocks_base_point);
  322. if (!validate_ext(&ext_base, 2, "base")) return -1;
  323. int i, ret;
  324. for (i=0; i<1000; i++) {
  325. uint8_t ser[FIELD_BYTES];
  326. crandom_generate(&crand, ser, sizeof(ser));
  327. #if (FIELD_BITS % 8)
  328. ser[FIELD_BYTES-1] &= (1<<(FIELD_BITS%8)) - 1;
  329. #endif
  330. /* TODO: we need a field generate, which can return random or pathological. */
  331. mask_t succ = field_deserialize(serf, ser);
  332. if (!succ) {
  333. youfail();
  334. printf(" Unlikely: fail at field_deserialize\n");
  335. return -1;
  336. }
  337. if (i) {
  338. copy_affine(&pbase, &base);
  339. }
  340. elligator_2s_inject(&base, serf);
  341. if (i) {
  342. ret = add_double_test(&base, &pbase);
  343. if (ret) return ret;
  344. }
  345. ret = single_twisting_test(&base);
  346. //if (ret) return ret;
  347. }
  348. return 0;
  349. }