Line data Source code
1 : // Copyright (c) 2016-2020 The Bitcoin Core developers 2 : // Distributed under the MIT software license, see the accompanying 3 : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 : 5 : #include <crypto/siphash.h> 6 : 7 : #define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b)))) 8 : 9 : #define SIPROUND do { \ 10 : v0 += v1; v1 = ROTL(v1, 13); v1 ^= v0; \ 11 : v0 = ROTL(v0, 32); \ 12 : v2 += v3; v3 = ROTL(v3, 16); v3 ^= v2; \ 13 : v0 += v3; v3 = ROTL(v3, 21); v3 ^= v0; \ 14 : v2 += v1; v1 = ROTL(v1, 17); v1 ^= v2; \ 15 : v2 = ROTL(v2, 32); \ 16 : } while (0) 17 : 18 224 : CSipHasher::CSipHasher(uint64_t k0, uint64_t k1) 19 : { 20 224 : v[0] = 0x736f6d6570736575ULL ^ k0; 21 224 : v[1] = 0x646f72616e646f6dULL ^ k1; 22 224 : v[2] = 0x6c7967656e657261ULL ^ k0; 23 224 : v[3] = 0x7465646279746573ULL ^ k1; 24 224 : count = 0; 25 224 : tmp = 0; 26 224 : } 27 : 28 224 : CSipHasher& CSipHasher::Write(uint64_t data) 29 : { 30 224 : uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3]; 31 : 32 224 : assert(count % 8 == 0); 33 : 34 224 : v3 ^= data; 35 224 : SIPROUND; 36 224 : SIPROUND; 37 224 : v0 ^= data; 38 : 39 224 : v[0] = v0; 40 224 : v[1] = v1; 41 224 : v[2] = v2; 42 224 : v[3] = v3; 43 : 44 224 : count += 8; 45 224 : return *this; 46 : } 47 : 48 0 : CSipHasher& CSipHasher::Write(Span<const unsigned char> data) 49 : { 50 0 : uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3]; 51 0 : uint64_t t = tmp; 52 0 : uint8_t c = count; 53 : 54 0 : while (data.size() > 0) { 55 0 : t |= uint64_t{data.front()} << (8 * (c % 8)); 56 0 : c++; 57 0 : if ((c & 7) == 0) { 58 0 : v3 ^= t; 59 0 : SIPROUND; 60 0 : SIPROUND; 61 0 : v0 ^= t; 62 0 : t = 0; 63 0 : } 64 0 : data = data.subspan(1); 65 : } 66 : 67 0 : v[0] = v0; 68 0 : v[1] = v1; 69 0 : v[2] = v2; 70 0 : v[3] = v3; 71 0 : count = c; 72 0 : tmp = t; 73 : 74 0 : return *this; 75 : } 76 : 77 224 : uint64_t CSipHasher::Finalize() const 78 : { 79 224 : uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3]; 80 : 81 224 : uint64_t t = tmp | (((uint64_t)count) << 56); 82 : 83 224 : v3 ^= t; 84 224 : SIPROUND; 85 224 : SIPROUND; 86 224 : v0 ^= t; 87 224 : v2 ^= 0xFF; 88 224 : SIPROUND; 89 224 : SIPROUND; 90 224 : SIPROUND; 91 224 : SIPROUND; 92 224 : return v0 ^ v1 ^ v2 ^ v3; 93 : } 94 : 95 499823 : uint64_t SipHashUint256(uint64_t k0, uint64_t k1, const uint256& val) 96 : { 97 : /* Specialized implementation for efficiency */ 98 499823 : uint64_t d = val.GetUint64(0); 99 : 100 499823 : uint64_t v0 = 0x736f6d6570736575ULL ^ k0; 101 499823 : uint64_t v1 = 0x646f72616e646f6dULL ^ k1; 102 499823 : uint64_t v2 = 0x6c7967656e657261ULL ^ k0; 103 499823 : uint64_t v3 = 0x7465646279746573ULL ^ k1 ^ d; 104 : 105 499823 : SIPROUND; 106 499823 : SIPROUND; 107 499823 : v0 ^= d; 108 499823 : d = val.GetUint64(1); 109 499823 : v3 ^= d; 110 499823 : SIPROUND; 111 499823 : SIPROUND; 112 499823 : v0 ^= d; 113 499823 : d = val.GetUint64(2); 114 499823 : v3 ^= d; 115 499823 : SIPROUND; 116 499823 : SIPROUND; 117 499823 : v0 ^= d; 118 499823 : d = val.GetUint64(3); 119 499823 : v3 ^= d; 120 499823 : SIPROUND; 121 499823 : SIPROUND; 122 499823 : v0 ^= d; 123 499823 : v3 ^= (uint64_t{4}) << 59; 124 499823 : SIPROUND; 125 499823 : SIPROUND; 126 499823 : v0 ^= (uint64_t{4}) << 59; 127 499823 : v2 ^= 0xFF; 128 499823 : SIPROUND; 129 499823 : SIPROUND; 130 499823 : SIPROUND; 131 499823 : SIPROUND; 132 499823 : return v0 ^ v1 ^ v2 ^ v3; 133 : } 134 : 135 2409407 : uint64_t SipHashUint256Extra(uint64_t k0, uint64_t k1, const uint256& val, uint32_t extra) 136 : { 137 : /* Specialized implementation for efficiency */ 138 2409407 : uint64_t d = val.GetUint64(0); 139 : 140 2409407 : uint64_t v0 = 0x736f6d6570736575ULL ^ k0; 141 2409407 : uint64_t v1 = 0x646f72616e646f6dULL ^ k1; 142 2409407 : uint64_t v2 = 0x6c7967656e657261ULL ^ k0; 143 2409407 : uint64_t v3 = 0x7465646279746573ULL ^ k1 ^ d; 144 : 145 2409407 : SIPROUND; 146 2409407 : SIPROUND; 147 2409407 : v0 ^= d; 148 2409407 : d = val.GetUint64(1); 149 2409407 : v3 ^= d; 150 2409407 : SIPROUND; 151 2409407 : SIPROUND; 152 2409407 : v0 ^= d; 153 2409407 : d = val.GetUint64(2); 154 2409407 : v3 ^= d; 155 2409407 : SIPROUND; 156 2409407 : SIPROUND; 157 2409407 : v0 ^= d; 158 2409407 : d = val.GetUint64(3); 159 2409407 : v3 ^= d; 160 2409407 : SIPROUND; 161 2409407 : SIPROUND; 162 2409407 : v0 ^= d; 163 2409407 : d = ((uint64_t{36}) << 56) | extra; 164 2409407 : v3 ^= d; 165 2409407 : SIPROUND; 166 2409407 : SIPROUND; 167 2409407 : v0 ^= d; 168 2409407 : v2 ^= 0xFF; 169 2409407 : SIPROUND; 170 2409407 : SIPROUND; 171 2409407 : SIPROUND; 172 2409407 : SIPROUND; 173 2409407 : return v0 ^ v1 ^ v2 ^ v3; 174 : }