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.

hash.cpp 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. // Copyright (c) 2013-2016 The Starwels developers
  2. // Distributed under the MIT software license, see the accompanying
  3. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  4. #include "hash.h"
  5. #include "crypto/common.h"
  6. #include "crypto/hmac_sha512.h"
  7. #include "pubkey.h"
  8. inline uint32_t ROTL32(uint32_t x, int8_t r)
  9. {
  10. return (x << r) | (x >> (32 - r));
  11. }
  12. unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char>& vDataToHash)
  13. {
  14. // The following is MurmurHash3 (x86_32), see http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp
  15. uint32_t h1 = nHashSeed;
  16. const uint32_t c1 = 0xcc9e2d51;
  17. const uint32_t c2 = 0x1b873593;
  18. const int nblocks = vDataToHash.size() / 4;
  19. //----------
  20. // body
  21. const uint8_t* blocks = vDataToHash.data();
  22. for (int i = 0; i < nblocks; ++i) {
  23. uint32_t k1 = ReadLE32(blocks + i*4);
  24. k1 *= c1;
  25. k1 = ROTL32(k1, 15);
  26. k1 *= c2;
  27. h1 ^= k1;
  28. h1 = ROTL32(h1, 13);
  29. h1 = h1 * 5 + 0xe6546b64;
  30. }
  31. //----------
  32. // tail
  33. const uint8_t* tail = vDataToHash.data() + nblocks * 4;
  34. uint32_t k1 = 0;
  35. switch (vDataToHash.size() & 3) {
  36. case 3:
  37. k1 ^= tail[2] << 16;
  38. case 2:
  39. k1 ^= tail[1] << 8;
  40. case 1:
  41. k1 ^= tail[0];
  42. k1 *= c1;
  43. k1 = ROTL32(k1, 15);
  44. k1 *= c2;
  45. h1 ^= k1;
  46. }
  47. //----------
  48. // finalization
  49. h1 ^= vDataToHash.size();
  50. h1 ^= h1 >> 16;
  51. h1 *= 0x85ebca6b;
  52. h1 ^= h1 >> 13;
  53. h1 *= 0xc2b2ae35;
  54. h1 ^= h1 >> 16;
  55. return h1;
  56. }
  57. void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64])
  58. {
  59. unsigned char num[4];
  60. num[0] = (nChild >> 24) & 0xFF;
  61. num[1] = (nChild >> 16) & 0xFF;
  62. num[2] = (nChild >> 8) & 0xFF;
  63. num[3] = (nChild >> 0) & 0xFF;
  64. CHMAC_SHA512(chainCode.begin(), chainCode.size()).Write(&header, 1).Write(data, 32).Write(num, 4).Finalize(output);
  65. }
  66. #define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
  67. #define SIPROUND do { \
  68. v0 += v1; v1 = ROTL(v1, 13); v1 ^= v0; \
  69. v0 = ROTL(v0, 32); \
  70. v2 += v3; v3 = ROTL(v3, 16); v3 ^= v2; \
  71. v0 += v3; v3 = ROTL(v3, 21); v3 ^= v0; \
  72. v2 += v1; v1 = ROTL(v1, 17); v1 ^= v2; \
  73. v2 = ROTL(v2, 32); \
  74. } while (0)
  75. CSipHasher::CSipHasher(uint64_t k0, uint64_t k1)
  76. {
  77. v[0] = 0x736f6d6570736575ULL ^ k0;
  78. v[1] = 0x646f72616e646f6dULL ^ k1;
  79. v[2] = 0x6c7967656e657261ULL ^ k0;
  80. v[3] = 0x7465646279746573ULL ^ k1;
  81. count = 0;
  82. tmp = 0;
  83. }
  84. CSipHasher& CSipHasher::Write(uint64_t data)
  85. {
  86. uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
  87. assert(count % 8 == 0);
  88. v3 ^= data;
  89. SIPROUND;
  90. SIPROUND;
  91. v0 ^= data;
  92. v[0] = v0;
  93. v[1] = v1;
  94. v[2] = v2;
  95. v[3] = v3;
  96. count += 8;
  97. return *this;
  98. }
  99. CSipHasher& CSipHasher::Write(const unsigned char* data, size_t size)
  100. {
  101. uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
  102. uint64_t t = tmp;
  103. int c = count;
  104. while (size--) {
  105. t |= ((uint64_t)(*(data++))) << (8 * (c % 8));
  106. c++;
  107. if ((c & 7) == 0) {
  108. v3 ^= t;
  109. SIPROUND;
  110. SIPROUND;
  111. v0 ^= t;
  112. t = 0;
  113. }
  114. }
  115. v[0] = v0;
  116. v[1] = v1;
  117. v[2] = v2;
  118. v[3] = v3;
  119. count = c;
  120. tmp = t;
  121. return *this;
  122. }
  123. uint64_t CSipHasher::Finalize() const
  124. {
  125. uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
  126. uint64_t t = tmp | (((uint64_t)count) << 56);
  127. v3 ^= t;
  128. SIPROUND;
  129. SIPROUND;
  130. v0 ^= t;
  131. v2 ^= 0xFF;
  132. SIPROUND;
  133. SIPROUND;
  134. SIPROUND;
  135. SIPROUND;
  136. return v0 ^ v1 ^ v2 ^ v3;
  137. }
  138. uint64_t SipHashUint256(uint64_t k0, uint64_t k1, const uint256& val)
  139. {
  140. /* Specialized implementation for efficiency */
  141. uint64_t d = val.GetUint64(0);
  142. uint64_t v0 = 0x736f6d6570736575ULL ^ k0;
  143. uint64_t v1 = 0x646f72616e646f6dULL ^ k1;
  144. uint64_t v2 = 0x6c7967656e657261ULL ^ k0;
  145. uint64_t v3 = 0x7465646279746573ULL ^ k1 ^ d;
  146. SIPROUND;
  147. SIPROUND;
  148. v0 ^= d;
  149. d = val.GetUint64(1);
  150. v3 ^= d;
  151. SIPROUND;
  152. SIPROUND;
  153. v0 ^= d;
  154. d = val.GetUint64(2);
  155. v3 ^= d;
  156. SIPROUND;
  157. SIPROUND;
  158. v0 ^= d;
  159. d = val.GetUint64(3);
  160. v3 ^= d;
  161. SIPROUND;
  162. SIPROUND;
  163. v0 ^= d;
  164. v3 ^= ((uint64_t)4) << 59;
  165. SIPROUND;
  166. SIPROUND;
  167. v0 ^= ((uint64_t)4) << 59;
  168. v2 ^= 0xFF;
  169. SIPROUND;
  170. SIPROUND;
  171. SIPROUND;
  172. SIPROUND;
  173. return v0 ^ v1 ^ v2 ^ v3;
  174. }
  175. uint64_t SipHashUint256Extra(uint64_t k0, uint64_t k1, const uint256& val, uint32_t extra)
  176. {
  177. /* Specialized implementation for efficiency */
  178. uint64_t d = val.GetUint64(0);
  179. uint64_t v0 = 0x736f6d6570736575ULL ^ k0;
  180. uint64_t v1 = 0x646f72616e646f6dULL ^ k1;
  181. uint64_t v2 = 0x6c7967656e657261ULL ^ k0;
  182. uint64_t v3 = 0x7465646279746573ULL ^ k1 ^ d;
  183. SIPROUND;
  184. SIPROUND;
  185. v0 ^= d;
  186. d = val.GetUint64(1);
  187. v3 ^= d;
  188. SIPROUND;
  189. SIPROUND;
  190. v0 ^= d;
  191. d = val.GetUint64(2);
  192. v3 ^= d;
  193. SIPROUND;
  194. SIPROUND;
  195. v0 ^= d;
  196. d = val.GetUint64(3);
  197. v3 ^= d;
  198. SIPROUND;
  199. SIPROUND;
  200. v0 ^= d;
  201. d = (((uint64_t)36) << 56) | extra;
  202. v3 ^= d;
  203. SIPROUND;
  204. SIPROUND;
  205. v0 ^= d;
  206. v2 ^= 0xFF;
  207. SIPROUND;
  208. SIPROUND;
  209. SIPROUND;
  210. SIPROUND;
  211. return v0 ^ v1 ^ v2 ^ v3;
  212. }