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.
 
 
 
 
 

577 lines
16 KiB

  1. /* Copyright (c) 2014 Cryptography Research, Inc.
  2. * Released under the MIT License. See LICENSE.txt for license information.
  3. */
  4. #include "config.h"
  5. #include "word.h"
  6. #include <errno.h>
  7. #if GOLDILOCKS_USE_PTHREAD
  8. #include <pthread.h>
  9. #endif
  10. #include "goldilocks.h"
  11. #include "ec_point.h"
  12. #include "scalarmul.h"
  13. #include "barrett_field.h"
  14. #include "crandom.h"
  15. #include "sha512.h"
  16. #include "intrinsics.h"
  17. #ifndef GOLDILOCKS_RANDOM_INIT_FILE
  18. #define GOLDILOCKS_RANDOM_INIT_FILE "/dev/urandom"
  19. #endif
  20. #ifndef GOLDILOCKS_RANDOM_RESEED_INTERVAL
  21. #define GOLDILOCKS_RANDOM_RESEED_INTERVAL 10000
  22. #endif
  23. /* We'll check it ourselves */
  24. #ifndef GOLDILOCKS_RANDOM_RESEEDS_MANDATORY
  25. #define GOLDILOCKS_RANDOM_RESEEDS_MANDATORY 0
  26. #endif
  27. #define GOLDI_DIVERSIFY_BYTES 8
  28. #if FIELD_BYTES <= SHA512_OUTPUT_BYTES
  29. #define FIELD_HASH_BYTES SHA512_OUTPUT_BYTES
  30. #define field_hash_final sha512_final
  31. #else
  32. #define FIELD_HASH_BYTES (SHA512_OUTPUT_BYTES * ((FIELD_BYTES-1)/SHA512_OUTPUT_BYTES + 1))
  33. static inline void field_hash_final (
  34. struct sha512_ctx_t *ctx,
  35. unsigned char out[FIELD_HASH_BYTES]
  36. ) {
  37. /* SHA PRNG I guess? I really should have used SHAKE */
  38. int i;
  39. for (i=0; i<= (FIELD_BYTES-1) / SHA512_OUTPUT_BYTES; i++) {
  40. if (i)
  41. sha512_update(ctx, &out[(i-1)*SHA512_OUTPUT_BYTES], SHA512_OUTPUT_BYTES);
  42. sha512_final(ctx, &out[i*SHA512_OUTPUT_BYTES]);
  43. }
  44. }
  45. #endif
  46. /* These are just unique identifiers */
  47. static const char *G_INITING = "initializing";
  48. static const char *G_INITED = "initialized";
  49. static const char *G_FAILED = "failed to initialize";
  50. struct goldilocks_precomputed_public_key_t {
  51. struct goldilocks_public_key_t pub;
  52. struct fixed_base_table_t table;
  53. };
  54. /* FUTURE: auto. */
  55. static struct {
  56. const char * volatile state;
  57. #if GOLDILOCKS_USE_PTHREAD
  58. pthread_mutex_t mutex;
  59. #endif
  60. struct tw_niels_t combs[COMB_N << (COMB_T-1)];
  61. struct fixed_base_table_t fixed_base;
  62. struct tw_niels_t wnafs[1<<WNAF_PRECMP_BITS];
  63. struct crandom_state_t rand;
  64. } goldilocks_global;
  65. static inline mask_t
  66. goldilocks_check_init(void) {
  67. if (likely(goldilocks_global.state == G_INITED)) {
  68. return MASK_SUCCESS;
  69. } else {
  70. return MASK_FAILURE;
  71. }
  72. }
  73. int
  74. goldilocks_init (void) {
  75. const char *res = compare_and_swap(&goldilocks_global.state, NULL, G_INITING);
  76. if (res == G_INITED) return GOLDI_EALREADYINIT;
  77. else if (res) {
  78. return GOLDI_ECORRUPT;
  79. }
  80. #if GOLDILOCKS_USE_PTHREAD
  81. int ret = pthread_mutex_init(&goldilocks_global.mutex, NULL);
  82. if (ret) goto fail;
  83. #endif
  84. struct extensible_t ext;
  85. struct tw_extensible_t text;
  86. /* Sanity check: the base point is on the curve. */
  87. assert(validate_affine(&goldilocks_base_point));
  88. /* Convert it to twisted Edwards. */
  89. convert_affine_to_extensible(&ext, &goldilocks_base_point);
  90. twist_even(&text, &ext);
  91. /* Precompute the tables. */
  92. mask_t succ;
  93. succ = precompute_fixed_base(&goldilocks_global.fixed_base, &text,
  94. COMB_N, COMB_T, COMB_S, goldilocks_global.combs);
  95. succ &= precompute_fixed_base_wnaf(goldilocks_global.wnafs, &text, WNAF_PRECMP_BITS);
  96. int criff_res = crandom_init_from_file(&goldilocks_global.rand,
  97. GOLDILOCKS_RANDOM_INIT_FILE,
  98. GOLDILOCKS_RANDOM_RESEED_INTERVAL,
  99. GOLDILOCKS_RANDOM_RESEEDS_MANDATORY);
  100. #ifdef SUPERCOP_WONT_LET_ME_OPEN_FILES
  101. if (criff_res == EMFILE) {
  102. crandom_init_from_buffer(&goldilocks_global.rand, "SUPERCOP won't let me open files");
  103. criff_res = 0;
  104. }
  105. #endif
  106. if (succ & !criff_res) {
  107. if (!bool_compare_and_swap(&goldilocks_global.state, G_INITING, G_INITED)) {
  108. abort();
  109. }
  110. return 0;
  111. }
  112. /* it failed! fall though... */
  113. fail:
  114. if (!bool_compare_and_swap(&goldilocks_global.state, G_INITING, G_FAILED)) {
  115. /* ok something is seriously wrong */
  116. abort();
  117. }
  118. return -1;
  119. }
  120. int
  121. goldilocks_derive_private_key (
  122. struct goldilocks_private_key_t *privkey,
  123. const unsigned char proto[GOLDI_SYMKEY_BYTES]
  124. ) {
  125. if (!goldilocks_check_init()) {
  126. return GOLDI_EUNINIT;
  127. }
  128. memcpy(&privkey->opaque[2*GOLDI_FIELD_BYTES], proto, GOLDI_SYMKEY_BYTES);
  129. unsigned char skb[FIELD_HASH_BYTES];
  130. word_t sk[GOLDI_FIELD_WORDS];
  131. assert(sizeof(skb) >= sizeof(sk));
  132. struct sha512_ctx_t ctx;
  133. struct tw_extensible_t exta;
  134. struct field_t pk;
  135. sha512_init(&ctx);
  136. sha512_update(&ctx, (const unsigned char *)"derivepk", GOLDI_DIVERSIFY_BYTES);
  137. sha512_update(&ctx, proto, GOLDI_SYMKEY_BYTES);
  138. field_hash_final(&ctx, (unsigned char *)skb);
  139. barrett_deserialize_and_reduce(sk, skb, sizeof(skb), &curve_prime_order);
  140. barrett_serialize(privkey->opaque, sk, GOLDI_FIELD_BYTES);
  141. scalarmul_fixed_base(&exta, sk, GOLDI_SCALAR_BITS, &goldilocks_global.fixed_base);
  142. untwist_and_double_and_serialize(&pk, &exta);
  143. field_serialize(&privkey->opaque[GOLDI_FIELD_BYTES], &pk);
  144. return GOLDI_EOK;
  145. }
  146. void
  147. goldilocks_underive_private_key (
  148. unsigned char proto[GOLDI_SYMKEY_BYTES],
  149. const struct goldilocks_private_key_t *privkey
  150. ) {
  151. memcpy(proto, &privkey->opaque[2*GOLDI_FIELD_BYTES], GOLDI_SYMKEY_BYTES);
  152. }
  153. int
  154. goldilocks_keygen (
  155. struct goldilocks_private_key_t *privkey,
  156. struct goldilocks_public_key_t *pubkey
  157. ) {
  158. if (!goldilocks_check_init()) {
  159. return GOLDI_EUNINIT;
  160. }
  161. unsigned char proto[GOLDI_SYMKEY_BYTES];
  162. #if GOLDILOCKS_USE_PTHREAD
  163. int ml_ret = pthread_mutex_lock(&goldilocks_global.mutex);
  164. if (ml_ret) return ml_ret;
  165. #endif
  166. int ret = crandom_generate(&goldilocks_global.rand, proto, sizeof(proto));
  167. #if GOLDILOCKS_USE_PTHREAD
  168. ml_ret = pthread_mutex_unlock(&goldilocks_global.mutex);
  169. if (ml_ret) abort();
  170. #endif
  171. int ret2 = goldilocks_derive_private_key(privkey, proto);
  172. if (!ret) ret = ret2;
  173. ret2 = goldilocks_private_to_public(pubkey, privkey);
  174. if (!ret) ret = ret2;
  175. return ret ? GOLDI_ENODICE : GOLDI_EOK;
  176. }
  177. int
  178. goldilocks_private_to_public (
  179. struct goldilocks_public_key_t *pubkey,
  180. const struct goldilocks_private_key_t *privkey
  181. ) {
  182. struct field_t pk;
  183. mask_t msucc = field_deserialize(&pk,&privkey->opaque[GOLDI_FIELD_BYTES]);
  184. if (msucc) {
  185. field_serialize(pubkey->opaque, &pk);
  186. return GOLDI_EOK;
  187. } else {
  188. return GOLDI_ECORRUPT;
  189. }
  190. }
  191. static int
  192. goldilocks_shared_secret_core (
  193. uint8_t shared[GOLDI_SHARED_SECRET_BYTES],
  194. const struct goldilocks_private_key_t *my_privkey,
  195. const struct goldilocks_public_key_t *your_pubkey,
  196. const struct goldilocks_precomputed_public_key_t *pre
  197. ) {
  198. uint8_t gxy[GOLDI_FIELD_BYTES];
  199. /* This function doesn't actually need anything in goldilocks_global,
  200. * so it doesn't check init.
  201. */
  202. assert(GOLDI_SHARED_SECRET_BYTES == SHA512_OUTPUT_BYTES);
  203. word_t sk[GOLDI_FIELD_WORDS];
  204. struct field_t pk;
  205. mask_t succ = field_deserialize(&pk,your_pubkey->opaque), msucc = -1;
  206. #ifdef EXPERIMENT_ECDH_STIR_IN_PUBKEYS
  207. struct field_t sum, prod;
  208. msucc &= field_deserialize(&sum,&my_privkey->opaque[GOLDI_FIELD_BYTES]);
  209. field_mul(&prod,&pk,&sum);
  210. field_add(&sum,&pk,&sum);
  211. #endif
  212. msucc &= barrett_deserialize(sk,my_privkey->opaque,&curve_prime_order);
  213. #if GOLDI_IMPLEMENT_PRECOMPUTED_KEYS
  214. if (pre) {
  215. struct tw_extensible_t tw;
  216. succ &= scalarmul_fixed_base(&tw, sk, GOLDI_SCALAR_BITS, &pre->table);
  217. untwist_and_double_and_serialize(&pk, &tw);
  218. } else {
  219. succ &= montgomery_ladder(&pk,&pk,sk,GOLDI_SCALAR_BITS,1);
  220. }
  221. #else
  222. (void)pre;
  223. succ &= montgomery_ladder(&pk,&pk,sk,GOLDI_SCALAR_BITS,1);
  224. #endif
  225. field_serialize(gxy,&pk);
  226. /* obliterate records of our failure by adjusting with obliteration key */
  227. struct sha512_ctx_t ctx;
  228. sha512_init(&ctx);
  229. #ifdef EXPERIMENT_ECDH_OBLITERATE_CT
  230. uint8_t oblit[GOLDI_DIVERSIFY_BYTES + GOLDI_SYMKEY_BYTES];
  231. unsigned i;
  232. for (i=0; i<GOLDI_DIVERSIFY_BYTES; i++) {
  233. oblit[i] = "noshared"[i] & ~(succ&msucc);
  234. }
  235. for (i=0; i<GOLDI_SYMKEY_BYTES; i++) {
  236. oblit[GOLDI_DIVERSIFY_BYTES+i] = my_privkey->opaque[2*GOLDI_FIELD_BYTES+i] & ~(succ&msucc);
  237. }
  238. sha512_update(&ctx, oblit, sizeof(oblit));
  239. #endif
  240. #ifdef EXPERIMENT_ECDH_STIR_IN_PUBKEYS
  241. /* stir in the sum and product of the pubkeys. */
  242. uint8_t a_pk[GOLDI_FIELD_BYTES];
  243. field_serialize(a_pk, &sum);
  244. sha512_update(&ctx, a_pk, GOLDI_FIELD_BYTES);
  245. field_serialize(a_pk, &prod);
  246. sha512_update(&ctx, a_pk, GOLDI_FIELD_BYTES);
  247. #endif
  248. /* stir in the shared key and finish */
  249. sha512_update(&ctx, gxy, GOLDI_FIELD_BYTES);
  250. sha512_final(&ctx, shared);
  251. return (GOLDI_ECORRUPT & ~msucc)
  252. | (GOLDI_EINVAL & msucc &~ succ)
  253. | (GOLDI_EOK & msucc & succ);
  254. }
  255. int
  256. goldilocks_shared_secret (
  257. uint8_t shared[GOLDI_SHARED_SECRET_BYTES],
  258. const struct goldilocks_private_key_t *my_privkey,
  259. const struct goldilocks_public_key_t *your_pubkey
  260. ) {
  261. return goldilocks_shared_secret_core(
  262. shared,
  263. my_privkey,
  264. your_pubkey,
  265. NULL
  266. );
  267. }
  268. #if GOLDI_IMPLEMENT_SIGNATURES
  269. static void
  270. goldilocks_derive_challenge(
  271. word_t challenge[GOLDI_FIELD_WORDS],
  272. const unsigned char pubkey[GOLDI_FIELD_BYTES],
  273. const unsigned char gnonce[GOLDI_FIELD_BYTES],
  274. const unsigned char *message,
  275. uint64_t message_len
  276. ) {
  277. /* challenge = H(pk, [nonceG], message). */
  278. unsigned char sha_out[FIELD_HASH_BYTES];
  279. struct sha512_ctx_t ctx;
  280. sha512_init(&ctx);
  281. sha512_update(&ctx, pubkey, GOLDI_FIELD_BYTES);
  282. sha512_update(&ctx, gnonce, GOLDI_FIELD_BYTES);
  283. sha512_update(&ctx, message, message_len);
  284. field_hash_final(&ctx, sha_out);
  285. barrett_deserialize_and_reduce(challenge, sha_out, sizeof(sha_out), &curve_prime_order);
  286. }
  287. int
  288. goldilocks_sign (
  289. uint8_t signature_out[GOLDI_SIGNATURE_BYTES],
  290. const uint8_t *message,
  291. uint64_t message_len,
  292. const struct goldilocks_private_key_t *privkey
  293. ) {
  294. if (!goldilocks_check_init()) {
  295. return GOLDI_EUNINIT;
  296. }
  297. /* challenge = H(pk, [nonceG], message). */
  298. word_t skw[GOLDI_FIELD_WORDS];
  299. mask_t succ = barrett_deserialize(skw,privkey->opaque,&curve_prime_order);
  300. if (!succ) {
  301. really_memset(skw,0,sizeof(skw));
  302. return GOLDI_ECORRUPT;
  303. }
  304. /* Derive a nonce. TODO: use HMAC. FUTURE: factor. */
  305. unsigned char sha_out[FIELD_HASH_BYTES];
  306. word_t tk[GOLDI_FIELD_WORDS];
  307. struct sha512_ctx_t ctx;
  308. sha512_init(&ctx);
  309. sha512_update(&ctx, (const unsigned char *)"signonce", 8);
  310. sha512_update(&ctx, &privkey->opaque[2*GOLDI_FIELD_BYTES], GOLDI_SYMKEY_BYTES);
  311. sha512_update(&ctx, message, message_len);
  312. sha512_update(&ctx, &privkey->opaque[2*GOLDI_FIELD_BYTES], GOLDI_SYMKEY_BYTES);
  313. field_hash_final(&ctx, sha_out);
  314. barrett_deserialize_and_reduce(tk, sha_out, sizeof(sha_out), &curve_prime_order);
  315. /* 4[nonce]G */
  316. uint8_t signature_tmp[GOLDI_FIELD_BYTES];
  317. struct tw_extensible_t exta;
  318. struct field_t gsk;
  319. scalarmul_fixed_base(&exta, tk, GOLDI_SCALAR_BITS, &goldilocks_global.fixed_base);
  320. double_tw_extensible(&exta);
  321. untwist_and_double_and_serialize(&gsk, &exta);
  322. field_serialize(signature_tmp, &gsk);
  323. word_t challenge[GOLDI_FIELD_WORDS];
  324. goldilocks_derive_challenge (
  325. challenge,
  326. &privkey->opaque[GOLDI_FIELD_BYTES],
  327. signature_tmp,
  328. message,
  329. message_len
  330. );
  331. /* reduce challenge and sub. */
  332. barrett_negate(challenge,GOLDI_FIELD_WORDS,&curve_prime_order);
  333. barrett_mac(
  334. tk,GOLDI_FIELD_WORDS,
  335. challenge,GOLDI_FIELD_WORDS,
  336. skw,GOLDI_FIELD_WORDS,
  337. &curve_prime_order
  338. );
  339. word_t carry = add_nr_ext_packed(tk,tk,GOLDI_FIELD_WORDS,tk,GOLDI_FIELD_WORDS,-1);
  340. barrett_reduce(tk,GOLDI_FIELD_WORDS,carry,&curve_prime_order);
  341. memcpy(signature_out, signature_tmp, GOLDI_FIELD_BYTES);
  342. barrett_serialize(signature_out+GOLDI_FIELD_BYTES, tk, GOLDI_FIELD_BYTES);
  343. really_memset((unsigned char *)tk,0,sizeof(tk));
  344. really_memset((unsigned char *)skw,0,sizeof(skw));
  345. really_memset((unsigned char *)challenge,0,sizeof(challenge));
  346. /* response = 2(nonce_secret - sk*challenge)
  347. * Nonce = 8[nonce_secret]*G
  348. * PK = 2[sk]*G, except doubled (TODO)
  349. * so [2] ( [response]G + 2[challenge]PK ) = Nonce
  350. */
  351. return 0;
  352. }
  353. int
  354. goldilocks_verify (
  355. const uint8_t signature[GOLDI_SIGNATURE_BYTES],
  356. const uint8_t *message,
  357. uint64_t message_len,
  358. const struct goldilocks_public_key_t *pubkey
  359. ) {
  360. if (!goldilocks_check_init()) {
  361. return GOLDI_EUNINIT;
  362. }
  363. struct field_t pk;
  364. word_t s[GOLDI_FIELD_WORDS];
  365. mask_t succ = field_deserialize(&pk,pubkey->opaque);
  366. if (!succ) return GOLDI_EINVAL;
  367. succ = barrett_deserialize(s, &signature[GOLDI_FIELD_BYTES], &curve_prime_order);
  368. if (!succ) return GOLDI_EINVAL;
  369. word_t challenge[GOLDI_FIELD_WORDS];
  370. goldilocks_derive_challenge(challenge, pubkey->opaque, signature, message, message_len);
  371. struct field_t eph;
  372. struct tw_extensible_t pk_text;
  373. /* deserialize [nonce]G */
  374. succ = field_deserialize(&eph, signature);
  375. if (!succ) return GOLDI_EINVAL;
  376. succ = deserialize_and_twist_approx(&pk_text, &sqrt_d_minus_1, &pk);
  377. if (!succ) return GOLDI_EINVAL;
  378. linear_combo_var_fixed_vt( &pk_text,
  379. challenge, GOLDI_SCALAR_BITS,
  380. s, GOLDI_SCALAR_BITS,
  381. goldilocks_global.wnafs, WNAF_PRECMP_BITS );
  382. untwist_and_double_and_serialize( &pk, &pk_text );
  383. succ = field_eq(&eph, &pk);
  384. return succ ? 0 : GOLDI_EINVAL;
  385. }
  386. #endif
  387. #if GOLDI_IMPLEMENT_PRECOMPUTED_KEYS
  388. struct goldilocks_precomputed_public_key_t *
  389. goldilocks_precompute_public_key (
  390. const struct goldilocks_public_key_t *pub
  391. ) {
  392. struct goldilocks_precomputed_public_key_t *precom;
  393. precom = (struct goldilocks_precomputed_public_key_t *)
  394. malloc(sizeof(*precom));
  395. if (!precom) return NULL;
  396. struct tw_extensible_t pk_text;
  397. struct field_t pk;
  398. mask_t succ = field_deserialize(&pk, pub->opaque);
  399. if (!succ) {
  400. free(precom);
  401. return NULL;
  402. }
  403. succ = deserialize_and_twist_approx(&pk_text, &sqrt_d_minus_1, &pk);
  404. if (!succ) {
  405. free(precom);
  406. return NULL;
  407. }
  408. succ = precompute_fixed_base(&precom->table, &pk_text,
  409. COMB_N, COMB_T, COMB_S, NULL);
  410. if (!succ) {
  411. free(precom);
  412. return NULL;
  413. }
  414. memcpy(&precom->pub,pub,sizeof(*pub));
  415. return precom;
  416. }
  417. void
  418. goldilocks_destroy_precomputed_public_key (
  419. struct goldilocks_precomputed_public_key_t *precom
  420. ) {
  421. if (!precom) return;
  422. destroy_fixed_base(&precom->table);
  423. really_memset(&precom->pub.opaque, 0, sizeof(precom->pub));
  424. free(precom);
  425. }
  426. int
  427. goldilocks_verify_precomputed (
  428. const uint8_t signature[GOLDI_SIGNATURE_BYTES],
  429. const uint8_t *message,
  430. uint64_t message_len,
  431. const struct goldilocks_precomputed_public_key_t *pubkey
  432. ) {
  433. if (!goldilocks_check_init()) {
  434. return GOLDI_EUNINIT;
  435. }
  436. word_t s[GOLDI_FIELD_WORDS];
  437. mask_t succ = barrett_deserialize(s, &signature[GOLDI_FIELD_BYTES], &curve_prime_order);
  438. if (!succ) return GOLDI_EINVAL;
  439. word_t challenge[GOLDI_FIELD_WORDS];
  440. goldilocks_derive_challenge(challenge, pubkey->pub.opaque, signature, message, message_len);
  441. struct field_t eph, pk;
  442. struct tw_extensible_t pk_text;
  443. /* deserialize [nonce]G */
  444. succ = field_deserialize(&eph, signature);
  445. if (!succ) return GOLDI_EINVAL;
  446. succ = linear_combo_combs_vt (
  447. &pk_text,
  448. challenge, GOLDI_SCALAR_BITS, &pubkey->table,
  449. s, GOLDI_SCALAR_BITS, &goldilocks_global.fixed_base
  450. );
  451. if (!succ) return GOLDI_EINVAL;
  452. untwist_and_double_and_serialize( &pk, &pk_text );
  453. succ = field_eq(&eph, &pk);
  454. return succ ? 0 : GOLDI_EINVAL;
  455. }
  456. int
  457. goldilocks_shared_secret_precomputed (
  458. uint8_t shared[GOLDI_SHARED_SECRET_BYTES],
  459. const struct goldilocks_private_key_t *my_privkey,
  460. const struct goldilocks_precomputed_public_key_t *your_pubkey
  461. ) {
  462. return goldilocks_shared_secret_core(
  463. shared,
  464. my_privkey,
  465. &your_pubkey->pub,
  466. your_pubkey
  467. );
  468. }
  469. #endif /* GOLDI_IMPLEMENT_PRECOMPUTED_KEYS */