Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

159 lignes
5.0 KiB

  1. #include <stdint.h>
  2. #include <string.h>
  3. #include <openssl/sha.h>
  4. #include "hash_address.h"
  5. #include "xmss_commons.h"
  6. #include "params.h"
  7. #include "hash.h"
  8. #include "fips202.h"
  9. void addr_to_bytes(unsigned char *bytes, const uint32_t addr[8])
  10. {
  11. int i;
  12. for (i = 0; i < 8; i++) {
  13. ull_to_bytes(bytes + i*4, 4, addr[i]);
  14. }
  15. }
  16. static int core_hash(const xmss_params *params,
  17. unsigned char *out, const unsigned int type,
  18. const unsigned char *key, unsigned int keylen,
  19. const unsigned char *in, unsigned long long inlen, int n)
  20. {
  21. unsigned char buf[inlen + n + keylen];
  22. /* We arrange the input into the hash function to be of the form:
  23. * toByte(X, 32) || KEY || M */
  24. ull_to_bytes(buf, n, type);
  25. memcpy(buf + n, key, keylen);
  26. memcpy(buf + keylen + n, in, inlen);
  27. if (n == 32 && params->func == XMSS_SHA2) {
  28. SHA256(buf, inlen + keylen + n, out);
  29. }
  30. else if (n == 32 && params->func == XMSS_SHAKE) {
  31. shake128(out, 32, buf, inlen + keylen + n);
  32. }
  33. else if (n == 64 && params->func == XMSS_SHA2) {
  34. SHA512(buf, inlen + keylen + n, out);
  35. }
  36. else if (n == 64 && params->func == XMSS_SHAKE) {
  37. shake256(out, 64, buf, inlen + keylen + n);
  38. }
  39. else {
  40. return 1;
  41. }
  42. return 0;
  43. }
  44. int prf(const xmss_params *params,
  45. unsigned char *out, const unsigned char *in,
  46. const unsigned char *key, unsigned int keylen)
  47. {
  48. return core_hash(params, out, 3, key, keylen, in, 32, keylen);
  49. }
  50. int h_msg(const xmss_params *params,
  51. unsigned char *out,
  52. const unsigned char *in, unsigned long long inlen,
  53. const unsigned char *key, const unsigned int keylen)
  54. {
  55. return core_hash(params, out, 2, key, keylen, in, inlen, params->n);
  56. }
  57. /*
  58. * Computes the message hash using R, the public root, the index of the leaf
  59. * node, and the message. Notably, it requires m_with_prefix to have 4*n bytes
  60. * of space before the message, to use for the prefix. This is necessary to
  61. * prevent having to move the message around (and thus allocate memory for it).
  62. */
  63. int hash_message(const xmss_params *params, unsigned char *out,
  64. const unsigned char *R, const unsigned char *root,
  65. unsigned long long idx,
  66. unsigned char *m_with_prefix, unsigned long long mlen)
  67. {
  68. /* We're creating a hash using input of the form:
  69. toByte(X, 32) || R || root || index || M */
  70. ull_to_bytes(m_with_prefix, params->n, 2);
  71. memcpy(m_with_prefix + params->n, R, params->n);
  72. memcpy(m_with_prefix + 2 * params->n, root, params->n);
  73. ull_to_bytes(m_with_prefix + 3 * params->n, params->n, idx);
  74. /* Since the message can be bigger than the stack, this cannot use the
  75. * core_hash function. */
  76. if (params->n == 32 && params->func == XMSS_SHA2) {
  77. SHA256(m_with_prefix, mlen + 4*params->n, out);
  78. }
  79. else if (params->n == 32 && params->func == XMSS_SHAKE) {
  80. shake128(out, 32, m_with_prefix, mlen + 4*params->n);
  81. }
  82. else if (params->n == 64 && params->func == XMSS_SHA2) {
  83. SHA512(m_with_prefix, mlen + 4*params->n, out);
  84. }
  85. else if (params->n == 64 && params->func == XMSS_SHAKE) {
  86. shake256(out, 64, m_with_prefix, mlen + 4*params->n);
  87. }
  88. else {
  89. return 1;
  90. }
  91. return 0;
  92. }
  93. /**
  94. * We assume the left half is in in[0]...in[n-1]
  95. */
  96. int hash_h(const xmss_params *params,
  97. unsigned char *out, const unsigned char *in,
  98. const unsigned char *pub_seed, uint32_t addr[8])
  99. {
  100. unsigned char buf[2*params->n];
  101. unsigned char key[params->n];
  102. unsigned char bitmask[2*params->n];
  103. unsigned char addr_as_bytes[32];
  104. unsigned int i;
  105. /* Generate the n-byte key. */
  106. set_key_and_mask(addr, 0);
  107. addr_to_bytes(addr_as_bytes, addr);
  108. prf(params, key, addr_as_bytes, pub_seed, params->n);
  109. /* Generate the 2n-byte mask. */
  110. set_key_and_mask(addr, 1);
  111. addr_to_bytes(addr_as_bytes, addr);
  112. prf(params, bitmask, addr_as_bytes, pub_seed, params->n);
  113. set_key_and_mask(addr, 2);
  114. addr_to_bytes(addr_as_bytes, addr);
  115. prf(params, bitmask + params->n, addr_as_bytes, pub_seed, params->n);
  116. for (i = 0; i < 2*params->n; i++) {
  117. buf[i] = in[i] ^ bitmask[i];
  118. }
  119. return core_hash(params, out, 1, key, params->n, buf, 2*params->n, params->n);
  120. }
  121. int hash_f(const xmss_params *params,
  122. unsigned char *out, const unsigned char *in,
  123. const unsigned char *pub_seed, uint32_t addr[8])
  124. {
  125. unsigned char buf[params->n];
  126. unsigned char key[params->n];
  127. unsigned char bitmask[params->n];
  128. unsigned char addr_as_bytes[32];
  129. unsigned int i;
  130. set_key_and_mask(addr, 0);
  131. addr_to_bytes(addr_as_bytes, addr);
  132. prf(params, key, addr_as_bytes, pub_seed, params->n);
  133. set_key_and_mask(addr, 1);
  134. addr_to_bytes(addr_as_bytes, addr);
  135. prf(params, bitmask, addr_as_bytes, pub_seed, params->n);
  136. for (i = 0; i < params->n; i++) {
  137. buf[i] = in[i] ^ bitmask[i];
  138. }
  139. return core_hash(params, out, 0, key, params->n, buf, params->n, params->n);
  140. }