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.
 
 
 
 
 

190 lines
6.1 KiB

  1. /* Copyright (c) 2015 Cryptography Research, Inc.
  2. * Released under the MIT License. See LICENSE.txt for license information.
  3. */
  4. /**
  5. * @file decaf_precompute.c
  6. * @author Mike Hamburg
  7. * @brief Decaf global constant table precomputation.
  8. */
  9. #define _XOPEN_SOURCE 600 /* for posix_memalign */
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include "field.h"
  13. #include "f_field.h"
  14. #include "decaf.h"
  15. #include "decaf_config.h"
  16. #define GEN_TABLES
  17. #include "curve_data.inc.c"
  18. /* To satisfy linker. */
  19. const gf API_NS(precomputed_base_as_fe)[1];
  20. const API_NS(scalar_t) API_NS(precomputed_scalarmul_adjustment);
  21. const API_NS(scalar_t) API_NS(point_scalarmul_adjustment);
  22. const API_NS(scalar_t) API_NS(sc_r2) = {{{0}}};
  23. const decaf_word_t API_NS(MONTGOMERY_FACTOR) = 0;
  24. const API_NS(point_t) API_NS(point_base);
  25. const uint8_t API_NS(x_base_point)[X_PUBLIC_BYTES] = {0};
  26. struct niels_s;
  27. const gf_s *API_NS(precomputed_wnaf_as_fe);
  28. extern const size_t API_NS2(sizeof,precomputed_wnafs);
  29. void API_NS(precompute_wnafs) (
  30. struct niels_s *out,
  31. const API_NS(point_t) base
  32. );
  33. static void scalar_print(const char *name, const API_NS(scalar_t) sc) { /* UNIFY */
  34. printf("const API_NS(scalar_t) %s = {{{\n", name);
  35. const int SCALAR_BYTES = (SCALAR_BITS + 7) / 8;
  36. unsigned char ser[SCALAR_BYTES];
  37. API_NS(scalar_encode)(ser,sc);
  38. int b=0, i, comma=0;
  39. unsigned long long limb = 0;
  40. for (i=0; i<SCALAR_BYTES; i++) {
  41. limb |= ((uint64_t)ser[i])<<b;
  42. b += 8;
  43. if (b == 64 || i==SCALAR_BYTES-1) {
  44. b = 0;
  45. if (comma) printf(",");
  46. comma = 1;
  47. printf("SC_LIMB(0x%016llx)", limb);
  48. limb = ((uint64_t)ser[i])>>(8-b);
  49. }
  50. }
  51. printf("}}};\n\n");
  52. }
  53. static void field_print(const gf f) { /* UNIFY */
  54. unsigned char ser[SER_BYTES];
  55. gf_serialize(ser,f);
  56. int b=0, i, comma=0;
  57. unsigned long long limb = 0;
  58. printf("{FIELD_LITERAL(");
  59. for (i=0; i<SER_BYTES; i++) {
  60. limb |= ((uint64_t)ser[i])<<b;
  61. b += 8;
  62. if (b >= GF_LIT_LIMB_BITS || i == SER_BYTES-1) {
  63. limb &= (1ull<<GF_LIT_LIMB_BITS) -1;
  64. b -= GF_LIT_LIMB_BITS;
  65. if (comma) printf(",");
  66. comma = 1;
  67. printf("0x%016llx", limb);
  68. limb = ((uint64_t)ser[i])>>(8-b);
  69. }
  70. }
  71. printf(")}");
  72. assert(b<8);
  73. }
  74. int main(int argc, char **argv) {
  75. (void)argc; (void)argv;
  76. API_NS(point_t) real_point_base;
  77. int ret = API_NS(point_decode)(real_point_base,base_point_ser_for_pregen,0);
  78. if (ret != DECAF_SUCCESS) return 1;
  79. API_NS(precomputed_s) *pre;
  80. ret = posix_memalign((void**)&pre, API_NS2(alignof,precomputed_s), API_NS2(sizeof,precomputed_s));
  81. if (ret || !pre) return 1;
  82. API_NS(precompute)(pre, real_point_base);
  83. struct niels_s *preWnaf;
  84. ret = posix_memalign((void**)&preWnaf, API_NS2(alignof,precomputed_s), API_NS2(sizeof,precomputed_wnafs));
  85. if (ret || !preWnaf) return 1;
  86. API_NS(precompute_wnafs)(preWnaf, real_point_base);
  87. const gf_s *output;
  88. unsigned i;
  89. printf("/** @warning: this file was automatically generated. */\n");
  90. printf("#include \"field.h\"\n\n");
  91. printf("#include <decaf.h>\n\n");
  92. printf("#define API_NS(_id) %s_##_id\n", API_NAME);
  93. printf("#define API_NS2(_pref,_id) _pref##_%s_##_id\n", API_NAME);
  94. output = (const gf_s *)real_point_base;
  95. printf("const API_NS(point_t) API_NS(point_base) = {{\n");
  96. for (i=0; i < sizeof(API_NS(point_t)); i+=sizeof(gf)) {
  97. if (i) printf(",\n ");
  98. field_print(output++);
  99. }
  100. printf("\n}};\n");
  101. output = (const gf_s *)pre;
  102. printf("const gf API_NS(precomputed_base_as_fe)[%d]\n",
  103. (int)(API_NS2(sizeof,precomputed_s) / sizeof(gf)));
  104. printf("__attribute__((aligned(%d),visibility(\"hidden\"))) = {\n ", (int)API_NS2(alignof,precomputed_s));
  105. for (i=0; i < API_NS2(sizeof,precomputed_s); i+=sizeof(gf)) {
  106. if (i) printf(",\n ");
  107. field_print(output++);
  108. }
  109. printf("\n};\n");
  110. output = (const gf_s *)preWnaf;
  111. printf("const gf API_NS(precomputed_wnaf_as_fe)[%d]\n",
  112. (int)(API_NS2(sizeof,precomputed_wnafs) / sizeof(gf)));
  113. printf("__attribute__((aligned(%d),visibility(\"hidden\"))) = {\n ", (int)API_NS2(alignof,precomputed_s));
  114. for (i=0; i < API_NS2(sizeof,precomputed_wnafs); i+=sizeof(gf)) {
  115. if (i) printf(",\n ");
  116. field_print(output++);
  117. }
  118. printf("\n};\n");
  119. API_NS(scalar_t) smadj;
  120. API_NS(scalar_copy)(smadj,API_NS(scalar_one));
  121. for (i=0; i<DECAF_COMBS_N*DECAF_COMBS_T*DECAF_COMBS_S; i++) {
  122. API_NS(scalar_add)(smadj,smadj,smadj);
  123. }
  124. API_NS(scalar_sub)(smadj, smadj, API_NS(scalar_one));
  125. scalar_print("API_NS(precomputed_scalarmul_adjustment)", smadj);
  126. API_NS(scalar_copy)(smadj,API_NS(scalar_one));
  127. for (i=0; i<SCALAR_BITS-1 + DECAF_WINDOW_BITS
  128. - ((SCALAR_BITS-1) % DECAF_WINDOW_BITS); i++) {
  129. API_NS(scalar_add)(smadj,smadj,smadj);
  130. }
  131. API_NS(scalar_sub)(smadj, smadj, API_NS(scalar_one));
  132. scalar_print("API_NS(point_scalarmul_adjustment)", smadj);
  133. API_NS(scalar_copy)(smadj,API_NS(scalar_one));
  134. for (i=0; i<sizeof(API_NS(scalar_t))*8*2; i++) {
  135. API_NS(scalar_add)(smadj,smadj,smadj);
  136. }
  137. scalar_print("API_NS(sc_r2)", smadj);
  138. API_NS(scalar_sub)(smadj,API_NS(scalar_zero),API_NS(scalar_one)); /* get p-1 */
  139. unsigned long long w = 1, plo = smadj->limb[0]+1;
  140. #if DECAF_WORD_BITS == 32
  141. plo |= ((unsigned long long)smadj->limb[1]) << 32;
  142. #endif
  143. for (i=0; i<6; i++) {
  144. w *= w*plo + 2;
  145. }
  146. printf("const decaf_word_t API_NS(MONTGOMERY_FACTOR) = (decaf_word_t)0x%016llxull;\n\n", w);
  147. /* Generate the Montgomery ladder version of the base point */
  148. gf base1,base2;
  149. ret = gf_deserialize(base1,base_point_ser_for_pregen);
  150. if (ret != DECAF_SUCCESS) return 1;
  151. gf_sqr(base2,base1);
  152. uint8_t x_ser[X_PUBLIC_BYTES] = {0};
  153. gf_serialize(x_ser, base2);
  154. printf("const uint8_t API_NS(x_base_point)[%d] = {", X_PUBLIC_BYTES);
  155. for (i=0; i<X_PUBLIC_BYTES; i++) {
  156. printf("%s%s%d",i?",":"",(i%32==0)?"\n ":"",x_ser[i]);
  157. }
  158. printf("\n};\n");
  159. return 0;
  160. }