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.
 
 
 
 
 

226 lines
6.8 KiB

  1. /**
  2. * @cond internal
  3. * @file decaf_crypto.c
  4. * @copyright
  5. * Copyright (c) 2015 Cryptography Research, Inc. \n
  6. * Released under the MIT License. See LICENSE.txt for license information.
  7. * @author Mike Hamburg
  8. * @brief Decaf cyrpto routines.
  9. */
  10. #include "decaf_crypto.h"
  11. #include <string.h>
  12. #include "sha512.h"
  13. static const unsigned int DECAF_448_SCALAR_OVERKILL_BYTES = DECAF_448_SCALAR_BYTES + 8;
  14. void decaf_448_derive_private_key (
  15. decaf_448_private_key_t priv,
  16. const decaf_448_symmetric_key_t proto
  17. ) {
  18. const char *magic = "decaf_448_derive_private_key";
  19. uint8_t encoded_scalar[DECAF_448_SCALAR_OVERKILL_BYTES];
  20. decaf_448_point_t pub;
  21. keccak_sponge_t sponge;
  22. shake256_init(sponge);
  23. shake256_update(sponge, proto, sizeof(decaf_448_symmetric_key_t));
  24. shake256_update(sponge, (const unsigned char *)magic, strlen(magic));
  25. shake256_final(sponge, encoded_scalar, sizeof(encoded_scalar));
  26. shake256_destroy(sponge);
  27. memcpy(priv->sym, proto, sizeof(decaf_448_symmetric_key_t));
  28. decaf_448_scalar_decode_long(priv->secret_scalar, encoded_scalar, sizeof(encoded_scalar));
  29. decaf_448_precomputed_scalarmul(pub, decaf_448_precomputed_base, priv->secret_scalar);
  30. decaf_448_point_encode(priv->pub, pub);
  31. decaf_bzero(encoded_scalar, sizeof(encoded_scalar));
  32. }
  33. void
  34. decaf_448_destroy_private_key (
  35. decaf_448_private_key_t priv
  36. ) {
  37. decaf_bzero((void*)priv, sizeof(decaf_448_private_key_t));
  38. }
  39. void decaf_448_private_to_public (
  40. decaf_448_public_key_t pub,
  41. const decaf_448_private_key_t priv
  42. ) {
  43. memcpy(pub, priv->pub, sizeof(decaf_448_public_key_t));
  44. }
  45. decaf_bool_t
  46. decaf_448_shared_secret (
  47. uint8_t *shared,
  48. size_t shared_bytes,
  49. const decaf_448_private_key_t my_privkey,
  50. const decaf_448_public_key_t your_pubkey
  51. ) {
  52. uint8_t ss_ser[DECAF_448_SER_BYTES];
  53. const char *nope = "decaf_448_ss_invalid";
  54. unsigned i;
  55. /* Lexsort keys. Less will be -1 if mine is less, and 0 otherwise. */
  56. uint16_t less = 0;
  57. for (i=0; i<DECAF_448_SER_BYTES; i++) {
  58. uint16_t delta = my_privkey->pub[i];
  59. delta -= your_pubkey[i];
  60. /* Case:
  61. * = -> delta = 0 -> hi delta-1 = -1, hi delta = 0
  62. * > -> delta > 0 -> hi delta-1 = 0, hi delta = 0
  63. * < -> delta < 0 -> hi delta-1 = (doesnt matter), hi delta = -1
  64. */
  65. less &= delta-1;
  66. less |= delta;
  67. }
  68. less >>= 8;
  69. keccak_sponge_t sponge;
  70. shake256_init(sponge);
  71. /* update the lesser */
  72. for (i=0; i<sizeof(ss_ser); i++) {
  73. ss_ser[i] = (my_privkey->pub[i] & less) | (your_pubkey[i] & ~less);
  74. }
  75. shake256_update(sponge, ss_ser, sizeof(ss_ser));
  76. /* update the greater */
  77. for (i=0; i<sizeof(ss_ser); i++) {
  78. ss_ser[i] = (my_privkey->pub[i] & ~less) | (your_pubkey[i] & less);
  79. }
  80. shake256_update(sponge, ss_ser, sizeof(ss_ser));
  81. decaf_bool_t ret = decaf_448_direct_scalarmul(ss_ser, your_pubkey, my_privkey->secret_scalar, DECAF_FALSE, DECAF_TRUE);
  82. /* If invalid, then replace ... */
  83. for (i=0; i<sizeof(ss_ser); i++) {
  84. ss_ser[i] &= ret;
  85. if (i < sizeof(my_privkey->sym)) {
  86. ss_ser[i] |= my_privkey->sym[i] & ~ret;
  87. } else if (i - sizeof(my_privkey->sym) < strlen(nope)) {
  88. ss_ser[i] |= nope[i-sizeof(my_privkey->sym)] & ~ret;
  89. }
  90. }
  91. shake256_update(sponge, ss_ser, sizeof(ss_ser));
  92. shake256_final(sponge, shared, shared_bytes);
  93. shake256_destroy(sponge);
  94. decaf_bzero(ss_ser, sizeof(ss_ser));
  95. return ret;
  96. }
  97. void
  98. decaf_448_sign_shake (
  99. decaf_448_signature_t sig,
  100. const decaf_448_private_key_t priv,
  101. const keccak_sponge_t shake
  102. ) {
  103. const char *magic = "decaf_448_sign_shake";
  104. uint8_t overkill[DECAF_448_SCALAR_OVERKILL_BYTES], encoded[DECAF_448_SER_BYTES];
  105. decaf_448_point_t point;
  106. decaf_448_scalar_t nonce, challenge;
  107. /* Derive nonce */
  108. keccak_sponge_t ctx;
  109. memcpy(ctx, shake, sizeof(ctx));
  110. shake256_update(ctx, priv->sym, sizeof(priv->sym));
  111. shake256_update(ctx, (const unsigned char *)magic, strlen(magic));
  112. shake256_final(ctx, overkill, sizeof(overkill));
  113. decaf_448_scalar_decode_long(nonce, overkill, sizeof(overkill));
  114. decaf_448_precomputed_scalarmul(point, decaf_448_precomputed_base, nonce);
  115. decaf_448_point_encode(encoded, point);
  116. /* Derive challenge */
  117. memcpy(ctx, shake, sizeof(ctx));
  118. shake256_update(ctx, priv->pub, sizeof(priv->pub));
  119. shake256_update(ctx, encoded, sizeof(encoded));
  120. shake256_final(ctx, overkill, sizeof(overkill));
  121. shake256_destroy(ctx);
  122. decaf_448_scalar_decode_long(challenge, overkill, sizeof(overkill));
  123. /* Respond */
  124. decaf_448_scalar_mul(challenge, challenge, priv->secret_scalar);
  125. decaf_448_scalar_sub(nonce, nonce, challenge);
  126. /* Save results */
  127. memcpy(sig, encoded, sizeof(encoded));
  128. decaf_448_scalar_encode(&sig[sizeof(encoded)], nonce);
  129. /* Clean up */
  130. decaf_448_scalar_destroy(nonce);
  131. decaf_448_scalar_destroy(challenge);
  132. decaf_bzero(overkill,sizeof(overkill));
  133. decaf_bzero(encoded,sizeof(encoded));
  134. }
  135. decaf_bool_t
  136. decaf_448_verify_shake (
  137. const decaf_448_signature_t sig,
  138. const decaf_448_public_key_t pub,
  139. const keccak_sponge_t shake
  140. ) {
  141. decaf_bool_t ret;
  142. uint8_t overkill[DECAF_448_SCALAR_OVERKILL_BYTES];
  143. decaf_448_point_t point, pubpoint;
  144. decaf_448_scalar_t challenge, response;
  145. /* Derive challenge */
  146. keccak_sponge_t ctx;
  147. memcpy(ctx, shake, sizeof(ctx));
  148. shake256_update(ctx, pub, sizeof(decaf_448_public_key_t));
  149. shake256_update(ctx, sig, DECAF_448_SER_BYTES);
  150. shake256_final(ctx, overkill, sizeof(overkill));
  151. shake256_destroy(ctx);
  152. decaf_448_scalar_decode_long(challenge, overkill, sizeof(overkill));
  153. /* Decode points. */
  154. ret = decaf_448_point_decode(point, sig, DECAF_TRUE);
  155. ret &= decaf_448_point_decode(pubpoint, pub, DECAF_FALSE);
  156. ret &= decaf_448_scalar_decode(response, &sig[DECAF_448_SER_BYTES]);
  157. decaf_448_base_double_scalarmul_non_secret (
  158. pubpoint, response, pubpoint, challenge
  159. );
  160. ret &= decaf_448_point_eq(pubpoint, point);
  161. return ret;
  162. }
  163. void
  164. decaf_448_sign (
  165. decaf_448_signature_t sig,
  166. const decaf_448_private_key_t priv,
  167. const unsigned char *message,
  168. size_t message_len
  169. ) {
  170. keccak_sponge_t ctx;
  171. shake256_init(ctx);
  172. shake256_update(ctx, message, message_len);
  173. decaf_448_sign_shake(sig, priv, ctx);
  174. shake256_destroy(ctx);
  175. }
  176. decaf_bool_t
  177. decaf_448_verify (
  178. const decaf_448_signature_t sig,
  179. const decaf_448_public_key_t pub,
  180. const unsigned char *message,
  181. size_t message_len
  182. ) {
  183. keccak_sponge_t ctx;
  184. shake256_init(ctx);
  185. shake256_update(ctx, message, message_len);
  186. decaf_bool_t ret = decaf_448_verify_shake(sig, pub, ctx);
  187. shake256_destroy(ctx);
  188. return ret;
  189. }