Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

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