sign.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #define hydro_sign_CHALLENGEBYTES 32
  2. #define hydro_sign_NONCEBYTES 32
  3. #define hydro_sign_PREHASHBYTES 64
  4. static void
  5. hydro_sign_p2(uint8_t sig[hydro_x25519_BYTES], const uint8_t challenge[hydro_sign_CHALLENGEBYTES],
  6. const uint8_t eph_sk[hydro_x25519_BYTES], const uint8_t sk[hydro_x25519_BYTES])
  7. {
  8. hydro_x25519_scalar_t scalar1, scalar2, scalar3;
  9. COMPILER_ASSERT(hydro_sign_CHALLENGEBYTES == hydro_x25519_BYTES);
  10. hydro_x25519_swapin(scalar1, eph_sk);
  11. hydro_x25519_swapin(scalar2, sk);
  12. hydro_x25519_swapin(scalar3, challenge);
  13. hydro_x25519_sc_montmul(scalar1, scalar2, scalar3);
  14. mem_zero(scalar2, sizeof scalar2);
  15. hydro_x25519_sc_montmul(scalar2, scalar1, hydro_x25519_sc_r2);
  16. hydro_x25519_swapout(sig, scalar2);
  17. }
  18. static void
  19. hydro_sign_challenge(uint8_t challenge[hydro_sign_CHALLENGEBYTES],
  20. const uint8_t nonce[hydro_sign_NONCEBYTES],
  21. const uint8_t pk[hydro_sign_PUBLICKEYBYTES],
  22. const uint8_t prehash[hydro_sign_PREHASHBYTES])
  23. {
  24. hydro_hash_state st;
  25. hydro_hash_init(&st, (const char *) zero, NULL);
  26. hydro_hash_update(&st, nonce, hydro_sign_NONCEBYTES);
  27. hydro_hash_update(&st, pk, hydro_sign_PUBLICKEYBYTES);
  28. hydro_hash_update(&st, prehash, hydro_sign_PREHASHBYTES);
  29. hydro_hash_final(&st, challenge, hydro_sign_CHALLENGEBYTES);
  30. }
  31. static int
  32. hydro_sign_prehash(uint8_t csig[hydro_sign_BYTES], const uint8_t prehash[hydro_sign_PREHASHBYTES],
  33. const uint8_t sk[hydro_sign_SECRETKEYBYTES])
  34. {
  35. hydro_hash_state st;
  36. uint8_t challenge[hydro_sign_CHALLENGEBYTES];
  37. const uint8_t * pk = &sk[hydro_x25519_SECRETKEYBYTES];
  38. uint8_t * nonce = &csig[0];
  39. uint8_t * sig = &csig[hydro_sign_NONCEBYTES];
  40. uint8_t * eph_sk = sig;
  41. hydro_random_buf(eph_sk, hydro_x25519_SECRETKEYBYTES);
  42. COMPILER_ASSERT(hydro_x25519_SECRETKEYBYTES == hydro_hash_KEYBYTES);
  43. hydro_hash_init(&st, (const char *) zero, sk);
  44. hydro_hash_update(&st, eph_sk, hydro_x25519_SECRETKEYBYTES);
  45. hydro_hash_update(&st, prehash, hydro_sign_CHALLENGEBYTES);
  46. hydro_hash_final(&st, eph_sk, hydro_x25519_SECRETKEYBYTES);
  47. hydro_x25519_scalarmult_base_uniform(nonce, eph_sk);
  48. hydro_sign_challenge(challenge, nonce, pk, prehash);
  49. COMPILER_ASSERT(hydro_sign_BYTES == hydro_sign_NONCEBYTES + hydro_x25519_SECRETKEYBYTES);
  50. COMPILER_ASSERT(hydro_x25519_SECRETKEYBYTES <= hydro_sign_CHALLENGEBYTES);
  51. hydro_sign_p2(sig, challenge, eph_sk, sk);
  52. return 0;
  53. }
  54. static int
  55. hydro_sign_verify_core(hydro_x25519_fe xs[5], const hydro_x25519_limb_t *other1,
  56. const uint8_t other2[hydro_x25519_BYTES])
  57. {
  58. hydro_x25519_limb_t * z2 = xs[1], *x3 = xs[2], *z3 = xs[3];
  59. hydro_x25519_fe xo2;
  60. const hydro_x25519_limb_t sixteen = 16;
  61. hydro_x25519_swapin(xo2, other2);
  62. memcpy(x3, other1, 2 * sizeof(hydro_x25519_fe));
  63. hydro_x25519_ladder_part1(xs);
  64. /* Here z2 = t2^2 */
  65. hydro_x25519_mul1(z2, other1);
  66. hydro_x25519_mul1(z2, other1 + hydro_x25519_NLIMBS);
  67. hydro_x25519_mul1(z2, xo2);
  68. hydro_x25519_mul(z2, z2, &sixteen, 1);
  69. hydro_x25519_mul1(z3, xo2);
  70. hydro_x25519_sub(z3, z3, x3);
  71. hydro_x25519_sqr1(z3);
  72. /* check equality */
  73. hydro_x25519_sub(z3, z3, z2);
  74. /* canon(z2): both sides are zero. canon(z3): the two sides are equal. */
  75. /* Reject sigs where both sides are zero. */
  76. return hydro_x25519_canon(z2) | ~hydro_x25519_canon(z3);
  77. }
  78. static int
  79. hydro_sign_verify_p2(const uint8_t sig[hydro_x25519_BYTES],
  80. const uint8_t challenge[hydro_sign_CHALLENGEBYTES],
  81. const uint8_t nonce[hydro_sign_NONCEBYTES],
  82. const uint8_t pk[hydro_x25519_BYTES])
  83. {
  84. hydro_x25519_fe xs[7];
  85. hydro_x25519_core(&xs[0], challenge, pk, 0);
  86. hydro_x25519_core(&xs[2], sig, hydro_x25519_BASE_POINT, 0);
  87. return hydro_sign_verify_core(&xs[2], xs[0], nonce);
  88. }
  89. static int
  90. hydro_sign_verify_challenge(const uint8_t csig[hydro_sign_BYTES],
  91. const uint8_t challenge[hydro_sign_CHALLENGEBYTES],
  92. const uint8_t pk[hydro_sign_PUBLICKEYBYTES])
  93. {
  94. const uint8_t *nonce = &csig[0];
  95. const uint8_t *sig = &csig[hydro_sign_NONCEBYTES];
  96. return hydro_sign_verify_p2(sig, challenge, nonce, pk);
  97. }
  98. void
  99. hydro_sign_keygen(hydro_sign_keypair *kp)
  100. {
  101. uint8_t *pk_copy = &kp->sk[hydro_x25519_SECRETKEYBYTES];
  102. COMPILER_ASSERT(hydro_sign_SECRETKEYBYTES ==
  103. hydro_x25519_SECRETKEYBYTES + hydro_x25519_PUBLICKEYBYTES);
  104. COMPILER_ASSERT(hydro_sign_PUBLICKEYBYTES == hydro_x25519_PUBLICKEYBYTES);
  105. hydro_random_buf(kp->sk, hydro_x25519_SECRETKEYBYTES);
  106. hydro_x25519_scalarmult_base_uniform(kp->pk, kp->sk);
  107. memcpy(pk_copy, kp->pk, hydro_x25519_PUBLICKEYBYTES);
  108. }
  109. void
  110. hydro_sign_keygen_deterministic(hydro_sign_keypair *kp, const uint8_t seed[hydro_sign_SEEDBYTES])
  111. {
  112. uint8_t *pk_copy = &kp->sk[hydro_x25519_SECRETKEYBYTES];
  113. COMPILER_ASSERT(hydro_sign_SEEDBYTES >= hydro_random_SEEDBYTES);
  114. hydro_random_buf_deterministic(kp->sk, hydro_x25519_SECRETKEYBYTES, seed);
  115. hydro_x25519_scalarmult_base_uniform(kp->pk, kp->sk);
  116. memcpy(pk_copy, kp->pk, hydro_x25519_PUBLICKEYBYTES);
  117. }
  118. int
  119. hydro_sign_init(hydro_sign_state *state, const char ctx[hydro_sign_CONTEXTBYTES])
  120. {
  121. return hydro_hash_init(&state->hash_st, ctx, NULL);
  122. }
  123. int
  124. hydro_sign_update(hydro_sign_state *state, const void *m_, size_t mlen)
  125. {
  126. return hydro_hash_update(&state->hash_st, m_, mlen);
  127. }
  128. int
  129. hydro_sign_final_create(hydro_sign_state *state, uint8_t csig[hydro_sign_BYTES],
  130. const uint8_t sk[hydro_sign_SECRETKEYBYTES])
  131. {
  132. uint8_t prehash[hydro_sign_PREHASHBYTES];
  133. hydro_hash_final(&state->hash_st, prehash, sizeof prehash);
  134. return hydro_sign_prehash(csig, prehash, sk);
  135. }
  136. int
  137. hydro_sign_final_verify(hydro_sign_state *state, const uint8_t csig[hydro_sign_BYTES],
  138. const uint8_t pk[hydro_sign_PUBLICKEYBYTES])
  139. {
  140. uint8_t challenge[hydro_sign_CHALLENGEBYTES];
  141. uint8_t prehash[hydro_sign_PREHASHBYTES];
  142. const uint8_t *nonce = &csig[0];
  143. hydro_hash_final(&state->hash_st, prehash, sizeof prehash);
  144. hydro_sign_challenge(challenge, nonce, pk, prehash);
  145. return hydro_sign_verify_challenge(csig, challenge, pk);
  146. }
  147. int
  148. hydro_sign_create(uint8_t csig[hydro_sign_BYTES], const void *m_, size_t mlen,
  149. const char ctx[hydro_sign_CONTEXTBYTES],
  150. const uint8_t sk[hydro_sign_SECRETKEYBYTES])
  151. {
  152. hydro_sign_state st;
  153. if (hydro_sign_init(&st, ctx) != 0 || hydro_sign_update(&st, m_, mlen) != 0 ||
  154. hydro_sign_final_create(&st, csig, sk) != 0) {
  155. return -1;
  156. }
  157. return 0;
  158. }
  159. int
  160. hydro_sign_verify(const uint8_t csig[hydro_sign_BYTES], const void *m_, size_t mlen,
  161. const char ctx[hydro_sign_CONTEXTBYTES],
  162. const uint8_t pk[hydro_sign_PUBLICKEYBYTES])
  163. {
  164. hydro_sign_state st;
  165. if (hydro_sign_init(&st, ctx) != 0 || hydro_sign_update(&st, m_, mlen) != 0 ||
  166. hydro_sign_final_verify(&st, csig, pk) != 0) {
  167. return -1;
  168. }
  169. return 0;
  170. }