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.

124 lines
3.5 KiB

  1. #include "hash_address.h"
  2. #include "xmss_commons.h"
  3. #include "params.h"
  4. #include "hash.h"
  5. #include "fips202.h"
  6. #include <stdint.h>
  7. #include <string.h>
  8. #include <openssl/sha.h>
  9. unsigned char* addr_to_byte(unsigned char *bytes, const uint32_t addr[8])
  10. {
  11. int i;
  12. for (i = 0; i < 8; i++) {
  13. to_byte(bytes + i*4, addr[i], 4);
  14. }
  15. return bytes;
  16. }
  17. static int core_hash(const xmss_params *params,
  18. unsigned char *out, const unsigned int type,
  19. const unsigned char *key, unsigned int keylen,
  20. const unsigned char *in, unsigned long long inlen, int n)
  21. {
  22. unsigned long long i = 0;
  23. unsigned char buf[inlen + n + keylen];
  24. /* Input is of the form (toByte(X, 32) || KEY || M). */
  25. to_byte(buf, type, n);
  26. for (i=0; i < keylen; i++) {
  27. buf[i+n] = key[i];
  28. }
  29. for (i=0; i < inlen; i++) {
  30. buf[keylen + n + i] = in[i];
  31. }
  32. if (n == 32 && params->func == XMSS_SHA2) {
  33. SHA256(buf, inlen + keylen + n, out);
  34. }
  35. else if (n == 32 && params->func == XMSS_SHAKE) {
  36. shake128(out, 32, buf, inlen + keylen + n);
  37. }
  38. else if (n == 64 && params->func == XMSS_SHA2) {
  39. SHA512(buf, inlen + keylen + n, out);
  40. }
  41. else if (n == 64 && params->func == XMSS_SHAKE) {
  42. shake256(out, 64, buf, inlen + keylen + n);
  43. }
  44. else {
  45. return 1;
  46. }
  47. return 0;
  48. }
  49. int prf(const xmss_params *params,
  50. unsigned char *out, const unsigned char *in,
  51. const unsigned char *key, unsigned int keylen)
  52. {
  53. return core_hash(params, out, 3, key, keylen, in, 32, keylen);
  54. }
  55. int h_msg(const xmss_params *params,
  56. unsigned char *out,
  57. const unsigned char *in, unsigned long long inlen,
  58. const unsigned char *key, const unsigned int keylen)
  59. {
  60. return core_hash(params, out, 2, key, keylen, in, inlen, params->n);
  61. }
  62. /**
  63. * We assume the left half is in in[0]...in[n-1]
  64. */
  65. int hash_h(const xmss_params *params,
  66. unsigned char *out, const unsigned char *in,
  67. const unsigned char *pub_seed, uint32_t addr[8])
  68. {
  69. unsigned char buf[2*params->n];
  70. unsigned char key[params->n];
  71. unsigned char bitmask[2*params->n];
  72. unsigned char byte_addr[32];
  73. unsigned int i;
  74. set_key_and_mask(addr, 0);
  75. addr_to_byte(byte_addr, addr);
  76. prf(params, key, byte_addr, pub_seed, params->n);
  77. set_key_and_mask(addr, 1);
  78. addr_to_byte(byte_addr, addr);
  79. prf(params, bitmask, byte_addr, pub_seed, params->n);
  80. set_key_and_mask(addr, 2);
  81. addr_to_byte(byte_addr, addr);
  82. prf(params, bitmask+params->n, byte_addr, pub_seed, params->n);
  83. for (i = 0; i < 2*params->n; i++) {
  84. buf[i] = in[i] ^ bitmask[i];
  85. }
  86. return core_hash(params, out, 1, key, params->n, buf, 2*params->n, params->n);
  87. }
  88. int hash_f(const xmss_params *params,
  89. unsigned char *out, const unsigned char *in,
  90. const unsigned char *pub_seed, uint32_t addr[8])
  91. {
  92. unsigned char buf[params->n];
  93. unsigned char key[params->n];
  94. unsigned char bitmask[params->n];
  95. unsigned char byte_addr[32];
  96. unsigned int i;
  97. set_key_and_mask(addr, 0);
  98. addr_to_byte(byte_addr, addr);
  99. prf(params, key, byte_addr, pub_seed, params->n);
  100. set_key_and_mask(addr, 1);
  101. addr_to_byte(byte_addr, addr);
  102. prf(params, bitmask, byte_addr, pub_seed, params->n);
  103. for (i = 0; i < params->n; i++) {
  104. buf[i] = in[i] ^ bitmask[i];
  105. }
  106. return core_hash(params, out, 0, key, params->n, buf, params->n, params->n);
  107. }