Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

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