Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

145 rader
4.3 KiB

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