/root/bitcoin/src/crypto/muhash.cpp
| Line | Count | Source | 
| 1 |  | // Copyright (c) 2017-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/muhash.h> | 
| 6 |  |  | 
| 7 |  | #include <crypto/chacha20.h> | 
| 8 |  | #include <crypto/common.h> | 
| 9 |  | #include <hash.h> | 
| 10 |  | #include <util/check.h> | 
| 11 |  |  | 
| 12 |  | #include <bit> | 
| 13 |  | #include <cassert> | 
| 14 |  | #include <cstdio> | 
| 15 |  | #include <limits> | 
| 16 |  |  | 
| 17 |  | namespace { | 
| 18 |  |  | 
| 19 |  | using limb_t = Num3072::limb_t; | 
| 20 |  | using signed_limb_t = Num3072::signed_limb_t; | 
| 21 |  | using double_limb_t = Num3072::double_limb_t; | 
| 22 |  | using signed_double_limb_t = Num3072::signed_double_limb_t; | 
| 23 |  | constexpr int LIMB_SIZE = Num3072::LIMB_SIZE; | 
| 24 |  | constexpr int SIGNED_LIMB_SIZE = Num3072::SIGNED_LIMB_SIZE; | 
| 25 |  | constexpr int LIMBS = Num3072::LIMBS; | 
| 26 |  | constexpr int SIGNED_LIMBS = Num3072::SIGNED_LIMBS; | 
| 27 |  | constexpr int FINAL_LIMB_POSITION = 3072 / SIGNED_LIMB_SIZE; | 
| 28 |  | constexpr int FINAL_LIMB_MODULUS_BITS = 3072 % SIGNED_LIMB_SIZE; | 
| 29 |  | constexpr limb_t MAX_LIMB = (limb_t)(-1); | 
| 30 |  | constexpr limb_t MAX_SIGNED_LIMB = (((limb_t)1) << SIGNED_LIMB_SIZE) - 1; | 
| 31 |  | /** 2^3072 - 1103717, the largest 3072-bit safe prime number, is used as the modulus. */ | 
| 32 |  | constexpr limb_t MAX_PRIME_DIFF = 1103717; | 
| 33 |  | /** The modular inverse of (2**3072 - MAX_PRIME_DIFF) mod (MAX_SIGNED_LIMB + 1). */ | 
| 34 |  | constexpr limb_t MODULUS_INVERSE = limb_t(0x70a1421da087d93); | 
| 35 |  |  | 
| 36 |  |  | 
| 37 |  | /** Extract the lowest limb of [c0,c1,c2] into n, and left shift the number by 1 limb. */ | 
| 38 |  | inline void extract3(limb_t& c0, limb_t& c1, limb_t& c2, limb_t& n) | 
| 39 | 0 | { | 
| 40 | 0 |     n = c0; | 
| 41 | 0 |     c0 = c1; | 
| 42 | 0 |     c1 = c2; | 
| 43 | 0 |     c2 = 0; | 
| 44 | 0 | } | 
| 45 |  |  | 
| 46 |  | /** [c0,c1] = a * b */ | 
| 47 |  | inline void mul(limb_t& c0, limb_t& c1, const limb_t& a, const limb_t& b) | 
| 48 | 0 | { | 
| 49 | 0 |     double_limb_t t = (double_limb_t)a * b; | 
| 50 | 0 |     c1 = t >> LIMB_SIZE; | 
| 51 | 0 |     c0 = t; | 
| 52 | 0 | } | 
| 53 |  |  | 
| 54 |  | /* [c0,c1,c2] += n * [d0,d1,d2]. c2 is 0 initially */ | 
| 55 |  | inline void mulnadd3(limb_t& c0, limb_t& c1, limb_t& c2, limb_t& d0, limb_t& d1, limb_t& d2, const limb_t& n) | 
| 56 | 0 | { | 
| 57 | 0 |     double_limb_t t = (double_limb_t)d0 * n + c0; | 
| 58 | 0 |     c0 = t; | 
| 59 | 0 |     t >>= LIMB_SIZE; | 
| 60 | 0 |     t += (double_limb_t)d1 * n + c1; | 
| 61 | 0 |     c1 = t; | 
| 62 | 0 |     t >>= LIMB_SIZE; | 
| 63 | 0 |     c2 = t + d2 * n; | 
| 64 | 0 | } | 
| 65 |  |  | 
| 66 |  | /* [c0,c1] *= n */ | 
| 67 |  | inline void muln2(limb_t& c0, limb_t& c1, const limb_t& n) | 
| 68 | 0 | { | 
| 69 | 0 |     double_limb_t t = (double_limb_t)c0 * n; | 
| 70 | 0 |     c0 = t; | 
| 71 | 0 |     t >>= LIMB_SIZE; | 
| 72 | 0 |     t += (double_limb_t)c1 * n; | 
| 73 | 0 |     c1 = t; | 
| 74 | 0 | } | 
| 75 |  |  | 
| 76 |  | /** [c0,c1,c2] += a * b */ | 
| 77 |  | inline void muladd3(limb_t& c0, limb_t& c1, limb_t& c2, const limb_t& a, const limb_t& b) | 
| 78 | 0 | { | 
| 79 | 0 |     double_limb_t t = (double_limb_t)a * b; | 
| 80 | 0 |     limb_t th = t >> LIMB_SIZE; | 
| 81 | 0 |     limb_t tl = t; | 
| 82 |  | 
 | 
| 83 | 0 |     c0 += tl; | 
| 84 | 0 |     th += (c0 < tl) ? 1 : 0; | 
| 85 | 0 |     c1 += th; | 
| 86 | 0 |     c2 += (c1 < th) ? 1 : 0; | 
| 87 | 0 | } | 
| 88 |  |  | 
| 89 |  | /** | 
| 90 |  |  * Add limb a to [c0,c1]: [c0,c1] += a. Then extract the lowest | 
| 91 |  |  * limb of [c0,c1] into n, and left shift the number by 1 limb. | 
| 92 |  |  * */ | 
| 93 |  | inline void addnextract2(limb_t& c0, limb_t& c1, const limb_t& a, limb_t& n) | 
| 94 | 0 | { | 
| 95 | 0 |     limb_t c2 = 0; | 
| 96 |  |  | 
| 97 |  |     // add | 
| 98 | 0 |     c0 += a; | 
| 99 | 0 |     if (c0 < a) { | 
| 100 | 0 |         c1 += 1; | 
| 101 |  |  | 
| 102 |  |         // Handle case when c1 has overflown | 
| 103 | 0 |         if (c1 == 0) c2 = 1; | 
| 104 | 0 |     } | 
| 105 |  |  | 
| 106 |  |     // extract | 
| 107 | 0 |     n = c0; | 
| 108 | 0 |     c0 = c1; | 
| 109 | 0 |     c1 = c2; | 
| 110 | 0 | } | 
| 111 |  |  | 
| 112 |  | } // namespace | 
| 113 |  |  | 
| 114 |  | /** Indicates whether d is larger than the modulus. */ | 
| 115 |  | bool Num3072::IsOverflow() const | 
| 116 | 0 | { | 
| 117 | 0 |     if (this->limbs[0] <= std::numeric_limits<limb_t>::max() - MAX_PRIME_DIFF) return false; | 
| 118 | 0 |     for (int i = 1; i < LIMBS; ++i) { | 
| 119 | 0 |         if (this->limbs[i] != std::numeric_limits<limb_t>::max()) return false; | 
| 120 | 0 |     } | 
| 121 | 0 |     return true; | 
| 122 | 0 | } | 
| 123 |  |  | 
| 124 |  | void Num3072::FullReduce() | 
| 125 | 0 | { | 
| 126 | 0 |     limb_t c0 = MAX_PRIME_DIFF; | 
| 127 | 0 |     limb_t c1 = 0; | 
| 128 | 0 |     for (int i = 0; i < LIMBS; ++i) { | 
| 129 | 0 |         addnextract2(c0, c1, this->limbs[i], this->limbs[i]); | 
| 130 | 0 |     } | 
| 131 | 0 | } | 
| 132 |  |  | 
| 133 |  | namespace { | 
| 134 |  | /** A type representing a number in signed limb representation. */ | 
| 135 |  | struct Num3072Signed | 
| 136 |  | { | 
| 137 |  |     /** The represented value is sum(limbs[i]*2^(SIGNED_LIMB_SIZE*i), i=0..SIGNED_LIMBS-1). | 
| 138 |  |      *  Note that limbs may be negative, or exceed 2^SIGNED_LIMB_SIZE-1. */ | 
| 139 |  |     signed_limb_t limbs[SIGNED_LIMBS]; | 
| 140 |  |  | 
| 141 |  |     /** Construct a Num3072Signed with value 0. */ | 
| 142 |  |     Num3072Signed() | 
| 143 | 0 |     { | 
| 144 | 0 |         memset(limbs, 0, sizeof(limbs)); | 
| 145 | 0 |     } | 
| 146 |  |  | 
| 147 |  |     /** Convert a Num3072 to a Num3072Signed. Output will be normalized and in | 
| 148 |  |      *  range 0..2^3072-1. */ | 
| 149 |  |     void FromNum3072(const Num3072& in) | 
| 150 | 0 |     { | 
| 151 | 0 |         double_limb_t c = 0; | 
| 152 | 0 |         int b = 0, outpos = 0; | 
| 153 | 0 |         for (int i = 0; i < LIMBS; ++i) { | 
| 154 | 0 |             c += double_limb_t{in.limbs[i]} << b; | 
| 155 | 0 |             b += LIMB_SIZE; | 
| 156 | 0 |             while (b >= SIGNED_LIMB_SIZE) { | 
| 157 | 0 |                 limbs[outpos++] = limb_t(c) & MAX_SIGNED_LIMB; | 
| 158 | 0 |                 c >>= SIGNED_LIMB_SIZE; | 
| 159 | 0 |                 b -= SIGNED_LIMB_SIZE; | 
| 160 | 0 |             } | 
| 161 | 0 |         } | 
| 162 | 0 |         Assume(outpos == SIGNED_LIMBS - 1); | 
| 163 | 0 |         limbs[SIGNED_LIMBS - 1] = c; | 
| 164 | 0 |         c >>= SIGNED_LIMB_SIZE; | 
| 165 | 0 |         Assume(c == 0); | 
| 166 | 0 |     } | 
| 167 |  |  | 
| 168 |  |     /** Convert a Num3072Signed to a Num3072. Input must be in range 0..modulus-1. */ | 
| 169 |  |     void ToNum3072(Num3072& out) const | 
| 170 | 0 |     { | 
| 171 | 0 |         double_limb_t c = 0; | 
| 172 | 0 |         int b = 0, outpos = 0; | 
| 173 | 0 |         for (int i = 0; i < SIGNED_LIMBS; ++i) { | 
| 174 | 0 |             c += double_limb_t(limbs[i]) << b; | 
| 175 | 0 |             b += SIGNED_LIMB_SIZE; | 
| 176 | 0 |             if (b >= LIMB_SIZE) { | 
| 177 | 0 |                 out.limbs[outpos++] = c; | 
| 178 | 0 |                 c >>= LIMB_SIZE; | 
| 179 | 0 |                 b -= LIMB_SIZE; | 
| 180 | 0 |             } | 
| 181 | 0 |         } | 
| 182 | 0 |         Assume(outpos == LIMBS); | 
| 183 | 0 |         Assume(c == 0); | 
| 184 | 0 |     } | 
| 185 |  |  | 
| 186 |  |     /** Take a Num3072Signed in range 1-2*2^3072..2^3072-1, and: | 
| 187 |  |      *  - optionally negate it (if negate is true) | 
| 188 |  |      *  - reduce it modulo the modulus (2^3072 - MAX_PRIME_DIFF) | 
| 189 |  |      *  - produce output with all limbs in range 0..2^SIGNED_LIMB_SIZE-1 | 
| 190 |  |      */ | 
| 191 |  |     void Normalize(bool negate) | 
| 192 | 0 |     { | 
| 193 |  |         // Add modulus if this was negative. This brings the range of *this to 1-2^3072..2^3072-1. | 
| 194 | 0 |         signed_limb_t cond_add = limbs[SIGNED_LIMBS-1] >> (LIMB_SIZE-1); // -1 if this is negative; 0 otherwise | 
| 195 | 0 |         limbs[0] += signed_limb_t(-MAX_PRIME_DIFF) & cond_add; | 
| 196 | 0 |         limbs[FINAL_LIMB_POSITION] += (signed_limb_t(1) << FINAL_LIMB_MODULUS_BITS) & cond_add; | 
| 197 |  |         // Next negate all limbs if negate was set. This does not change the range of *this. | 
| 198 | 0 |         signed_limb_t cond_negate = -signed_limb_t(negate); // -1 if this negate is true; 0 otherwise | 
| 199 | 0 |         for (int i = 0; i < SIGNED_LIMBS; ++i) { | 
| 200 | 0 |             limbs[i] = (limbs[i] ^ cond_negate) - cond_negate; | 
| 201 | 0 |         } | 
| 202 |  |         // Perform carry (make all limbs except the top one be in range 0..2^SIGNED_LIMB_SIZE-1). | 
| 203 | 0 |         for (int i = 0; i < SIGNED_LIMBS - 1; ++i) { | 
| 204 | 0 |             limbs[i + 1] += limbs[i] >> SIGNED_LIMB_SIZE; | 
| 205 | 0 |             limbs[i] &= MAX_SIGNED_LIMB; | 
| 206 | 0 |         } | 
| 207 |  |         // Again add modulus if *this was negative. This brings the range of *this to 0..2^3072-1. | 
| 208 | 0 |         cond_add = limbs[SIGNED_LIMBS-1] >> (LIMB_SIZE-1); // -1 if this is negative; 0 otherwise | 
| 209 | 0 |         limbs[0] += signed_limb_t(-MAX_PRIME_DIFF) & cond_add; | 
| 210 | 0 |         limbs[FINAL_LIMB_POSITION] += (signed_limb_t(1) << FINAL_LIMB_MODULUS_BITS) & cond_add; | 
| 211 |  |         // Perform another carry. Now all limbs are in range 0..2^SIGNED_LIMB_SIZE-1. | 
| 212 | 0 |         for (int i = 0; i < SIGNED_LIMBS - 1; ++i) { | 
| 213 | 0 |             limbs[i + 1] += limbs[i] >> SIGNED_LIMB_SIZE; | 
| 214 | 0 |             limbs[i] &= MAX_SIGNED_LIMB; | 
| 215 | 0 |         } | 
| 216 | 0 |     } | 
| 217 |  | }; | 
| 218 |  |  | 
| 219 |  | /** 2x2 transformation matrix with signed_limb_t elements. */ | 
| 220 |  | struct SignedMatrix | 
| 221 |  | { | 
| 222 |  |     signed_limb_t u, v, q, r; | 
| 223 |  | }; | 
| 224 |  |  | 
| 225 |  | /** Compute the transformation matrix for SIGNED_LIMB_SIZE divsteps. | 
| 226 |  |  * | 
| 227 |  |  * eta: initial eta value | 
| 228 |  |  * f:   bottom SIGNED_LIMB_SIZE bits of initial f value | 
| 229 |  |  * g:   bottom SIGNED_LIMB_SIZE bits of initial g value | 
| 230 |  |  * out: resulting transformation matrix, scaled by 2^SIGNED_LIMB_SIZE | 
| 231 |  |  * return: eta value after SIGNED_LIMB_SIZE divsteps | 
| 232 |  |  */ | 
| 233 |  | inline limb_t ComputeDivstepMatrix(signed_limb_t eta, limb_t f, limb_t g, SignedMatrix& out) | 
| 234 | 0 | { | 
| 235 |  |     /** inv256[i] = -1/(2*i+1) (mod 256) */ | 
| 236 | 0 |     static const uint8_t NEGINV256[128] = { | 
| 237 | 0 |         0xFF, 0x55, 0x33, 0x49, 0xC7, 0x5D, 0x3B, 0x11, 0x0F, 0xE5, 0xC3, 0x59, | 
| 238 | 0 |         0xD7, 0xED, 0xCB, 0x21, 0x1F, 0x75, 0x53, 0x69, 0xE7, 0x7D, 0x5B, 0x31, | 
| 239 | 0 |         0x2F, 0x05, 0xE3, 0x79, 0xF7, 0x0D, 0xEB, 0x41, 0x3F, 0x95, 0x73, 0x89, | 
| 240 | 0 |         0x07, 0x9D, 0x7B, 0x51, 0x4F, 0x25, 0x03, 0x99, 0x17, 0x2D, 0x0B, 0x61, | 
| 241 | 0 |         0x5F, 0xB5, 0x93, 0xA9, 0x27, 0xBD, 0x9B, 0x71, 0x6F, 0x45, 0x23, 0xB9, | 
| 242 | 0 |         0x37, 0x4D, 0x2B, 0x81, 0x7F, 0xD5, 0xB3, 0xC9, 0x47, 0xDD, 0xBB, 0x91, | 
| 243 | 0 |         0x8F, 0x65, 0x43, 0xD9, 0x57, 0x6D, 0x4B, 0xA1, 0x9F, 0xF5, 0xD3, 0xE9, | 
| 244 | 0 |         0x67, 0xFD, 0xDB, 0xB1, 0xAF, 0x85, 0x63, 0xF9, 0x77, 0x8D, 0x6B, 0xC1, | 
| 245 | 0 |         0xBF, 0x15, 0xF3, 0x09, 0x87, 0x1D, 0xFB, 0xD1, 0xCF, 0xA5, 0x83, 0x19, | 
| 246 | 0 |         0x97, 0xAD, 0x8B, 0xE1, 0xDF, 0x35, 0x13, 0x29, 0xA7, 0x3D, 0x1B, 0xF1, | 
| 247 | 0 |         0xEF, 0xC5, 0xA3, 0x39, 0xB7, 0xCD, 0xAB, 0x01 | 
| 248 | 0 |     }; | 
| 249 |  |     // Coefficients of returned SignedMatrix; starts off as identity matrix. */ | 
| 250 | 0 |     limb_t u = 1, v = 0, q = 0, r = 1; | 
| 251 |  |     // The number of divsteps still left. | 
| 252 | 0 |     int i = SIGNED_LIMB_SIZE; | 
| 253 | 0 |     while (true) { | 
| 254 |  |         /* Use a sentinel bit to count zeros only up to i. */ | 
| 255 | 0 |         int zeros = std::countr_zero(g | (MAX_LIMB << i)); | 
| 256 |  |         /* Perform zeros divsteps at once; they all just divide g by two. */ | 
| 257 | 0 |         g >>= zeros; | 
| 258 | 0 |         u <<= zeros; | 
| 259 | 0 |         v <<= zeros; | 
| 260 | 0 |         eta -= zeros; | 
| 261 | 0 |         i -= zeros; | 
| 262 |  |          /* We're done once we've performed SIGNED_LIMB_SIZE divsteps. */ | 
| 263 | 0 |         if (i == 0) break; | 
| 264 |  |         /* If eta is negative, negate it and replace f,g with g,-f. */ | 
| 265 | 0 |         if (eta < 0) { | 
| 266 | 0 |             limb_t tmp; | 
| 267 | 0 |             eta = -eta; | 
| 268 | 0 |             tmp = f; f = g; g = -tmp; | 
| 269 | 0 |             tmp = u; u = q; q = -tmp; | 
| 270 | 0 |             tmp = v; v = r; r = -tmp; | 
| 271 | 0 |         } | 
| 272 |  |         /* eta is now >= 0. In what follows we're going to cancel out the bottom bits of g. No more | 
| 273 |  |          * than i can be cancelled out (as we'd be done before that point), and no more than eta+1 | 
| 274 |  |          * can be done as its sign will flip once that happens. */ | 
| 275 | 0 |         int limit = ((int)eta + 1) > i ? i : ((int)eta + 1); | 
| 276 |  |         /* m is a mask for the bottom min(limit, 8) bits (our table only supports 8 bits). */ | 
| 277 | 0 |         limb_t m = (MAX_LIMB >> (LIMB_SIZE - limit)) & 255U; | 
| 278 |  |         /* Find what multiple of f must be added to g to cancel its bottom min(limit, 8) bits. */ | 
| 279 | 0 |         limb_t w = (g * NEGINV256[(f >> 1) & 127]) & m; | 
| 280 |  |         /* Do so. */ | 
| 281 | 0 |         g += f * w; | 
| 282 | 0 |         q += u * w; | 
| 283 | 0 |         r += v * w; | 
| 284 | 0 |     } | 
| 285 | 0 |     out.u = (signed_limb_t)u; | 
| 286 | 0 |     out.v = (signed_limb_t)v; | 
| 287 | 0 |     out.q = (signed_limb_t)q; | 
| 288 | 0 |     out.r = (signed_limb_t)r; | 
| 289 | 0 |     return eta; | 
| 290 | 0 | } | 
| 291 |  |  | 
| 292 |  | /** Apply matrix t/2^SIGNED_LIMB_SIZE to vector [d,e], modulo modulus. | 
| 293 |  |  * | 
| 294 |  |  * On input and output, d and e are in range 1-2*modulus..modulus-1. | 
| 295 |  |  */ | 
| 296 |  | inline void UpdateDE(Num3072Signed& d, Num3072Signed& e, const SignedMatrix& t) | 
| 297 | 0 | { | 
| 298 | 0 |     const signed_limb_t u = t.u, v=t.v, q=t.q, r=t.r; | 
| 299 |  |  | 
| 300 |  |     /* [md,me] start as zero; plus [u,q] if d is negative; plus [v,r] if e is negative. */ | 
| 301 | 0 |     signed_limb_t sd = d.limbs[SIGNED_LIMBS - 1] >> (LIMB_SIZE - 1); | 
| 302 | 0 |     signed_limb_t se = e.limbs[SIGNED_LIMBS - 1] >> (LIMB_SIZE - 1); | 
| 303 | 0 |     signed_limb_t md = (u & sd) + (v & se); | 
| 304 | 0 |     signed_limb_t me = (q & sd) + (r & se); | 
| 305 |  |     /* Begin computing t*[d,e]. */ | 
| 306 | 0 |     signed_limb_t di = d.limbs[0], ei = e.limbs[0]; | 
| 307 | 0 |     signed_double_limb_t cd = (signed_double_limb_t)u * di + (signed_double_limb_t)v * ei; | 
| 308 | 0 |     signed_double_limb_t ce = (signed_double_limb_t)q * di + (signed_double_limb_t)r * ei; | 
| 309 |  |     /* Correct md,me so that t*[d,e]+modulus*[md,me] has SIGNED_LIMB_SIZE zero bottom bits. */ | 
| 310 | 0 |     md -= (MODULUS_INVERSE * limb_t(cd) + md) & MAX_SIGNED_LIMB; | 
| 311 | 0 |     me -= (MODULUS_INVERSE * limb_t(ce) + me) & MAX_SIGNED_LIMB; | 
| 312 |  |     /* Update the beginning of computation for t*[d,e]+modulus*[md,me] now md,me are known. */ | 
| 313 | 0 |     cd -= (signed_double_limb_t)1103717 * md; | 
| 314 | 0 |     ce -= (signed_double_limb_t)1103717 * me; | 
| 315 |  |     /* Verify that the low SIGNED_LIMB_SIZE bits of the computation are indeed zero, and then throw them away. */ | 
| 316 | 0 |     Assume((cd & MAX_SIGNED_LIMB) == 0); | 
| 317 | 0 |     Assume((ce & MAX_SIGNED_LIMB) == 0); | 
| 318 | 0 |     cd >>= SIGNED_LIMB_SIZE; | 
| 319 | 0 |     ce >>= SIGNED_LIMB_SIZE; | 
| 320 |  |     /* Now iteratively compute limb i=1..SIGNED_LIMBS-2 of t*[d,e]+modulus*[md,me], and store them in output | 
| 321 |  |      * limb i-1 (shifting down by SIGNED_LIMB_SIZE bits). The corresponding limbs in modulus are all zero, | 
| 322 |  |      * so modulus/md/me are not actually involved here. */ | 
| 323 | 0 |     for (int i = 1; i < SIGNED_LIMBS - 1; ++i) { | 
| 324 | 0 |         di = d.limbs[i]; | 
| 325 | 0 |         ei = e.limbs[i]; | 
| 326 | 0 |         cd += (signed_double_limb_t)u * di + (signed_double_limb_t)v * ei; | 
| 327 | 0 |         ce += (signed_double_limb_t)q * di + (signed_double_limb_t)r * ei; | 
| 328 | 0 |         d.limbs[i - 1] = (signed_limb_t)cd & MAX_SIGNED_LIMB; cd >>= SIGNED_LIMB_SIZE; | 
| 329 | 0 |         e.limbs[i - 1] = (signed_limb_t)ce & MAX_SIGNED_LIMB; ce >>= SIGNED_LIMB_SIZE; | 
| 330 | 0 |     } | 
| 331 |  |     /* Compute limb SIGNED_LIMBS-1 of t*[d,e]+modulus*[md,me], and store it in output limb SIGNED_LIMBS-2. */ | 
| 332 | 0 |     di = d.limbs[SIGNED_LIMBS - 1]; | 
| 333 | 0 |     ei = e.limbs[SIGNED_LIMBS - 1]; | 
| 334 | 0 |     cd += (signed_double_limb_t)u * di + (signed_double_limb_t)v * ei; | 
| 335 | 0 |     ce += (signed_double_limb_t)q * di + (signed_double_limb_t)r * ei; | 
| 336 | 0 |     cd += (signed_double_limb_t)md << FINAL_LIMB_MODULUS_BITS; | 
| 337 | 0 |     ce += (signed_double_limb_t)me << FINAL_LIMB_MODULUS_BITS; | 
| 338 | 0 |     d.limbs[SIGNED_LIMBS - 2] = (signed_limb_t)cd & MAX_SIGNED_LIMB; cd >>= SIGNED_LIMB_SIZE; | 
| 339 | 0 |     e.limbs[SIGNED_LIMBS - 2] = (signed_limb_t)ce & MAX_SIGNED_LIMB; ce >>= SIGNED_LIMB_SIZE; | 
| 340 |  |     /* What remains goes into output limb SINGED_LIMBS-1 */ | 
| 341 | 0 |     d.limbs[SIGNED_LIMBS - 1] = (signed_limb_t)cd; | 
| 342 | 0 |     e.limbs[SIGNED_LIMBS - 1] = (signed_limb_t)ce; | 
| 343 | 0 | } | 
| 344 |  |  | 
| 345 |  | /** Apply matrix t/2^SIGNED_LIMB_SIZE to vector (f,g). | 
| 346 |  |  * | 
| 347 |  |  * The matrix t must be chosen such that t*(f,g) results in multiples of 2^SIGNED_LIMB_SIZE. | 
| 348 |  |  * This is the case for matrices computed by ComputeDivstepMatrix(). | 
| 349 |  |  */ | 
| 350 |  | inline void UpdateFG(Num3072Signed& f, Num3072Signed& g, const SignedMatrix& t, int len) | 
| 351 | 0 | { | 
| 352 | 0 |     const signed_limb_t u = t.u, v=t.v, q=t.q, r=t.r; | 
| 353 |  | 
 | 
| 354 | 0 |     signed_limb_t fi, gi; | 
| 355 | 0 |     signed_double_limb_t cf, cg; | 
| 356 |  |     /* Start computing t*[f,g]. */ | 
| 357 | 0 |     fi = f.limbs[0]; | 
| 358 | 0 |     gi = g.limbs[0]; | 
| 359 | 0 |     cf = (signed_double_limb_t)u * fi + (signed_double_limb_t)v * gi; | 
| 360 | 0 |     cg = (signed_double_limb_t)q * fi + (signed_double_limb_t)r * gi; | 
| 361 |  |     /* Verify that the bottom SIGNED_LIMB_BITS bits of the result are zero, and then throw them away. */ | 
| 362 | 0 |     Assume((cf & MAX_SIGNED_LIMB) == 0); | 
| 363 | 0 |     Assume((cg & MAX_SIGNED_LIMB) == 0); | 
| 364 | 0 |     cf >>= SIGNED_LIMB_SIZE; | 
| 365 | 0 |     cg >>= SIGNED_LIMB_SIZE; | 
| 366 |  |     /* Now iteratively compute limb i=1..SIGNED_LIMBS-1 of t*[f,g], and store them in output limb i-1 (shifting | 
| 367 |  |      * down by SIGNED_LIMB_BITS bits). */ | 
| 368 | 0 |     for (int i = 1; i < len; ++i) { | 
| 369 | 0 |         fi = f.limbs[i]; | 
| 370 | 0 |         gi = g.limbs[i]; | 
| 371 | 0 |         cf += (signed_double_limb_t)u * fi + (signed_double_limb_t)v * gi; | 
| 372 | 0 |         cg += (signed_double_limb_t)q * fi + (signed_double_limb_t)r * gi; | 
| 373 | 0 |         f.limbs[i - 1] = (signed_limb_t)cf & MAX_SIGNED_LIMB; cf >>= SIGNED_LIMB_SIZE; | 
| 374 | 0 |         g.limbs[i - 1] = (signed_limb_t)cg & MAX_SIGNED_LIMB; cg >>= SIGNED_LIMB_SIZE; | 
| 375 | 0 |     } | 
| 376 |  |     /* What remains is limb SIGNED_LIMBS of t*[f,g]; store it as output limb SIGNED_LIMBS-1. */ | 
| 377 | 0 |     f.limbs[len - 1] = (signed_limb_t)cf; | 
| 378 | 0 |     g.limbs[len - 1] = (signed_limb_t)cg; | 
| 379 |  | 
 | 
| 380 | 0 | } | 
| 381 |  | } // namespace | 
| 382 |  |  | 
| 383 |  | Num3072 Num3072::GetInverse() const | 
| 384 | 0 | { | 
| 385 |  |     // Compute a modular inverse based on a variant of the safegcd algorithm: | 
| 386 |  |     // - Paper: https://gcd.cr.yp.to/papers.html | 
| 387 |  |     // - Inspired by this code in libsecp256k1: | 
| 388 |  |     //   https://github.com/bitcoin-core/secp256k1/blob/master/src/modinv32_impl.h | 
| 389 |  |     // - Explanation of the algorithm: | 
| 390 |  |     //   https://github.com/bitcoin-core/secp256k1/blob/master/doc/safegcd_implementation.md | 
| 391 |  |  | 
| 392 |  |     // Local variables d, e, f, g: | 
| 393 |  |     // - f and g are the variables whose gcd we compute (despite knowing the answer is 1): | 
| 394 |  |     //   - f is always odd, and initialized as modulus | 
| 395 |  |     //   - g is initialized as *this (called x in what follows) | 
| 396 |  |     // - d and e are the numbers for which at every step it is the case that: | 
| 397 |  |     //   - f = d * x mod modulus; d is initialized as 0 | 
| 398 |  |     //   - g = e * x mod modulus; e is initialized as 1 | 
| 399 | 0 |     Num3072Signed d, e, f, g; | 
| 400 | 0 |     e.limbs[0] = 1; | 
| 401 |  |     // F is initialized as modulus, which in signed limb representation can be expressed | 
| 402 |  |     // simply as 2^3072 + -MAX_PRIME_DIFF. | 
| 403 | 0 |     f.limbs[0] = -MAX_PRIME_DIFF; | 
| 404 | 0 |     f.limbs[FINAL_LIMB_POSITION] = ((limb_t)1) << FINAL_LIMB_MODULUS_BITS; | 
| 405 | 0 |     g.FromNum3072(*this); | 
| 406 | 0 |     int len = SIGNED_LIMBS; //!< The number of significant limbs in f and g | 
| 407 | 0 |     signed_limb_t eta = -1; //!< State to track knowledge about ratio of f and g | 
| 408 |  |     // Perform divsteps on [f,g] until g=0 is reached, keeping (d,e) synchronized with them. | 
| 409 | 0 |     while (true) { | 
| 410 |  |         // Compute transformation matrix t that represents the next SIGNED_LIMB_SIZE divsteps | 
| 411 |  |         // to apply. This can be computed from just the bottom limb of f and g, and eta. | 
| 412 | 0 |         SignedMatrix t; | 
| 413 | 0 |         eta = ComputeDivstepMatrix(eta, f.limbs[0], g.limbs[0], t); | 
| 414 |  |         // Apply that transformation matrix to the full [f,g] vector. | 
| 415 | 0 |         UpdateFG(f, g, t, len); | 
| 416 |  |         // Apply that transformation matrix to the full [d,e] vector (mod modulus). | 
| 417 | 0 |         UpdateDE(d, e, t); | 
| 418 |  |  | 
| 419 |  |         // Check if g is zero. | 
| 420 | 0 |         if (g.limbs[0] == 0) { | 
| 421 | 0 |             signed_limb_t cond = 0; | 
| 422 | 0 |             for (int j = 1; j < len; ++j) { | 
| 423 | 0 |                 cond |= g.limbs[j]; | 
| 424 | 0 |             } | 
| 425 |  |             // If so, we're done. | 
| 426 | 0 |             if (cond == 0) break; | 
| 427 | 0 |         } | 
| 428 |  |  | 
| 429 |  |         // Check if the top limbs of both f and g are both 0 or -1. | 
| 430 | 0 |         signed_limb_t fn = f.limbs[len - 1], gn = g.limbs[len - 1]; | 
| 431 | 0 |         signed_limb_t cond = ((signed_limb_t)len - 2) >> (LIMB_SIZE - 1); | 
| 432 | 0 |         cond |= fn ^ (fn >> (LIMB_SIZE - 1)); | 
| 433 | 0 |         cond |= gn ^ (gn >> (LIMB_SIZE - 1)); | 
| 434 | 0 |         if (cond == 0) { | 
| 435 |  |             // If so, drop the top limb, shrinking the size of f and g, by | 
| 436 |  |             // propagating the sign to the previous limb. | 
| 437 | 0 |             f.limbs[len - 2] |= (limb_t)f.limbs[len - 1] << SIGNED_LIMB_SIZE; | 
| 438 | 0 |             g.limbs[len - 2] |= (limb_t)g.limbs[len - 1] << SIGNED_LIMB_SIZE; | 
| 439 | 0 |             --len; | 
| 440 | 0 |         } | 
| 441 | 0 |     } | 
| 442 |  |     // At some point, [f,g] will have been rewritten into [f',0], such that gcd(f,g) = gcd(f',0). | 
| 443 |  |     // This is proven in the paper. As f started out being modulus, a prime number, we know that | 
| 444 |  |     // gcd is 1, and thus f' is 1 or -1. | 
| 445 | 0 |     Assume((f.limbs[0] & MAX_SIGNED_LIMB) == 1 || (f.limbs[0] & MAX_SIGNED_LIMB) == MAX_SIGNED_LIMB); | 
| 446 |  |     // As we've maintained the invariant that f = d * x mod modulus, we get d/f mod modulus is the | 
| 447 |  |     // modular inverse of x we're looking for. As f is 1 or -1, it is also true that d/f = d*f. | 
| 448 |  |     // Normalize d to prepare it for output, while negating it if f is negative. | 
| 449 | 0 |     d.Normalize(f.limbs[len - 1] >> (LIMB_SIZE  - 1)); | 
| 450 | 0 |     Num3072 ret; | 
| 451 | 0 |     d.ToNum3072(ret); | 
| 452 | 0 |     return ret; | 
| 453 | 0 | } | 
| 454 |  |  | 
| 455 |  | void Num3072::Multiply(const Num3072& a) | 
| 456 | 0 | { | 
| 457 | 0 |     limb_t c0 = 0, c1 = 0, c2 = 0; | 
| 458 | 0 |     Num3072 tmp; | 
| 459 |  |  | 
| 460 |  |     /* Compute limbs 0..N-2 of this*a into tmp, including one reduction. */ | 
| 461 | 0 |     for (int j = 0; j < LIMBS - 1; ++j) { | 
| 462 | 0 |         limb_t d0 = 0, d1 = 0, d2 = 0; | 
| 463 | 0 |         mul(d0, d1, this->limbs[1 + j], a.limbs[LIMBS + j - (1 + j)]); | 
| 464 | 0 |         for (int i = 2 + j; i < LIMBS; ++i) muladd3(d0, d1, d2, this->limbs[i], a.limbs[LIMBS + j - i]); | 
| 465 | 0 |         mulnadd3(c0, c1, c2, d0, d1, d2, MAX_PRIME_DIFF); | 
| 466 | 0 |         for (int i = 0; i < j + 1; ++i) muladd3(c0, c1, c2, this->limbs[i], a.limbs[j - i]); | 
| 467 | 0 |         extract3(c0, c1, c2, tmp.limbs[j]); | 
| 468 | 0 |     } | 
| 469 |  |  | 
| 470 |  |     /* Compute limb N-1 of a*b into tmp. */ | 
| 471 | 0 |     assert(c2 == 0); | 
| 472 | 0 |     for (int i = 0; i < LIMBS; ++i) muladd3(c0, c1, c2, this->limbs[i], a.limbs[LIMBS - 1 - i]); | 
| 473 | 0 |     extract3(c0, c1, c2, tmp.limbs[LIMBS - 1]); | 
| 474 |  |  | 
| 475 |  |     /* Perform a second reduction. */ | 
| 476 | 0 |     muln2(c0, c1, MAX_PRIME_DIFF); | 
| 477 | 0 |     for (int j = 0; j < LIMBS; ++j) { | 
| 478 | 0 |         addnextract2(c0, c1, tmp.limbs[j], this->limbs[j]); | 
| 479 | 0 |     } | 
| 480 |  | 
 | 
| 481 | 0 |     assert(c1 == 0); | 
| 482 | 0 |     assert(c0 == 0 || c0 == 1); | 
| 483 |  |  | 
| 484 |  |     /* Perform up to two more reductions if the internal state has already | 
| 485 |  |      * overflown the MAX of Num3072 or if it is larger than the modulus or | 
| 486 |  |      * if both are the case. | 
| 487 |  |      * */ | 
| 488 | 0 |     if (this->IsOverflow()) this->FullReduce(); | 
| 489 | 0 |     if (c0) this->FullReduce(); | 
| 490 | 0 | } | 
| 491 |  |  | 
| 492 |  | void Num3072::SetToOne() | 
| 493 | 0 | { | 
| 494 | 0 |     this->limbs[0] = 1; | 
| 495 | 0 |     for (int i = 1; i < LIMBS; ++i) this->limbs[i] = 0; | 
| 496 | 0 | } | 
| 497 |  |  | 
| 498 |  | void Num3072::Divide(const Num3072& a) | 
| 499 | 0 | { | 
| 500 | 0 |     if (this->IsOverflow()) this->FullReduce(); | 
| 501 |  | 
 | 
| 502 | 0 |     Num3072 inv{}; | 
| 503 | 0 |     if (a.IsOverflow()) { | 
| 504 | 0 |         Num3072 b = a; | 
| 505 | 0 |         b.FullReduce(); | 
| 506 | 0 |         inv = b.GetInverse(); | 
| 507 | 0 |     } else { | 
| 508 | 0 |         inv = a.GetInverse(); | 
| 509 | 0 |     } | 
| 510 |  | 
 | 
| 511 | 0 |     this->Multiply(inv); | 
| 512 | 0 |     if (this->IsOverflow()) this->FullReduce(); | 
| 513 | 0 | } | 
| 514 |  |  | 
| 515 | 0 | Num3072::Num3072(const unsigned char (&data)[BYTE_SIZE]) { | 
| 516 | 0 |     for (int i = 0; i < LIMBS; ++i) { | 
| 517 | 0 |         if (sizeof(limb_t) == 4) { | 
| 518 | 0 |             this->limbs[i] = ReadLE32(data + 4 * i); | 
| 519 | 0 |         } else if (sizeof(limb_t) == 8) { | 
| 520 | 0 |             this->limbs[i] = ReadLE64(data + 8 * i); | 
| 521 | 0 |         } | 
| 522 | 0 |     } | 
| 523 | 0 | } | 
| 524 |  |  | 
| 525 | 0 | void Num3072::ToBytes(unsigned char (&out)[BYTE_SIZE]) { | 
| 526 | 0 |     for (int i = 0; i < LIMBS; ++i) { | 
| 527 | 0 |         if (sizeof(limb_t) == 4) { | 
| 528 | 0 |             WriteLE32(out + i * 4, this->limbs[i]); | 
| 529 | 0 |         } else if (sizeof(limb_t) == 8) { | 
| 530 | 0 |             WriteLE64(out + i * 8, this->limbs[i]); | 
| 531 | 0 |         } | 
| 532 | 0 |     } | 
| 533 | 0 | } | 
| 534 |  |  | 
| 535 | 0 | Num3072 MuHash3072::ToNum3072(std::span<const unsigned char> in) { | 
| 536 | 0 |     unsigned char tmp[Num3072::BYTE_SIZE]; | 
| 537 |  | 
 | 
| 538 | 0 |     uint256 hashed_in{(HashWriter{} << in).GetSHA256()}; | 
| 539 | 0 |     static_assert(sizeof(tmp) % ChaCha20Aligned::BLOCKLEN == 0); | 
| 540 | 0 |     ChaCha20Aligned{MakeByteSpan(hashed_in)}.Keystream(MakeWritableByteSpan(tmp)); | 
| 541 | 0 |     Num3072 out{tmp}; | 
| 542 |  | 
 | 
| 543 | 0 |     return out; | 
| 544 | 0 | } | 
| 545 |  |  | 
| 546 |  | MuHash3072::MuHash3072(std::span<const unsigned char> in) noexcept | 
| 547 | 0 | { | 
| 548 | 0 |     m_numerator = ToNum3072(in); | 
| 549 | 0 | } | 
| 550 |  |  | 
| 551 |  | void MuHash3072::Finalize(uint256& out) noexcept | 
| 552 | 0 | { | 
| 553 | 0 |     m_numerator.Divide(m_denominator); | 
| 554 | 0 |     m_denominator.SetToOne();  // Needed to keep the MuHash object valid | 
| 555 |  | 
 | 
| 556 | 0 |     unsigned char data[Num3072::BYTE_SIZE]; | 
| 557 | 0 |     m_numerator.ToBytes(data); | 
| 558 |  | 
 | 
| 559 | 0 |     out = (HashWriter{} << data).GetSHA256(); | 
| 560 | 0 | } | 
| 561 |  |  | 
| 562 |  | MuHash3072& MuHash3072::operator*=(const MuHash3072& mul) noexcept | 
| 563 | 0 | { | 
| 564 | 0 |     m_numerator.Multiply(mul.m_numerator); | 
| 565 | 0 |     m_denominator.Multiply(mul.m_denominator); | 
| 566 | 0 |     return *this; | 
| 567 | 0 | } | 
| 568 |  |  | 
| 569 |  | MuHash3072& MuHash3072::operator/=(const MuHash3072& div) noexcept | 
| 570 | 0 | { | 
| 571 | 0 |     m_numerator.Multiply(div.m_denominator); | 
| 572 | 0 |     m_denominator.Multiply(div.m_numerator); | 
| 573 | 0 |     return *this; | 
| 574 | 0 | } | 
| 575 |  |  | 
| 576 | 0 | MuHash3072& MuHash3072::Insert(std::span<const unsigned char> in) noexcept { | 
| 577 | 0 |     m_numerator.Multiply(ToNum3072(in)); | 
| 578 | 0 |     return *this; | 
| 579 | 0 | } | 
| 580 |  |  | 
| 581 | 0 | MuHash3072& MuHash3072::Remove(std::span<const unsigned char> in) noexcept { | 
| 582 | 0 |     m_denominator.Multiply(ToNum3072(in)); | 
| 583 | 0 |     return *this; | 
| 584 | 0 | } |