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.

137 line
3.3 KiB

  1. /*
  2. hash.c version 20160722
  3. Andreas Hülsing
  4. Joost Rijneveld
  5. Public domain.
  6. */
  7. #include "hash_address.h"
  8. #include "xmss_commons.h"
  9. #include "params.h"
  10. #include "hash.h"
  11. #include "fips202.h"
  12. #include <stddef.h>
  13. #include <stdio.h>
  14. #include <stdint.h>
  15. #include <string.h>
  16. #include <openssl/sha.h>
  17. unsigned char* addr_to_byte(unsigned char *bytes, const uint32_t addr[8])
  18. {
  19. #if IS_LITTLE_ENDIAN==1
  20. int i = 0;
  21. for(i=0;i<8;i++)
  22. to_byte(bytes+i*4, addr[i],4);
  23. return bytes;
  24. #else
  25. memcpy(bytes, addr, 32);
  26. return bytes;
  27. #endif
  28. }
  29. static int core_hash(unsigned char *out, const unsigned int type, const unsigned char *key, unsigned int keylen, const unsigned char *in, unsigned long long inlen, int n)
  30. {
  31. unsigned long long i = 0;
  32. unsigned char buf[inlen + n + keylen];
  33. // Input is (toByte(X, 32) || KEY || M)
  34. // set toByte
  35. to_byte(buf, type, n);
  36. for (i=0; i < keylen; i++) {
  37. buf[i+n] = key[i];
  38. }
  39. for (i=0; i < inlen; i++) {
  40. buf[keylen + n + i] = in[i];
  41. }
  42. if (n == 32 && XMSS_FUNC == XMSS_SHA2) {
  43. SHA256(buf, inlen + keylen + n, out);
  44. }
  45. else if (n == 32 && XMSS_FUNC == XMSS_SHAKE) {
  46. shake128(out, 32, buf, inlen + keylen + n);
  47. }
  48. else if (n == 64 && XMSS_FUNC == XMSS_SHA2) {
  49. SHA512(buf, inlen + keylen + n, out);
  50. }
  51. else if (n == 64 && XMSS_FUNC == XMSS_SHAKE) {
  52. shake256(out, 64, buf, inlen + keylen + n);
  53. }
  54. else {
  55. return 1;
  56. }
  57. return 0;
  58. }
  59. /**
  60. * Implements PRF
  61. */
  62. int prf(unsigned char *out, const unsigned char *in, const unsigned char *key, unsigned int keylen)
  63. {
  64. return core_hash(out, 3, key, keylen, in, 32, keylen);
  65. }
  66. /*
  67. * Implemts H_msg
  68. */
  69. int h_msg(unsigned char *out, const unsigned char *in, unsigned long long inlen, const unsigned char *key, const unsigned int keylen)
  70. {
  71. if (keylen != 3*XMSS_N){
  72. fprintf(stderr, "H_msg takes 3n-bit keys, we got n=%d but a keylength of %d.\n", XMSS_N, keylen);
  73. return 1;
  74. }
  75. return core_hash(out, 2, key, keylen, in, inlen, XMSS_N);
  76. }
  77. /**
  78. * We assume the left half is in in[0]...in[n-1]
  79. */
  80. int hash_h(unsigned char *out, const unsigned char *in, const unsigned char *pub_seed, uint32_t addr[8])
  81. {
  82. unsigned char buf[2*XMSS_N];
  83. unsigned char key[XMSS_N];
  84. unsigned char bitmask[2*XMSS_N];
  85. unsigned char byte_addr[32];
  86. unsigned int i;
  87. setKeyAndMask(addr, 0);
  88. addr_to_byte(byte_addr, addr);
  89. prf(key, byte_addr, pub_seed, XMSS_N);
  90. // Use MSB order
  91. setKeyAndMask(addr, 1);
  92. addr_to_byte(byte_addr, addr);
  93. prf(bitmask, byte_addr, pub_seed, XMSS_N);
  94. setKeyAndMask(addr, 2);
  95. addr_to_byte(byte_addr, addr);
  96. prf(bitmask+XMSS_N, byte_addr, pub_seed, XMSS_N);
  97. for (i = 0; i < 2*XMSS_N; i++) {
  98. buf[i] = in[i] ^ bitmask[i];
  99. }
  100. return core_hash(out, 1, key, XMSS_N, buf, 2*XMSS_N, XMSS_N);
  101. }
  102. int hash_f(unsigned char *out, const unsigned char *in, const unsigned char *pub_seed, uint32_t addr[8])
  103. {
  104. unsigned char buf[XMSS_N];
  105. unsigned char key[XMSS_N];
  106. unsigned char bitmask[XMSS_N];
  107. unsigned char byte_addr[32];
  108. unsigned int i;
  109. setKeyAndMask(addr, 0);
  110. addr_to_byte(byte_addr, addr);
  111. prf(key, byte_addr, pub_seed, XMSS_N);
  112. setKeyAndMask(addr, 1);
  113. addr_to_byte(byte_addr, addr);
  114. prf(bitmask, byte_addr, pub_seed, XMSS_N);
  115. for (i = 0; i < XMSS_N; i++) {
  116. buf[i] = in[i] ^ bitmask[i];
  117. }
  118. return core_hash(out, 0, key, XMSS_N, buf, XMSS_N, XMSS_N);
  119. }