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.
 
 
 
 
 

169 lines
4.1 KiB

  1. /* Copyright (c) 2014 Cryptography Research, Inc.
  2. * Released under the MIT License. See LICENSE.txt for license information.
  3. */
  4. #include "goldilocks.h"
  5. #include "ec_point.h"
  6. #include "scalarmul.h"
  7. #include "barrett_field.h"
  8. #include "crandom.h"
  9. #ifndef GOLDILOCKS_RANDOM_INIT_FILE
  10. #define GOLDILOCKS_RANDOM_INIT_FILE "/dev/urandom"
  11. #endif
  12. #ifndef GOLDILOCKS_RANDOM_RESEED_INTERVAL
  13. #define GOLDILOCKS_RANDOM_RESEED_INTERVAL 10000
  14. #endif
  15. /* We'll check it ourselves */
  16. #ifndef GOLDILOCKS_RANDOM_RESEEDS_MANDATORY
  17. #define GOLDILOCKS_RANDOM_RESEEDS_MANDATORY 0
  18. #endif
  19. /* TODO: word size; precompute */
  20. const struct affine_t goldilocks_base_point = {
  21. {{ 0xf0de840aed939full, 0xc170033f4ba0c7ull, 0xf3932d94c63d96ull, 0x9cecfa96147eaaull,
  22. 0x5f065c3c59d070ull, 0x3a6a26adf73324ull, 0x1b4faff4609845ull, 0x297ea0ea2692ffull
  23. }},
  24. {{ 19, 0, 0, 0, 0, 0, 0, 0 }}
  25. };
  26. // FIXME: threading
  27. // TODO: autogen instead of init
  28. struct {
  29. struct tw_niels_t combs[80];
  30. struct tw_niels_t wnafs[32];
  31. struct crandom_state_t rand;
  32. } goldilocks_global;
  33. int
  34. goldilocks_init() {
  35. struct extensible_t ext;
  36. struct tw_extensible_t text;
  37. /* Sanity check: the base point is on the curve. */
  38. assert(p448_affine_validate(&goldilocks_base_point));
  39. /* Convert it to twisted Edwards. */
  40. convert_affine_to_extensible(&ext, &goldilocks_base_point);
  41. p448_isogeny_un_to_tw(&text, &ext);
  42. /* Precompute the tables. */
  43. precompute_for_combs(goldilocks_global.combs, &text, 5, 5, 18);
  44. precompute_for_wnaf(goldilocks_global.wnafs, &text, 5);
  45. return crandom_init_from_file(&goldilocks_global.rand,
  46. GOLDILOCKS_RANDOM_INIT_FILE,
  47. GOLDILOCKS_RANDOM_RESEED_INTERVAL,
  48. GOLDILOCKS_RANDOM_RESEEDS_MANDATORY);
  49. }
  50. // TODO: move to a better place
  51. // TODO: word size
  52. void
  53. p448_serialize(uint8_t *serial, const struct p448_t *x) {
  54. int i,j;
  55. p448_t red;
  56. p448_copy(&red, x);
  57. p448_strong_reduce(&red);
  58. for (i=0; i<8; i++) {
  59. for (j=0; j<7; j++) {
  60. serial[7*i+j] = red.limb[i];
  61. red.limb[i] >>= 8;
  62. }
  63. assert(red.limb[i] == 0);
  64. }
  65. }
  66. void
  67. q448_serialize(uint8_t *serial, const word_t x[7]) {
  68. int i,j;
  69. for (i=0; i<7; i++) {
  70. for (j=0; j<8; j++) {
  71. serial[8*i+j] = x[i]>>(8*j);
  72. }
  73. }
  74. }
  75. mask_t
  76. q448_deserialize(word_t x[7], const uint8_t serial[56]) {
  77. int i,j;
  78. for (i=0; i<7; i++) {
  79. word_t out = 0;
  80. for (j=0; j<8; j++) {
  81. out |= ((word_t)serial[8*i+j])<<(8*j);
  82. }
  83. x[i] = out;
  84. }
  85. // TODO: check for reduction
  86. return MASK_SUCCESS;
  87. }
  88. mask_t
  89. p448_deserialize(p448_t *x, const uint8_t serial[56]) {
  90. int i,j;
  91. for (i=0; i<8; i++) {
  92. word_t out = 0;
  93. for (j=0; j<7; j++) {
  94. out |= ((word_t)serial[7*i+j])<<(8*j);
  95. }
  96. x->limb[i] = out;
  97. }
  98. // TODO: check for reduction
  99. return MASK_SUCCESS;
  100. }
  101. static word_t
  102. q448_lo[4] = {
  103. 0xdc873d6d54a7bb0dull,
  104. 0xde933d8d723a70aaull,
  105. 0x3bb124b65129c96full,
  106. 0x000000008335dc16ull
  107. };
  108. int
  109. goldilocks_keygen(
  110. uint8_t private[56],
  111. uint8_t public[56]
  112. ) {
  113. // TODO: check for init. Also maybe take CRANDOM object? API...
  114. word_t sk[448*2/WORD_BITS];
  115. struct tw_extensible_t exta;
  116. struct p448_t pk;
  117. int ret = crandom_generate(&goldilocks_global.rand, (unsigned char *)sk, sizeof(sk));
  118. barrett_reduce(sk,sizeof(sk)/sizeof(sk[0]),0,q448_lo,7,4,62); // TODO word size
  119. q448_serialize(private, sk);
  120. edwards_comb(&exta, sk, goldilocks_global.combs, 5, 5, 18);
  121. isogeny_and_serialize(&pk, &exta);
  122. p448_serialize(public, &pk);
  123. return ret;
  124. }
  125. int
  126. goldilocks_shared_secret(
  127. uint8_t shared[56],
  128. const uint8_t private[56],
  129. const uint8_t public[56]
  130. ) {
  131. // TODO: SHA
  132. word_t sk[448/WORD_BITS];
  133. struct p448_t pk;
  134. mask_t succ = p448_deserialize(&pk,public);
  135. succ &= q448_deserialize(sk,private);
  136. succ &= p448_montgomery_ladder(&pk,&pk,sk,446,2);
  137. p448_serialize(shared,&pk);
  138. // TODO: hash
  139. if (succ) {
  140. return 0;
  141. } else {
  142. return -1;
  143. }
  144. }