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