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.

144 lines
3.2 KiB

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