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.
 
 
 
 
 

314 lines
11 KiB

  1. /**
  2. * @cond internal
  3. * @brief EdDSA routines.
  4. */
  5. #include "word.h"
  6. #include <decaf/ed$(gf_bits).h>
  7. #include <decaf/shake.h>
  8. #include <decaf/sha512.h>
  9. #include <string.h>
  10. #define API_NAME "$(c_ns)"
  11. #define API_NS(_id) $(c_ns)_##_id
  12. #define hash_ctx_t decaf_$(eddsa_hash)_ctx_t
  13. #define hash_init decaf_$(eddsa_hash)_init
  14. #define hash_update decaf_$(eddsa_hash)_update
  15. #define hash_final decaf_$(eddsa_hash)_final
  16. #define hash_destroy decaf_$(eddsa_hash)_destroy
  17. #define hash_hash decaf_$(eddsa_hash)_hash
  18. #define NO_CONTEXT DECAF_EDDSA_$(gf_shortname)_SUPPORTS_CONTEXTLESS_SIGS
  19. #define EDDSA_USE_SIGMA_ISOGENY $(eddsa_sigma_iso)
  20. #define COFACTOR $(cofactor)
  21. #define EDDSA_PREHASH_BYTES 64
  22. #if NO_CONTEXT
  23. const uint8_t NO_CONTEXT_POINTS_HERE = 0;
  24. const uint8_t * const DECAF_ED$(gf_shortname)_NO_CONTEXT = &NO_CONTEXT_POINTS_HERE;
  25. #endif
  26. static void clamp (
  27. uint8_t secret_scalar_ser[DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES]
  28. ) {
  29. /* Blarg */
  30. secret_scalar_ser[0] &= -COFACTOR;
  31. uint8_t hibit = (1<<$(gf_bits % 8))>>1;
  32. if (hibit == 0) {
  33. secret_scalar_ser[DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES - 1] = 0;
  34. secret_scalar_ser[DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES - 2] |= 0x80;
  35. } else {
  36. secret_scalar_ser[DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES - 1] &= hibit-1;
  37. secret_scalar_ser[DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES - 1] |= hibit;
  38. }
  39. }
  40. static void hash_init_with_dom(
  41. hash_ctx_t hash,
  42. uint8_t prehashed,
  43. uint8_t for_prehash,
  44. const uint8_t *context,
  45. uint8_t context_len
  46. ) {
  47. hash_init(hash);
  48. #if NO_CONTEXT
  49. if (context_len == 0 && context == DECAF_ED$(gf_shortname)_NO_CONTEXT) {
  50. (void)prehashed;
  51. (void)for_prehash;
  52. (void)context;
  53. (void)context_len;
  54. return;
  55. }
  56. #endif
  57. const char *dom_s = "$(eddsa_dom)";
  58. const uint8_t dom[2] = {2+word_is_zero(prehashed)+word_is_zero(for_prehash), context_len};
  59. hash_update(hash,(const unsigned char *)dom_s, strlen(dom_s));
  60. hash_update(hash,dom,2);
  61. hash_update(hash,context,context_len);
  62. }
  63. void decaf_ed$(gf_shortname)_prehash_init (
  64. hash_ctx_t hash
  65. ) {
  66. hash_init(hash);
  67. }
  68. /* In this file because it uses the hash */
  69. void decaf_ed$(gf_shortname)_convert_private_key_to_x$(gf_shortname) (
  70. uint8_t x[DECAF_X$(gf_shortname)_PRIVATE_BYTES],
  71. const uint8_t ed[DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES]
  72. ) {
  73. /* pass the private key through hash_hash function */
  74. /* and keep the first DECAF_X$(gf_shortname)_PRIVATE_BYTES bytes */
  75. hash_hash(
  76. x,
  77. DECAF_X$(gf_shortname)_PRIVATE_BYTES,
  78. ed,
  79. DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES
  80. );
  81. }
  82. void decaf_ed$(gf_shortname)_derive_public_key (
  83. uint8_t pubkey[DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES],
  84. const uint8_t privkey[DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES]
  85. ) {
  86. /* only this much used for keygen */
  87. uint8_t secret_scalar_ser[DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES];
  88. hash_hash(
  89. secret_scalar_ser,
  90. sizeof(secret_scalar_ser),
  91. privkey,
  92. DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES
  93. );
  94. clamp(secret_scalar_ser);
  95. API_NS(scalar_t) secret_scalar;
  96. API_NS(scalar_decode_long)(secret_scalar, secret_scalar_ser, sizeof(secret_scalar_ser));
  97. /* Since we are going to mul_by_cofactor during encoding, divide by it here.
  98. * However, the EdDSA base point is not the same as the decaf base point if
  99. * the sigma isogeny is in use: the EdDSA base point is on Etwist_d/(1-d) and
  100. * the decaf base point is on Etwist_d, and when converted it effectively
  101. * picks up a factor of 2 from the isogenies. So we might start at 2 instead of 1.
  102. */
  103. for (unsigned int c=1; c<$(C_NS)_EDDSA_ENCODE_RATIO; c <<= 1) {
  104. API_NS(scalar_halve)(secret_scalar,secret_scalar);
  105. }
  106. API_NS(point_t) p;
  107. API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),secret_scalar);
  108. API_NS(point_mul_by_ratio_and_encode_like_eddsa)(pubkey, p);
  109. /* Cleanup */
  110. API_NS(scalar_destroy)(secret_scalar);
  111. API_NS(point_destroy)(p);
  112. decaf_bzero(secret_scalar_ser, sizeof(secret_scalar_ser));
  113. }
  114. void decaf_ed$(gf_shortname)_sign (
  115. uint8_t signature[DECAF_EDDSA_$(gf_shortname)_SIGNATURE_BYTES],
  116. const uint8_t privkey[DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES],
  117. const uint8_t pubkey[DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES],
  118. const uint8_t *message,
  119. size_t message_len,
  120. uint8_t prehashed,
  121. const uint8_t *context,
  122. uint8_t context_len
  123. ) {
  124. API_NS(scalar_t) secret_scalar;
  125. hash_ctx_t hash;
  126. {
  127. /* Schedule the secret key */
  128. struct {
  129. uint8_t secret_scalar_ser[DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES];
  130. uint8_t seed[DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES];
  131. } __attribute__((packed)) expanded;
  132. hash_hash(
  133. (uint8_t *)&expanded,
  134. sizeof(expanded),
  135. privkey,
  136. DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES
  137. );
  138. clamp(expanded.secret_scalar_ser);
  139. API_NS(scalar_decode_long)(secret_scalar, expanded.secret_scalar_ser, sizeof(expanded.secret_scalar_ser));
  140. /* Hash to create the nonce */
  141. hash_init_with_dom(hash,prehashed,0,context,context_len);
  142. hash_update(hash,expanded.seed,sizeof(expanded.seed));
  143. hash_update(hash,message,message_len);
  144. decaf_bzero(&expanded, sizeof(expanded));
  145. }
  146. /* Decode the nonce */
  147. API_NS(scalar_t) nonce_scalar;
  148. {
  149. uint8_t nonce[2*DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES];
  150. hash_final(hash,nonce,sizeof(nonce));
  151. API_NS(scalar_decode_long)(nonce_scalar, nonce, sizeof(nonce));
  152. decaf_bzero(nonce, sizeof(nonce));
  153. }
  154. uint8_t nonce_point[DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES] = {0};
  155. {
  156. /* Scalarmul to create the nonce-point */
  157. API_NS(scalar_t) nonce_scalar_2;
  158. API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar);
  159. for (unsigned int c = 2; c < $(C_NS)_EDDSA_ENCODE_RATIO; c <<= 1) {
  160. API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar_2);
  161. }
  162. API_NS(point_t) p;
  163. API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),nonce_scalar_2);
  164. API_NS(point_mul_by_ratio_and_encode_like_eddsa)(nonce_point, p);
  165. API_NS(point_destroy)(p);
  166. API_NS(scalar_destroy)(nonce_scalar_2);
  167. }
  168. API_NS(scalar_t) challenge_scalar;
  169. {
  170. /* Compute the challenge */
  171. hash_init_with_dom(hash,prehashed,0,context,context_len);
  172. hash_update(hash,nonce_point,sizeof(nonce_point));
  173. hash_update(hash,pubkey,DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES);
  174. hash_update(hash,message,message_len);
  175. uint8_t challenge[2*DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES];
  176. hash_final(hash,challenge,sizeof(challenge));
  177. hash_destroy(hash);
  178. API_NS(scalar_decode_long)(challenge_scalar,challenge,sizeof(challenge));
  179. decaf_bzero(challenge,sizeof(challenge));
  180. }
  181. API_NS(scalar_mul)(challenge_scalar,challenge_scalar,secret_scalar);
  182. API_NS(scalar_add)(challenge_scalar,challenge_scalar,nonce_scalar);
  183. decaf_bzero(signature,DECAF_EDDSA_$(gf_shortname)_SIGNATURE_BYTES);
  184. memcpy(signature,nonce_point,sizeof(nonce_point));
  185. API_NS(scalar_encode)(&signature[DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES],challenge_scalar);
  186. API_NS(scalar_destroy)(secret_scalar);
  187. API_NS(scalar_destroy)(nonce_scalar);
  188. API_NS(scalar_destroy)(challenge_scalar);
  189. }
  190. void decaf_ed$(gf_shortname)_sign_prehash (
  191. uint8_t signature[DECAF_EDDSA_$(gf_shortname)_SIGNATURE_BYTES],
  192. const uint8_t privkey[DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES],
  193. const uint8_t pubkey[DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES],
  194. const decaf_ed$(gf_shortname)_prehash_ctx_t hash,
  195. const uint8_t *context,
  196. uint8_t context_len
  197. ) {
  198. uint8_t hash_output[EDDSA_PREHASH_BYTES];
  199. {
  200. decaf_ed$(gf_shortname)_prehash_ctx_t hash_too;
  201. memcpy(hash_too,hash,sizeof(hash_too));
  202. hash_final(hash_too,hash_output,sizeof(hash_output));
  203. hash_destroy(hash_too);
  204. }
  205. decaf_ed$(gf_shortname)_sign(signature,privkey,pubkey,hash_output,sizeof(hash_output),1,context,context_len);
  206. decaf_bzero(hash_output,sizeof(hash_output));
  207. }
  208. decaf_error_t decaf_ed$(gf_shortname)_verify (
  209. const uint8_t signature[DECAF_EDDSA_$(gf_shortname)_SIGNATURE_BYTES],
  210. const uint8_t pubkey[DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES],
  211. const uint8_t *message,
  212. size_t message_len,
  213. uint8_t prehashed,
  214. const uint8_t *context,
  215. uint8_t context_len
  216. ) {
  217. API_NS(point_t) pk_point, r_point;
  218. decaf_error_t error = API_NS(point_decode_like_eddsa_and_mul_by_ratio)(pk_point,pubkey);
  219. if (DECAF_SUCCESS != error) { return error; }
  220. error = API_NS(point_decode_like_eddsa_and_mul_by_ratio)(r_point,signature);
  221. if (DECAF_SUCCESS != error) { return error; }
  222. API_NS(scalar_t) challenge_scalar;
  223. {
  224. /* Compute the challenge */
  225. hash_ctx_t hash;
  226. hash_init_with_dom(hash,prehashed,0,context,context_len);
  227. hash_update(hash,signature,DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES);
  228. hash_update(hash,pubkey,DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES);
  229. hash_update(hash,message,message_len);
  230. uint8_t challenge[2*DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES];
  231. hash_final(hash,challenge,sizeof(challenge));
  232. hash_destroy(hash);
  233. API_NS(scalar_decode_long)(challenge_scalar,challenge,sizeof(challenge));
  234. decaf_bzero(challenge,sizeof(challenge));
  235. }
  236. API_NS(scalar_sub)(challenge_scalar, API_NS(scalar_zero), challenge_scalar);
  237. API_NS(scalar_t) response_scalar;
  238. API_NS(scalar_decode_long)(
  239. response_scalar,
  240. &signature[DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES],
  241. DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES
  242. );
  243. for (unsigned c=1; c<$(C_NS)_EDDSA_DECODE_RATIO; c<<=1) {
  244. API_NS(scalar_add)(response_scalar,response_scalar,response_scalar);
  245. }
  246. /* pk_point = -c(x(P)) + (cx + k)G = kG */
  247. API_NS(base_double_scalarmul_non_secret)(
  248. pk_point,
  249. response_scalar,
  250. pk_point,
  251. challenge_scalar
  252. );
  253. return decaf_succeed_if(API_NS(point_eq(pk_point,r_point)));
  254. }
  255. decaf_error_t decaf_ed$(gf_shortname)_verify_prehash (
  256. const uint8_t signature[DECAF_EDDSA_$(gf_shortname)_SIGNATURE_BYTES],
  257. const uint8_t pubkey[DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES],
  258. const decaf_ed$(gf_shortname)_prehash_ctx_t hash,
  259. const uint8_t *context,
  260. uint8_t context_len
  261. ) {
  262. decaf_error_t ret;
  263. uint8_t hash_output[EDDSA_PREHASH_BYTES];
  264. {
  265. decaf_ed$(gf_shortname)_prehash_ctx_t hash_too;
  266. memcpy(hash_too,hash,sizeof(hash_too));
  267. hash_final(hash_too,hash_output,sizeof(hash_output));
  268. hash_destroy(hash_too);
  269. }
  270. ret = decaf_ed$(gf_shortname)_verify(signature,pubkey,hash_output,sizeof(hash_output),1,context,context_len);
  271. return ret;
  272. }