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.
 
 
 
 
 

288 lines
7.5 KiB

  1. #include "test.h"
  2. #include <stdio.h>
  3. #include "ec_point.h"
  4. #include "field.h"
  5. #include "crandom.h"
  6. static void
  7. failprint_ext (
  8. const struct extensible_t *a
  9. ) {
  10. struct field_t zi, scaled;
  11. field_print(" x", &a->x);
  12. field_print(" y", &a->y);
  13. field_print(" z", &a->z);
  14. field_inverse(&zi, &a->z);
  15. field_mul(&scaled, &zi, &a->x);
  16. field_print(" X", &scaled);
  17. field_mul(&scaled, &zi, &a->y);
  18. field_print(" Y", &scaled);
  19. printf("\n");
  20. }
  21. static void
  22. failprint_tw_ext (
  23. const struct tw_extensible_t *a
  24. ) {
  25. failprint_ext((const struct extensible_t *)a);
  26. }
  27. static mask_t
  28. fail_if_different (
  29. const struct extensible_t *a,
  30. const struct extensible_t *b,
  31. const char *faildescr,
  32. const char *adescr,
  33. const char *bdescr
  34. ) {
  35. mask_t succ = eq_extensible(a, b);
  36. if (!succ) {
  37. youfail();
  38. printf(" %s\n", faildescr);
  39. printf("\n %s:\n", adescr);
  40. failprint_ext(a);
  41. printf("\n %s:\n", bdescr);
  42. failprint_ext(b);
  43. }
  44. return succ;
  45. }
  46. static mask_t
  47. validate_ext(
  48. const struct extensible_t *ext,
  49. int evenness,
  50. const char *description
  51. ) {
  52. mask_t succ = validate_extensible(ext), succ2;
  53. const char *error = "Point isn't on the curve.";
  54. if (evenness > 0) {
  55. succ2 = is_even_pt(ext);
  56. if (succ &~ succ2) error = "Point isn't even.";
  57. succ &= succ2;
  58. } else if (evenness < 0) {
  59. succ2 = is_even_pt(ext);
  60. if (succ &~ succ2) error = "Point is even but shouldn't be.";
  61. succ &= succ2;
  62. } /* FUTURE: quadness */
  63. if (~succ) {
  64. youfail();
  65. printf(" %s\n", error);
  66. printf(" %s\n", description);
  67. failprint_ext(ext);
  68. }
  69. return succ;
  70. }
  71. static mask_t
  72. validate_tw_ext(
  73. const struct tw_extensible_t *ext,
  74. int evenness,
  75. const char *description
  76. ) {
  77. mask_t succ = validate_tw_extensible(ext), succ2;
  78. const char *error = "Point isn't on the twisted curve.";
  79. if (evenness > 0) {
  80. succ2 = is_even_tw(ext);
  81. if (succ &~ succ2) error = "Point isn't even.";
  82. succ &= succ2;
  83. } else if (evenness < 0) {
  84. succ2 = is_even_tw(ext);
  85. if (succ &~ succ2) error = "Point is even but shouldn't be.";
  86. succ &= succ2;
  87. } /* FUTURE: quadness */
  88. if (~succ) {
  89. youfail();
  90. printf(" %s\n", error);
  91. printf(" %s\n", description);
  92. failprint_tw_ext(ext);
  93. }
  94. return succ;
  95. }
  96. static mask_t
  97. fail_if_different_tw (
  98. const struct tw_extensible_t *a,
  99. const struct tw_extensible_t *b,
  100. const char *faildescr,
  101. const char *adescr,
  102. const char *bdescr
  103. ) {
  104. return fail_if_different(
  105. (const struct extensible_t *)a, (const struct extensible_t *)b,
  106. faildescr,adescr,bdescr
  107. );
  108. }
  109. static int
  110. add_double_test (
  111. const struct affine_t *base1,
  112. const struct affine_t *base2
  113. ) {
  114. mask_t succ = MASK_SUCCESS;
  115. struct extensible_t exb;
  116. struct tw_extensible_t text1, text2, texta, textb;
  117. struct tw_pniels_t pn;
  118. /* Convert to ext */
  119. convert_affine_to_extensible(&exb, base1);
  120. succ &= validate_ext(&exb,0,"base1");
  121. twist_and_double(&text1, &exb);
  122. succ &= validate_tw_ext(&text1,2,"iso1");
  123. convert_affine_to_extensible(&exb, base2);
  124. succ &= validate_ext(&exb,0,"base2");
  125. twist_and_double(&text2, &exb);
  126. succ &= validate_tw_ext(&text2,2,"iso2");
  127. /* a + b == b + a? */
  128. convert_tw_extensible_to_tw_pniels(&pn, &text1);
  129. copy_tw_extensible(&texta, &text2);
  130. add_tw_pniels_to_tw_extensible(&texta, &pn);
  131. convert_tw_extensible_to_tw_pniels(&pn, &text2);
  132. copy_tw_extensible(&textb, &text1);
  133. add_tw_pniels_to_tw_extensible(&textb, &pn);
  134. succ &= fail_if_different_tw(&texta,&textb,"Addition commutativity","a+b","b+a");
  135. copy_tw_extensible(&textb, &text2);
  136. add_tw_pniels_to_tw_extensible(&textb, &pn);
  137. copy_tw_extensible(&texta, &text2);
  138. double_tw_extensible(&texta);
  139. succ &= fail_if_different_tw(&texta,&textb,"Doubling test","2b","b+b");
  140. if (~succ) {
  141. printf(" Bases were:\n");
  142. field_print(" x1", &base1->x);
  143. field_print(" y1", &base1->y);
  144. field_print(" x2", &base2->x);
  145. field_print(" y2", &base2->y);
  146. }
  147. return succ ? 0 : -1;
  148. }
  149. static int
  150. single_twisting_test (
  151. const struct affine_t *base
  152. ) {
  153. struct extensible_t exb, ext, tmpext;
  154. struct tw_extensible_t text, text2;
  155. mask_t succ = MASK_SUCCESS;
  156. convert_affine_to_extensible(&exb, base);
  157. succ &= validate_ext(&exb,0,"base");
  158. /* check: dual . iso = 4 */
  159. twist_and_double(&text, &exb);
  160. succ &= validate_tw_ext(&text,2,"iso");
  161. untwist_and_double(&ext, &text);
  162. succ &= validate_ext(&ext,2,"dual.iso");
  163. copy_extensible(&tmpext,&exb);
  164. double_extensible(&tmpext);
  165. succ &= validate_ext(&tmpext,1,"2*base");
  166. double_extensible(&tmpext);
  167. succ &= validate_ext(&tmpext,2,"4*base");
  168. succ &= fail_if_different(&ext,&tmpext,"Isogeny and dual","Dual . iso","4*base");
  169. /* check: twist and serialize */
  170. test_only_twist(&text, &exb);
  171. succ &= validate_tw_ext(&text,0,"tot");
  172. mask_t evt = is_even_tw(&text), evb = is_even_pt(&exb);
  173. if (evt != evb) {
  174. youfail();
  175. printf(" Different evenness from twist base: %d, twist: %d\n", (int)-evt, (int)-evb);
  176. succ = 0;
  177. } /* FUTURE: quadness */
  178. field_t sera,serb;
  179. untwist_and_double_and_serialize(&sera,&text);
  180. copy_extensible(&tmpext,&exb);
  181. double_extensible(&tmpext);
  182. serialize_extensible(&serb,&tmpext);
  183. /* check that their (doubled; FUTURE?) serializations are equal */
  184. if (~field_eq(&sera,&serb)) {
  185. youfail();
  186. printf(" Different serialization from twist + double ()\n");
  187. field_print(" t", &sera);
  188. field_print(" b", &serb);
  189. succ = 0;
  190. }
  191. untwist_and_double(&ext, &text);
  192. succ &= validate_ext(&tmpext,1,"dual.tot");
  193. twist_and_double(&text2, &ext);
  194. succ &= validate_tw_ext(&text2,2,"iso.dual.tot");
  195. double_tw_extensible(&text);
  196. succ &= validate_tw_ext(&text,1,"2*tot");
  197. double_tw_extensible(&text);
  198. succ &= validate_tw_ext(&text,2,"4*tot");
  199. succ &= fail_if_different_tw(&text,&text2,"Dual and isogeny","4*tot","iso.dual.tot");
  200. if (~succ) {
  201. printf(" Base was:\n");
  202. field_print(" x", &base->x);
  203. field_print(" y", &base->y);
  204. }
  205. return succ ? 0 : -1;
  206. }
  207. int test_pointops (void) {
  208. struct affine_t base, pbase;
  209. struct field_t serf;
  210. struct crandom_state_t crand;
  211. crandom_init_from_buffer(&crand, "test_pointops random initializer");
  212. int i, ret;
  213. for (i=0; i<1000; i++) {
  214. uint8_t ser[FIELD_BYTES];
  215. crandom_generate(&crand, ser, sizeof(ser));
  216. /* TODO: we need a field generate, which can return random or pathological. */
  217. mask_t succ = field_deserialize(&serf, ser);
  218. if (!succ) {
  219. youfail();
  220. printf(" Unlikely: fail at field_deserialize\n");
  221. return -1;
  222. }
  223. if (i) {
  224. copy_affine(&pbase, &base);
  225. }
  226. elligator_2s_inject(&base, &serf);
  227. if (i) {
  228. ret = add_double_test(&base, &pbase);
  229. if (ret) return ret;
  230. }
  231. ret = single_twisting_test(&base);
  232. if (ret) return ret;
  233. }
  234. return 0;
  235. }