/Users/eugenesiegel/btc/bitcoin/src/crypto/ripemd160.cpp
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | // Copyright (c) 2014-present 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/ripemd160.h> | 
| 6 |  |  | 
| 7 |  | #include <crypto/common.h> | 
| 8 |  |  | 
| 9 |  | #include <cstring> | 
| 10 |  |  | 
| 11 |  | // Internal implementation code. | 
| 12 |  | namespace | 
| 13 |  | { | 
| 14 |  | /// Internal RIPEMD-160 implementation. | 
| 15 |  | namespace ripemd160 | 
| 16 |  | { | 
| 17 | 0 | uint32_t inline f1(uint32_t x, uint32_t y, uint32_t z) { return x ^ y ^ z; } | 
| 18 | 0 | uint32_t inline f2(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (~x & z); } | 
| 19 | 0 | uint32_t inline f3(uint32_t x, uint32_t y, uint32_t z) { return (x | ~y) ^ z; } | 
| 20 | 0 | uint32_t inline f4(uint32_t x, uint32_t y, uint32_t z) { return (x & z) | (y & ~z); } | 
| 21 | 0 | uint32_t inline f5(uint32_t x, uint32_t y, uint32_t z) { return x ^ (y | ~z); } | 
| 22 |  |  | 
| 23 |  | /** Initialize RIPEMD-160 state. */ | 
| 24 |  | void inline Initialize(uint32_t* s) | 
| 25 | 0 | { | 
| 26 | 0 |     s[0] = 0x67452301ul; | 
| 27 | 0 |     s[1] = 0xEFCDAB89ul; | 
| 28 | 0 |     s[2] = 0x98BADCFEul; | 
| 29 | 0 |     s[3] = 0x10325476ul; | 
| 30 | 0 |     s[4] = 0xC3D2E1F0ul; | 
| 31 | 0 | } | 
| 32 |  |  | 
| 33 | 0 | uint32_t inline rol(uint32_t x, int i) { return (x << i) | (x >> (32 - i)); } | 
| 34 |  |  | 
| 35 |  | void inline Round(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t f, uint32_t x, uint32_t k, int r) | 
| 36 | 0 | { | 
| 37 | 0 |     a = rol(a + f + x + k, r) + e; | 
| 38 | 0 |     c = rol(c, 10); | 
| 39 | 0 | } | 
| 40 |  |  | 
| 41 | 0 | void inline R11(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f1(b, c, d), x, 0, r); } | 
| 42 | 0 | void inline R21(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f2(b, c, d), x, 0x5A827999ul, r); } | 
| 43 | 0 | void inline R31(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f3(b, c, d), x, 0x6ED9EBA1ul, r); } | 
| 44 | 0 | void inline R41(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f4(b, c, d), x, 0x8F1BBCDCul, r); } | 
| 45 | 0 | void inline R51(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f5(b, c, d), x, 0xA953FD4Eul, r); } | 
| 46 |  |  | 
| 47 | 0 | void inline R12(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f5(b, c, d), x, 0x50A28BE6ul, r); } | 
| 48 | 0 | void inline R22(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f4(b, c, d), x, 0x5C4DD124ul, r); } | 
| 49 | 0 | void inline R32(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f3(b, c, d), x, 0x6D703EF3ul, r); } | 
| 50 | 0 | void inline R42(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f2(b, c, d), x, 0x7A6D76E9ul, r); } | 
| 51 | 0 | void inline R52(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f1(b, c, d), x, 0, r); } | 
| 52 |  |  | 
| 53 |  | /** Perform a RIPEMD-160 transformation, processing a 64-byte chunk. */ | 
| 54 |  | void Transform(uint32_t* s, const unsigned char* chunk) | 
| 55 | 0 | { | 
| 56 | 0 |     uint32_t a1 = s[0], b1 = s[1], c1 = s[2], d1 = s[3], e1 = s[4]; | 
| 57 | 0 |     uint32_t a2 = a1, b2 = b1, c2 = c1, d2 = d1, e2 = e1; | 
| 58 | 0 |     uint32_t w0 = ReadLE32(chunk + 0), w1 = ReadLE32(chunk + 4), w2 = ReadLE32(chunk + 8), w3 = ReadLE32(chunk + 12); | 
| 59 | 0 |     uint32_t w4 = ReadLE32(chunk + 16), w5 = ReadLE32(chunk + 20), w6 = ReadLE32(chunk + 24), w7 = ReadLE32(chunk + 28); | 
| 60 | 0 |     uint32_t w8 = ReadLE32(chunk + 32), w9 = ReadLE32(chunk + 36), w10 = ReadLE32(chunk + 40), w11 = ReadLE32(chunk + 44); | 
| 61 | 0 |     uint32_t w12 = ReadLE32(chunk + 48), w13 = ReadLE32(chunk + 52), w14 = ReadLE32(chunk + 56), w15 = ReadLE32(chunk + 60); | 
| 62 |  | 
 | 
| 63 | 0 |     R11(a1, b1, c1, d1, e1, w0, 11); | 
| 64 | 0 |     R12(a2, b2, c2, d2, e2, w5, 8); | 
| 65 | 0 |     R11(e1, a1, b1, c1, d1, w1, 14); | 
| 66 | 0 |     R12(e2, a2, b2, c2, d2, w14, 9); | 
| 67 | 0 |     R11(d1, e1, a1, b1, c1, w2, 15); | 
| 68 | 0 |     R12(d2, e2, a2, b2, c2, w7, 9); | 
| 69 | 0 |     R11(c1, d1, e1, a1, b1, w3, 12); | 
| 70 | 0 |     R12(c2, d2, e2, a2, b2, w0, 11); | 
| 71 | 0 |     R11(b1, c1, d1, e1, a1, w4, 5); | 
| 72 | 0 |     R12(b2, c2, d2, e2, a2, w9, 13); | 
| 73 | 0 |     R11(a1, b1, c1, d1, e1, w5, 8); | 
| 74 | 0 |     R12(a2, b2, c2, d2, e2, w2, 15); | 
| 75 | 0 |     R11(e1, a1, b1, c1, d1, w6, 7); | 
| 76 | 0 |     R12(e2, a2, b2, c2, d2, w11, 15); | 
| 77 | 0 |     R11(d1, e1, a1, b1, c1, w7, 9); | 
| 78 | 0 |     R12(d2, e2, a2, b2, c2, w4, 5); | 
| 79 | 0 |     R11(c1, d1, e1, a1, b1, w8, 11); | 
| 80 | 0 |     R12(c2, d2, e2, a2, b2, w13, 7); | 
| 81 | 0 |     R11(b1, c1, d1, e1, a1, w9, 13); | 
| 82 | 0 |     R12(b2, c2, d2, e2, a2, w6, 7); | 
| 83 | 0 |     R11(a1, b1, c1, d1, e1, w10, 14); | 
| 84 | 0 |     R12(a2, b2, c2, d2, e2, w15, 8); | 
| 85 | 0 |     R11(e1, a1, b1, c1, d1, w11, 15); | 
| 86 | 0 |     R12(e2, a2, b2, c2, d2, w8, 11); | 
| 87 | 0 |     R11(d1, e1, a1, b1, c1, w12, 6); | 
| 88 | 0 |     R12(d2, e2, a2, b2, c2, w1, 14); | 
| 89 | 0 |     R11(c1, d1, e1, a1, b1, w13, 7); | 
| 90 | 0 |     R12(c2, d2, e2, a2, b2, w10, 14); | 
| 91 | 0 |     R11(b1, c1, d1, e1, a1, w14, 9); | 
| 92 | 0 |     R12(b2, c2, d2, e2, a2, w3, 12); | 
| 93 | 0 |     R11(a1, b1, c1, d1, e1, w15, 8); | 
| 94 | 0 |     R12(a2, b2, c2, d2, e2, w12, 6); | 
| 95 |  | 
 | 
| 96 | 0 |     R21(e1, a1, b1, c1, d1, w7, 7); | 
| 97 | 0 |     R22(e2, a2, b2, c2, d2, w6, 9); | 
| 98 | 0 |     R21(d1, e1, a1, b1, c1, w4, 6); | 
| 99 | 0 |     R22(d2, e2, a2, b2, c2, w11, 13); | 
| 100 | 0 |     R21(c1, d1, e1, a1, b1, w13, 8); | 
| 101 | 0 |     R22(c2, d2, e2, a2, b2, w3, 15); | 
| 102 | 0 |     R21(b1, c1, d1, e1, a1, w1, 13); | 
| 103 | 0 |     R22(b2, c2, d2, e2, a2, w7, 7); | 
| 104 | 0 |     R21(a1, b1, c1, d1, e1, w10, 11); | 
| 105 | 0 |     R22(a2, b2, c2, d2, e2, w0, 12); | 
| 106 | 0 |     R21(e1, a1, b1, c1, d1, w6, 9); | 
| 107 | 0 |     R22(e2, a2, b2, c2, d2, w13, 8); | 
| 108 | 0 |     R21(d1, e1, a1, b1, c1, w15, 7); | 
| 109 | 0 |     R22(d2, e2, a2, b2, c2, w5, 9); | 
| 110 | 0 |     R21(c1, d1, e1, a1, b1, w3, 15); | 
| 111 | 0 |     R22(c2, d2, e2, a2, b2, w10, 11); | 
| 112 | 0 |     R21(b1, c1, d1, e1, a1, w12, 7); | 
| 113 | 0 |     R22(b2, c2, d2, e2, a2, w14, 7); | 
| 114 | 0 |     R21(a1, b1, c1, d1, e1, w0, 12); | 
| 115 | 0 |     R22(a2, b2, c2, d2, e2, w15, 7); | 
| 116 | 0 |     R21(e1, a1, b1, c1, d1, w9, 15); | 
| 117 | 0 |     R22(e2, a2, b2, c2, d2, w8, 12); | 
| 118 | 0 |     R21(d1, e1, a1, b1, c1, w5, 9); | 
| 119 | 0 |     R22(d2, e2, a2, b2, c2, w12, 7); | 
| 120 | 0 |     R21(c1, d1, e1, a1, b1, w2, 11); | 
| 121 | 0 |     R22(c2, d2, e2, a2, b2, w4, 6); | 
| 122 | 0 |     R21(b1, c1, d1, e1, a1, w14, 7); | 
| 123 | 0 |     R22(b2, c2, d2, e2, a2, w9, 15); | 
| 124 | 0 |     R21(a1, b1, c1, d1, e1, w11, 13); | 
| 125 | 0 |     R22(a2, b2, c2, d2, e2, w1, 13); | 
| 126 | 0 |     R21(e1, a1, b1, c1, d1, w8, 12); | 
| 127 | 0 |     R22(e2, a2, b2, c2, d2, w2, 11); | 
| 128 |  | 
 | 
| 129 | 0 |     R31(d1, e1, a1, b1, c1, w3, 11); | 
| 130 | 0 |     R32(d2, e2, a2, b2, c2, w15, 9); | 
| 131 | 0 |     R31(c1, d1, e1, a1, b1, w10, 13); | 
| 132 | 0 |     R32(c2, d2, e2, a2, b2, w5, 7); | 
| 133 | 0 |     R31(b1, c1, d1, e1, a1, w14, 6); | 
| 134 | 0 |     R32(b2, c2, d2, e2, a2, w1, 15); | 
| 135 | 0 |     R31(a1, b1, c1, d1, e1, w4, 7); | 
| 136 | 0 |     R32(a2, b2, c2, d2, e2, w3, 11); | 
| 137 | 0 |     R31(e1, a1, b1, c1, d1, w9, 14); | 
| 138 | 0 |     R32(e2, a2, b2, c2, d2, w7, 8); | 
| 139 | 0 |     R31(d1, e1, a1, b1, c1, w15, 9); | 
| 140 | 0 |     R32(d2, e2, a2, b2, c2, w14, 6); | 
| 141 | 0 |     R31(c1, d1, e1, a1, b1, w8, 13); | 
| 142 | 0 |     R32(c2, d2, e2, a2, b2, w6, 6); | 
| 143 | 0 |     R31(b1, c1, d1, e1, a1, w1, 15); | 
| 144 | 0 |     R32(b2, c2, d2, e2, a2, w9, 14); | 
| 145 | 0 |     R31(a1, b1, c1, d1, e1, w2, 14); | 
| 146 | 0 |     R32(a2, b2, c2, d2, e2, w11, 12); | 
| 147 | 0 |     R31(e1, a1, b1, c1, d1, w7, 8); | 
| 148 | 0 |     R32(e2, a2, b2, c2, d2, w8, 13); | 
| 149 | 0 |     R31(d1, e1, a1, b1, c1, w0, 13); | 
| 150 | 0 |     R32(d2, e2, a2, b2, c2, w12, 5); | 
| 151 | 0 |     R31(c1, d1, e1, a1, b1, w6, 6); | 
| 152 | 0 |     R32(c2, d2, e2, a2, b2, w2, 14); | 
| 153 | 0 |     R31(b1, c1, d1, e1, a1, w13, 5); | 
| 154 | 0 |     R32(b2, c2, d2, e2, a2, w10, 13); | 
| 155 | 0 |     R31(a1, b1, c1, d1, e1, w11, 12); | 
| 156 | 0 |     R32(a2, b2, c2, d2, e2, w0, 13); | 
| 157 | 0 |     R31(e1, a1, b1, c1, d1, w5, 7); | 
| 158 | 0 |     R32(e2, a2, b2, c2, d2, w4, 7); | 
| 159 | 0 |     R31(d1, e1, a1, b1, c1, w12, 5); | 
| 160 | 0 |     R32(d2, e2, a2, b2, c2, w13, 5); | 
| 161 |  | 
 | 
| 162 | 0 |     R41(c1, d1, e1, a1, b1, w1, 11); | 
| 163 | 0 |     R42(c2, d2, e2, a2, b2, w8, 15); | 
| 164 | 0 |     R41(b1, c1, d1, e1, a1, w9, 12); | 
| 165 | 0 |     R42(b2, c2, d2, e2, a2, w6, 5); | 
| 166 | 0 |     R41(a1, b1, c1, d1, e1, w11, 14); | 
| 167 | 0 |     R42(a2, b2, c2, d2, e2, w4, 8); | 
| 168 | 0 |     R41(e1, a1, b1, c1, d1, w10, 15); | 
| 169 | 0 |     R42(e2, a2, b2, c2, d2, w1, 11); | 
| 170 | 0 |     R41(d1, e1, a1, b1, c1, w0, 14); | 
| 171 | 0 |     R42(d2, e2, a2, b2, c2, w3, 14); | 
| 172 | 0 |     R41(c1, d1, e1, a1, b1, w8, 15); | 
| 173 | 0 |     R42(c2, d2, e2, a2, b2, w11, 14); | 
| 174 | 0 |     R41(b1, c1, d1, e1, a1, w12, 9); | 
| 175 | 0 |     R42(b2, c2, d2, e2, a2, w15, 6); | 
| 176 | 0 |     R41(a1, b1, c1, d1, e1, w4, 8); | 
| 177 | 0 |     R42(a2, b2, c2, d2, e2, w0, 14); | 
| 178 | 0 |     R41(e1, a1, b1, c1, d1, w13, 9); | 
| 179 | 0 |     R42(e2, a2, b2, c2, d2, w5, 6); | 
| 180 | 0 |     R41(d1, e1, a1, b1, c1, w3, 14); | 
| 181 | 0 |     R42(d2, e2, a2, b2, c2, w12, 9); | 
| 182 | 0 |     R41(c1, d1, e1, a1, b1, w7, 5); | 
| 183 | 0 |     R42(c2, d2, e2, a2, b2, w2, 12); | 
| 184 | 0 |     R41(b1, c1, d1, e1, a1, w15, 6); | 
| 185 | 0 |     R42(b2, c2, d2, e2, a2, w13, 9); | 
| 186 | 0 |     R41(a1, b1, c1, d1, e1, w14, 8); | 
| 187 | 0 |     R42(a2, b2, c2, d2, e2, w9, 12); | 
| 188 | 0 |     R41(e1, a1, b1, c1, d1, w5, 6); | 
| 189 | 0 |     R42(e2, a2, b2, c2, d2, w7, 5); | 
| 190 | 0 |     R41(d1, e1, a1, b1, c1, w6, 5); | 
| 191 | 0 |     R42(d2, e2, a2, b2, c2, w10, 15); | 
| 192 | 0 |     R41(c1, d1, e1, a1, b1, w2, 12); | 
| 193 | 0 |     R42(c2, d2, e2, a2, b2, w14, 8); | 
| 194 |  | 
 | 
| 195 | 0 |     R51(b1, c1, d1, e1, a1, w4, 9); | 
| 196 | 0 |     R52(b2, c2, d2, e2, a2, w12, 8); | 
| 197 | 0 |     R51(a1, b1, c1, d1, e1, w0, 15); | 
| 198 | 0 |     R52(a2, b2, c2, d2, e2, w15, 5); | 
| 199 | 0 |     R51(e1, a1, b1, c1, d1, w5, 5); | 
| 200 | 0 |     R52(e2, a2, b2, c2, d2, w10, 12); | 
| 201 | 0 |     R51(d1, e1, a1, b1, c1, w9, 11); | 
| 202 | 0 |     R52(d2, e2, a2, b2, c2, w4, 9); | 
| 203 | 0 |     R51(c1, d1, e1, a1, b1, w7, 6); | 
| 204 | 0 |     R52(c2, d2, e2, a2, b2, w1, 12); | 
| 205 | 0 |     R51(b1, c1, d1, e1, a1, w12, 8); | 
| 206 | 0 |     R52(b2, c2, d2, e2, a2, w5, 5); | 
| 207 | 0 |     R51(a1, b1, c1, d1, e1, w2, 13); | 
| 208 | 0 |     R52(a2, b2, c2, d2, e2, w8, 14); | 
| 209 | 0 |     R51(e1, a1, b1, c1, d1, w10, 12); | 
| 210 | 0 |     R52(e2, a2, b2, c2, d2, w7, 6); | 
| 211 | 0 |     R51(d1, e1, a1, b1, c1, w14, 5); | 
| 212 | 0 |     R52(d2, e2, a2, b2, c2, w6, 8); | 
| 213 | 0 |     R51(c1, d1, e1, a1, b1, w1, 12); | 
| 214 | 0 |     R52(c2, d2, e2, a2, b2, w2, 13); | 
| 215 | 0 |     R51(b1, c1, d1, e1, a1, w3, 13); | 
| 216 | 0 |     R52(b2, c2, d2, e2, a2, w13, 6); | 
| 217 | 0 |     R51(a1, b1, c1, d1, e1, w8, 14); | 
| 218 | 0 |     R52(a2, b2, c2, d2, e2, w14, 5); | 
| 219 | 0 |     R51(e1, a1, b1, c1, d1, w11, 11); | 
| 220 | 0 |     R52(e2, a2, b2, c2, d2, w0, 15); | 
| 221 | 0 |     R51(d1, e1, a1, b1, c1, w6, 8); | 
| 222 | 0 |     R52(d2, e2, a2, b2, c2, w3, 13); | 
| 223 | 0 |     R51(c1, d1, e1, a1, b1, w15, 5); | 
| 224 | 0 |     R52(c2, d2, e2, a2, b2, w9, 11); | 
| 225 | 0 |     R51(b1, c1, d1, e1, a1, w13, 6); | 
| 226 | 0 |     R52(b2, c2, d2, e2, a2, w11, 11); | 
| 227 |  | 
 | 
| 228 | 0 |     uint32_t t = s[0]; | 
| 229 | 0 |     s[0] = s[1] + c1 + d2; | 
| 230 | 0 |     s[1] = s[2] + d1 + e2; | 
| 231 | 0 |     s[2] = s[3] + e1 + a2; | 
| 232 | 0 |     s[3] = s[4] + a1 + b2; | 
| 233 | 0 |     s[4] = t + b1 + c2; | 
| 234 | 0 | } | 
| 235 |  |  | 
| 236 |  | } // namespace ripemd160 | 
| 237 |  |  | 
| 238 |  | } // namespace | 
| 239 |  |  | 
| 240 |  | ////// RIPEMD160 | 
| 241 |  |  | 
| 242 |  | CRIPEMD160::CRIPEMD160() | 
| 243 | 0 | { | 
| 244 | 0 |     ripemd160::Initialize(s); | 
| 245 | 0 | } | 
| 246 |  |  | 
| 247 |  | CRIPEMD160& CRIPEMD160::Write(const unsigned char* data, size_t len) | 
| 248 | 0 | { | 
| 249 | 0 |     const unsigned char* end = data + len; | 
| 250 | 0 |     size_t bufsize = bytes % 64; | 
| 251 | 0 |     if (bufsize && bufsize + len >= 64) { | 
| 252 |  |         // Fill the buffer, and process it. | 
| 253 | 0 |         memcpy(buf + bufsize, data, 64 - bufsize); | 
| 254 | 0 |         bytes += 64 - bufsize; | 
| 255 | 0 |         data += 64 - bufsize; | 
| 256 | 0 |         ripemd160::Transform(s, buf); | 
| 257 | 0 |         bufsize = 0; | 
| 258 | 0 |     } | 
| 259 | 0 |     while (end - data >= 64) { | 
| 260 |  |         // Process full chunks directly from the source. | 
| 261 | 0 |         ripemd160::Transform(s, data); | 
| 262 | 0 |         bytes += 64; | 
| 263 | 0 |         data += 64; | 
| 264 | 0 |     } | 
| 265 | 0 |     if (end > data) { | 
| 266 |  |         // Fill the buffer with what remains. | 
| 267 | 0 |         memcpy(buf + bufsize, data, end - data); | 
| 268 | 0 |         bytes += end - data; | 
| 269 | 0 |     } | 
| 270 | 0 |     return *this; | 
| 271 | 0 | } | 
| 272 |  |  | 
| 273 |  | void CRIPEMD160::Finalize(unsigned char hash[OUTPUT_SIZE]) | 
| 274 | 0 | { | 
| 275 | 0 |     static const unsigned char pad[64] = {0x80}; | 
| 276 | 0 |     unsigned char sizedesc[8]; | 
| 277 | 0 |     WriteLE64(sizedesc, bytes << 3); | 
| 278 | 0 |     Write(pad, 1 + ((119 - (bytes % 64)) % 64)); | 
| 279 | 0 |     Write(sizedesc, 8); | 
| 280 | 0 |     WriteLE32(hash, s[0]); | 
| 281 | 0 |     WriteLE32(hash + 4, s[1]); | 
| 282 | 0 |     WriteLE32(hash + 8, s[2]); | 
| 283 | 0 |     WriteLE32(hash + 12, s[3]); | 
| 284 | 0 |     WriteLE32(hash + 16, s[4]); | 
| 285 | 0 | } | 
| 286 |  |  | 
| 287 |  | CRIPEMD160& CRIPEMD160::Reset() | 
| 288 | 0 | { | 
| 289 | 0 |     bytes = 0; | 
| 290 | 0 |     ripemd160::Initialize(s); | 
| 291 | 0 |     return *this; | 
| 292 | 0 | } |