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.

149 lines
3.2 KiB

  1. /*
  2. hash.c version 20160210
  3. Andreas Hülsing
  4. Joost Rijneveld
  5. Public domain.
  6. */
  7. #include "prg.h"
  8. #include "hash_address.h"
  9. #include <stddef.h>
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <openssl/sha.h>
  13. #include <openssl/hmac.h>
  14. #include <openssl/evp.h>
  15. /**
  16. * Implements PRF_m
  17. */
  18. int prf_m(unsigned char *out, const unsigned char *in, size_t inlen, const unsigned char *key, unsigned int keylen)
  19. {
  20. unsigned int length;
  21. if (keylen == 32) {
  22. HMAC(EVP_sha256(), key, keylen, in, inlen, out, &length);
  23. if (length != 32) {
  24. fprintf(stderr, "HMAC outputs %d bytes... That should not happen...", length);
  25. }
  26. return 0;
  27. }
  28. else {
  29. if (keylen == 64) {
  30. HMAC(EVP_sha512(), key, keylen, in, inlen, out, &length);
  31. if (length != 64) {
  32. fprintf(stderr, "HMAC outputs %d bytes... That should not happen...", length);
  33. }
  34. return 0;
  35. }
  36. }
  37. return 1;
  38. }
  39. /*
  40. * Implemts H_m
  41. */
  42. int hash_m(unsigned char *out, const unsigned char *in, unsigned long long inlen, const unsigned char *key, const unsigned int keylen, const unsigned int m)
  43. {
  44. unsigned int i;
  45. unsigned char buf[inlen + keylen];
  46. if (keylen != 2*m){
  47. fprintf(stderr, "H_m takes 2m-bit keys, we got m=%d but a keylength of %d.\n", m, keylen);
  48. return 1;
  49. }
  50. for (i=0; i < keylen; i++) {
  51. buf[i] = key[i];
  52. }
  53. for (i=0; i < inlen; i++) {
  54. buf[keylen + i] = in[i];
  55. }
  56. if (m == 32) {
  57. SHA256(buf, inlen + keylen, out);
  58. return 0;
  59. }
  60. else {
  61. if (m == 64) {
  62. SHA512(buf, inlen + keylen, out);
  63. return 0;
  64. }
  65. }
  66. return 1;
  67. }
  68. /**
  69. * We assume the left half is in in[0]...in[n-1]
  70. */
  71. int hash_2n_n(unsigned char *out, const unsigned char *in, const unsigned char *pub_seed, unsigned char addr[16], const unsigned int n)
  72. {
  73. unsigned char buf[4*n];
  74. unsigned char key[n];
  75. unsigned char bitmask[2*n];
  76. unsigned int i;
  77. SET_KEY_BIT(addr, 1);
  78. SET_BLOCK_BIT(addr, 0);
  79. prg_with_counter(key, pub_seed, n, addr);
  80. SET_KEY_BIT(addr, 0);
  81. // Use MSB order
  82. prg_with_counter(bitmask, pub_seed, n, addr);
  83. SET_BLOCK_BIT(addr, 1);
  84. prg_with_counter(bitmask+n, pub_seed, n, addr);
  85. for (i = 0; i < n; i++) {
  86. buf[i] = 0x00;
  87. buf[n+i] = key[i];
  88. buf[2*n+i] = in[i] ^ bitmask[i];
  89. buf[3*n+i] = in[n+i] ^ bitmask[n+i];
  90. }
  91. if (n == 32) {
  92. SHA256(buf, 4*n, out);
  93. return 0;
  94. }
  95. else {
  96. if (n == 64) {
  97. SHA512(buf, 4*n, out);
  98. return 0;
  99. }
  100. else {
  101. fprintf(stderr, "Hash.c:hash_2n_n: Code only supports n=32 or n=64");
  102. return -1;
  103. }
  104. }
  105. }
  106. int hash_n_n(unsigned char *out, const unsigned char *in, const unsigned char *pub_seed, unsigned char addr[16], const unsigned int n)
  107. {
  108. unsigned char buf[3*n];
  109. unsigned char key[n];
  110. unsigned char bitmask[n];
  111. unsigned int i;
  112. WOTS_SELECT_KEY(addr);
  113. prg_with_counter(key, pub_seed, n, addr);
  114. WOTS_SELECT_BLOCK(addr);
  115. prg_with_counter(bitmask, pub_seed, n, addr);
  116. for (i = 0; i < n; i++) {
  117. buf[i] = 0x00;
  118. buf[n+i] = key[i];
  119. buf[2*n+i] = in[i] ^ bitmask[i];
  120. }
  121. if (n == 32) {
  122. SHA256(buf, 3*n, out);
  123. return 0;
  124. }
  125. else {
  126. if (n == 64) {
  127. SHA512(buf, 3*n, out);
  128. return 0;
  129. }
  130. else {
  131. fprintf(stderr, "Hash.c:hash_n_n: Code only supports n=32 or n=64");
  132. return -1;
  133. }
  134. }
  135. }