Bitcoin ABC 0.32.4
P2P Digital Currency
muhash.cpp
Go to the documentation of this file.
1// Copyright (c) 2017-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/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 <cassert>
13#include <cstdio>
14#include <limits>
15
16namespace {
17
18using limb_t = Num3072::limb_t;
19using signed_limb_t = Num3072::signed_limb_t;
20using double_limb_t = Num3072::double_limb_t;
21using signed_double_limb_t = Num3072::signed_double_limb_t;
22constexpr int LIMB_SIZE = Num3072::LIMB_SIZE;
23constexpr int SIGNED_LIMB_SIZE = Num3072::SIGNED_LIMB_SIZE;
24constexpr int LIMBS = Num3072::LIMBS;
25constexpr int SIGNED_LIMBS = Num3072::SIGNED_LIMBS;
26constexpr int FINAL_LIMB_POSITION = 3072 / SIGNED_LIMB_SIZE;
27constexpr int FINAL_LIMB_MODULUS_BITS = 3072 % SIGNED_LIMB_SIZE;
28constexpr limb_t MAX_LIMB = (limb_t)(-1);
29constexpr limb_t MAX_SIGNED_LIMB = (((limb_t)1) << SIGNED_LIMB_SIZE) - 1;
34constexpr limb_t MAX_PRIME_DIFF = 1103717;
38constexpr limb_t MODULUS_INVERSE = limb_t(0x70a1421da087d93);
39
44inline void extract3(limb_t &c0, limb_t &c1, limb_t &c2, limb_t &n) {
45 n = c0;
46 c0 = c1;
47 c1 = c2;
48 c2 = 0;
49}
50
52inline void mul(limb_t &c0, limb_t &c1, const limb_t &a, const limb_t &b) {
53 double_limb_t t = (double_limb_t)a * b;
54 c1 = t >> LIMB_SIZE;
55 c0 = t;
56}
57
58/* [c0,c1,c2] += n * [d0,d1,d2]. c2 is 0 initially */
59inline void mulnadd3(limb_t &c0, limb_t &c1, limb_t &c2, limb_t &d0, limb_t &d1,
60 limb_t &d2, const limb_t &n) {
61 double_limb_t t = (double_limb_t)d0 * n + c0;
62 c0 = t;
63 t >>= LIMB_SIZE;
64 t += (double_limb_t)d1 * n + c1;
65 c1 = t;
66 t >>= LIMB_SIZE;
67 c2 = t + d2 * n;
68}
69
70/* [c0,c1] *= n */
71inline void muln2(limb_t &c0, limb_t &c1, const limb_t &n) {
72 double_limb_t t = (double_limb_t)c0 * n;
73 c0 = t;
74 t >>= LIMB_SIZE;
75 t += (double_limb_t)c1 * n;
76 c1 = t;
77}
78
80inline void muladd3(limb_t &c0, limb_t &c1, limb_t &c2, const limb_t &a,
81 const limb_t &b) {
82 double_limb_t t = (double_limb_t)a * b;
83 limb_t th = t >> LIMB_SIZE;
84 limb_t tl = t;
85
86 c0 += tl;
87 th += (c0 < tl) ? 1 : 0;
88 c1 += th;
89 c2 += (c1 < th) ? 1 : 0;
90}
91
96inline void addnextract2(limb_t &c0, limb_t &c1, const limb_t &a, limb_t &n) {
97 limb_t c2 = 0;
98
99 // add
100 c0 += a;
101 if (c0 < a) {
102 c1 += 1;
103
104 // Handle case when c1 has overflown
105 if (c1 == 0) {
106 c2 = 1;
107 }
108 }
109
110 // extract
111 n = c0;
112 c0 = c1;
113 c1 = c2;
114}
115
116} // namespace
117
120 if (this->limbs[0] <= std::numeric_limits<limb_t>::max() - MAX_PRIME_DIFF) {
121 return false;
122 }
123 for (int i = 1; i < LIMBS; ++i) {
124 if (this->limbs[i] != std::numeric_limits<limb_t>::max()) {
125 return false;
126 }
127 }
128 return true;
129}
130
132 limb_t c0 = MAX_PRIME_DIFF;
133 limb_t c1 = 0;
134 for (int i = 0; i < LIMBS; ++i) {
135 addnextract2(c0, c1, this->limbs[i], this->limbs[i]);
136 }
137}
138
139namespace {
141struct Num3072Signed {
147 signed_limb_t limbs[SIGNED_LIMBS];
148
150 Num3072Signed() { memset(limbs, 0, sizeof(limbs)); }
151
156 void FromNum3072(const Num3072 &in) {
157 double_limb_t c = 0;
158 int b = 0, outpos = 0;
159 for (int i = 0; i < LIMBS; ++i) {
160 c += double_limb_t{in.limbs[i]} << b;
161 b += LIMB_SIZE;
162 while (b >= SIGNED_LIMB_SIZE) {
163 limbs[outpos++] = limb_t(c) & MAX_SIGNED_LIMB;
164 c >>= SIGNED_LIMB_SIZE;
165 b -= SIGNED_LIMB_SIZE;
166 }
167 }
168 Assume(outpos == SIGNED_LIMBS - 1);
169 limbs[SIGNED_LIMBS - 1] = c;
170 c >>= SIGNED_LIMB_SIZE;
171 Assume(c == 0);
172 }
173
178 void ToNum3072(Num3072 &out) const {
179 double_limb_t c = 0;
180 int b = 0, outpos = 0;
181 for (int i = 0; i < SIGNED_LIMBS; ++i) {
182 c += double_limb_t(limbs[i]) << b;
183 b += SIGNED_LIMB_SIZE;
184 if (b >= LIMB_SIZE) {
185 out.limbs[outpos++] = c;
186 c >>= LIMB_SIZE;
187 b -= LIMB_SIZE;
188 }
189 }
190 Assume(outpos == LIMBS);
191 Assume(c == 0);
192 }
193
200 void Normalize(bool negate) {
201 // Add modulus if this was negative. This brings the range of *this to
202 // 1-2^3072..2^3072-1. -1 if this is negative; 0 otherwise
203 signed_limb_t cond_add = limbs[SIGNED_LIMBS - 1] >> (LIMB_SIZE - 1);
204 limbs[0] += signed_limb_t(-MAX_PRIME_DIFF) & cond_add;
205 limbs[FINAL_LIMB_POSITION] +=
206 (signed_limb_t(1) << FINAL_LIMB_MODULUS_BITS) & cond_add;
207 // Next negate all limbs if negate was set. This does not change the
208 // range of *this. -1 if this negate is true; 0 otherwise
209 signed_limb_t cond_negate = -signed_limb_t(negate);
210 for (int i = 0; i < SIGNED_LIMBS; ++i) {
211 limbs[i] = (limbs[i] ^ cond_negate) - cond_negate;
212 }
213 // Perform carry (make all limbs except the top one be in range
214 // 0..2^SIGNED_LIMB_SIZE-1).
215 for (int i = 0; i < SIGNED_LIMBS - 1; ++i) {
216 limbs[i + 1] += limbs[i] >> SIGNED_LIMB_SIZE;
217 limbs[i] &= MAX_SIGNED_LIMB;
218 }
219 // Again add modulus if *this was negative. This brings the range of
220 // *this to 0..2^3072-1. -1 if this is negative; 0 otherwise
221 cond_add = limbs[SIGNED_LIMBS - 1] >> (LIMB_SIZE - 1);
222 limbs[0] += signed_limb_t(-MAX_PRIME_DIFF) & cond_add;
223 limbs[FINAL_LIMB_POSITION] +=
224 (signed_limb_t(1) << FINAL_LIMB_MODULUS_BITS) & cond_add;
225 // Perform another carry. Now all limbs are in range
226 // 0..2^SIGNED_LIMB_SIZE-1.
227 for (int i = 0; i < SIGNED_LIMBS - 1; ++i) {
228 limbs[i + 1] += limbs[i] >> SIGNED_LIMB_SIZE;
229 limbs[i] &= MAX_SIGNED_LIMB;
230 }
231 }
232};
233
235struct SignedMatrix {
236 signed_limb_t u, v, q, r;
237};
238
243inline int CountTrailingZeroes(limb_t v) {
244#ifdef HAVE_DECL___BUILTIN_CTZ
245 /* Use __builtin_ctz if available, and sufficient for the size of limb_t. */
246 if constexpr (std::numeric_limits<limb_t>::max() <=
247 std::numeric_limits<unsigned>::max()) {
248 return __builtin_ctz(v);
249 }
250#endif
251#ifdef HAVE_DECL___BUILTIN_CTZL
252 /* Use __builtin_ctzl if available, and sufficient for the size of limb_t.
253 */
254 if constexpr (std::numeric_limits<limb_t>::max() <=
255 std::numeric_limits<unsigned long>::max()) {
256 return __builtin_ctzl(v);
257 }
258#endif
259#ifdef HAVE_DECL___BUILTIN_CTZLL
260 /* Use __builtin_ctzll if available, and sufficient for the size of limb_t.
261 */
262 if constexpr (std::numeric_limits<limb_t>::max() <=
263 std::numeric_limits<unsigned long long>::max()) {
264 return __builtin_ctzll(v);
265 }
266#endif
267 /* Otherwise fall back to a software implementation. */
268 if constexpr (LIMB_SIZE <= 32) {
269 static constexpr uint8_t debruijn[32] = {
270 0, 1, 2, 24, 3, 19, 6, 25, 26, 4, 20, 10, 16, 7, 12, 26,
271 31, 23, 18, 5, 21, 9, 15, 11, 30, 17, 8, 14, 29, 13, 28, 27};
272 return debruijn[((v & -v) * 0x04D7651F) >> 27];
273 } else {
274 static_assert(LIMB_SIZE <= 64);
275 static constexpr uint8_t debruijn[64] = {
276 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
277 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
278 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
279 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12};
280 return debruijn[((v & -v) * 0x022FDD63CC95386D) >> 58];
281 }
282}
283
293inline limb_t ComputeDivstepMatrix(signed_limb_t eta, limb_t f, limb_t g,
294 SignedMatrix &out) {
296 static const uint8_t NEGINV256[128] = {
297 0xFF, 0x55, 0x33, 0x49, 0xC7, 0x5D, 0x3B, 0x11, 0x0F, 0xE5, 0xC3, 0x59,
298 0xD7, 0xED, 0xCB, 0x21, 0x1F, 0x75, 0x53, 0x69, 0xE7, 0x7D, 0x5B, 0x31,
299 0x2F, 0x05, 0xE3, 0x79, 0xF7, 0x0D, 0xEB, 0x41, 0x3F, 0x95, 0x73, 0x89,
300 0x07, 0x9D, 0x7B, 0x51, 0x4F, 0x25, 0x03, 0x99, 0x17, 0x2D, 0x0B, 0x61,
301 0x5F, 0xB5, 0x93, 0xA9, 0x27, 0xBD, 0x9B, 0x71, 0x6F, 0x45, 0x23, 0xB9,
302 0x37, 0x4D, 0x2B, 0x81, 0x7F, 0xD5, 0xB3, 0xC9, 0x47, 0xDD, 0xBB, 0x91,
303 0x8F, 0x65, 0x43, 0xD9, 0x57, 0x6D, 0x4B, 0xA1, 0x9F, 0xF5, 0xD3, 0xE9,
304 0x67, 0xFD, 0xDB, 0xB1, 0xAF, 0x85, 0x63, 0xF9, 0x77, 0x8D, 0x6B, 0xC1,
305 0xBF, 0x15, 0xF3, 0x09, 0x87, 0x1D, 0xFB, 0xD1, 0xCF, 0xA5, 0x83, 0x19,
306 0x97, 0xAD, 0x8B, 0xE1, 0xDF, 0x35, 0x13, 0x29, 0xA7, 0x3D, 0x1B, 0xF1,
307 0xEF, 0xC5, 0xA3, 0x39, 0xB7, 0xCD, 0xAB, 0x01};
308 // Coefficients of returned SignedMatrix; starts off as identity matrix. */
309 limb_t u = 1, v = 0, q = 0, r = 1;
310 // The number of divsteps still left.
311 int i = SIGNED_LIMB_SIZE;
312 while (true) {
313 /* Use a sentinel bit to count zeros only up to i. */
314 int zeros = CountTrailingZeroes(g | (MAX_LIMB << i));
315 /* Perform zeros divsteps at once; they all just divide g by two. */
316 g >>= zeros;
317 u <<= zeros;
318 v <<= zeros;
319 eta -= zeros;
320 i -= zeros;
321 /* We're done once we've performed SIGNED_LIMB_SIZE divsteps. */
322 if (i == 0) {
323 break;
324 }
325 /* If eta is negative, negate it and replace f,g with g,-f. */
326 if (eta < 0) {
327 limb_t tmp;
328 eta = -eta;
329 tmp = f;
330 f = g;
331 g = -tmp;
332 tmp = u;
333 u = q;
334 q = -tmp;
335 tmp = v;
336 v = r;
337 r = -tmp;
338 }
339 /* eta is now >= 0. In what follows we're going to cancel out the bottom
340 * bits of g. No more than i can be cancelled out (as we'd be done
341 * before that point), and no more than eta+1 can be done as its sign
342 * will flip once that happens.
343 */
344 int limit = ((int)eta + 1) > i ? i : ((int)eta + 1);
345 /*
346 * m is a mask for the bottom min(limit, 8) bits (our table only
347 * supports 8 bits).
348 */
349 limb_t m = (MAX_LIMB >> (LIMB_SIZE - limit)) & 255U;
350 /*
351 * Find what multiple of f must be added to g to cancel its bottom
352 * min(limit, 8) bits.
353 */
354 limb_t w = (g * NEGINV256[(f >> 1) & 127]) & m;
355 /* Do so. */
356 g += f * w;
357 q += u * w;
358 r += v * w;
359 }
360 out.u = (signed_limb_t)u;
361 out.v = (signed_limb_t)v;
362 out.q = (signed_limb_t)q;
363 out.r = (signed_limb_t)r;
364 return eta;
365}
366
372inline void UpdateDE(Num3072Signed &d, Num3072Signed &e,
373 const SignedMatrix &t) {
374 const signed_limb_t u = t.u, v = t.v, q = t.q, r = t.r;
375
376 /*
377 * [md,me] start as zero; plus [u,q] if d is negative; plus [v,r] if e is
378 * negative.
379 */
380 signed_limb_t sd = d.limbs[SIGNED_LIMBS - 1] >> (LIMB_SIZE - 1);
381 signed_limb_t se = e.limbs[SIGNED_LIMBS - 1] >> (LIMB_SIZE - 1);
382 signed_limb_t md = (u & sd) + (v & se);
383 signed_limb_t me = (q & sd) + (r & se);
384 /* Begin computing t*[d,e]. */
385 signed_limb_t di = d.limbs[0], ei = e.limbs[0];
386 signed_double_limb_t cd =
387 (signed_double_limb_t)u * di + (signed_double_limb_t)v * ei;
388 signed_double_limb_t ce =
389 (signed_double_limb_t)q * di + (signed_double_limb_t)r * ei;
390 /*
391 * Correct md,me so that t*[d,e]+modulus*[md,me] has SIGNED_LIMB_SIZE zero
392 * bottom bits.
393 */
394 md -= (MODULUS_INVERSE * limb_t(cd) + md) & MAX_SIGNED_LIMB;
395 me -= (MODULUS_INVERSE * limb_t(ce) + me) & MAX_SIGNED_LIMB;
396 /*
397 * Update the beginning of computation for t*[d,e]+modulus*[md,me] now md,me
398 * are known.
399 */
400 cd -= (signed_double_limb_t)1103717 * md;
401 ce -= (signed_double_limb_t)1103717 * me;
402 /*
403 * Verify that the low SIGNED_LIMB_SIZE bits of the computation are indeed
404 * zero, and then throw them away.
405 */
406 Assume((cd & MAX_SIGNED_LIMB) == 0);
407 Assume((ce & MAX_SIGNED_LIMB) == 0);
408 cd >>= SIGNED_LIMB_SIZE;
409 ce >>= SIGNED_LIMB_SIZE;
410 /*
411 * Now iteratively compute limb i=1..SIGNED_LIMBS-2 of
412 * t*[d,e]+modulus*[md,me], and store them in output limb i-1 (shifting down
413 * by SIGNED_LIMB_SIZE bits). The corresponding limbs in modulus are all
414 * zero, so modulus/md/me are not actually involved here.
415 */
416 for (int i = 1; i < SIGNED_LIMBS - 1; ++i) {
417 di = d.limbs[i];
418 ei = e.limbs[i];
419 cd += (signed_double_limb_t)u * di + (signed_double_limb_t)v * ei;
420 ce += (signed_double_limb_t)q * di + (signed_double_limb_t)r * ei;
421 d.limbs[i - 1] = (signed_limb_t)cd & MAX_SIGNED_LIMB;
422 cd >>= SIGNED_LIMB_SIZE;
423 e.limbs[i - 1] = (signed_limb_t)ce & MAX_SIGNED_LIMB;
424 ce >>= SIGNED_LIMB_SIZE;
425 }
426 /*
427 * Compute limb SIGNED_LIMBS-1 of t*[d,e]+modulus*[md,me], and store it in
428 * output limb SIGNED_LIMBS-2.
429 */
430 di = d.limbs[SIGNED_LIMBS - 1];
431 ei = e.limbs[SIGNED_LIMBS - 1];
432 cd += (signed_double_limb_t)u * di + (signed_double_limb_t)v * ei;
433 ce += (signed_double_limb_t)q * di + (signed_double_limb_t)r * ei;
434 cd += (signed_double_limb_t)md << FINAL_LIMB_MODULUS_BITS;
435 ce += (signed_double_limb_t)me << FINAL_LIMB_MODULUS_BITS;
436 d.limbs[SIGNED_LIMBS - 2] = (signed_limb_t)cd & MAX_SIGNED_LIMB;
437 cd >>= SIGNED_LIMB_SIZE;
438 e.limbs[SIGNED_LIMBS - 2] = (signed_limb_t)ce & MAX_SIGNED_LIMB;
439 ce >>= SIGNED_LIMB_SIZE;
440 /* What remains goes into output limb SINGED_LIMBS-1 */
441 d.limbs[SIGNED_LIMBS - 1] = (signed_limb_t)cd;
442 e.limbs[SIGNED_LIMBS - 1] = (signed_limb_t)ce;
443}
444
452inline void UpdateFG(Num3072Signed &f, Num3072Signed &g, const SignedMatrix &t,
453 int len) {
454 const signed_limb_t u = t.u, v = t.v, q = t.q, r = t.r;
455
456 signed_limb_t fi, gi;
457 signed_double_limb_t cf, cg;
458 /* Start computing t*[f,g]. */
459 fi = f.limbs[0];
460 gi = g.limbs[0];
461 cf = (signed_double_limb_t)u * fi + (signed_double_limb_t)v * gi;
462 cg = (signed_double_limb_t)q * fi + (signed_double_limb_t)r * gi;
463 /*
464 * Verify that the bottom SIGNED_LIMB_BITS bits of the result are zero, and
465 * then throw them away.
466 */
467 Assume((cf & MAX_SIGNED_LIMB) == 0);
468 Assume((cg & MAX_SIGNED_LIMB) == 0);
469 cf >>= SIGNED_LIMB_SIZE;
470 cg >>= SIGNED_LIMB_SIZE;
471 /*
472 * Now iteratively compute limb i=1..SIGNED_LIMBS-1 of t*[f,g], and store
473 * them in output limb i-1 (shifting down by SIGNED_LIMB_BITS bits).
474 */
475 for (int i = 1; i < len; ++i) {
476 fi = f.limbs[i];
477 gi = g.limbs[i];
478 cf += (signed_double_limb_t)u * fi + (signed_double_limb_t)v * gi;
479 cg += (signed_double_limb_t)q * fi + (signed_double_limb_t)r * gi;
480 f.limbs[i - 1] = (signed_limb_t)cf & MAX_SIGNED_LIMB;
481 cf >>= SIGNED_LIMB_SIZE;
482 g.limbs[i - 1] = (signed_limb_t)cg & MAX_SIGNED_LIMB;
483 cg >>= SIGNED_LIMB_SIZE;
484 }
485 /*
486 * What remains is limb SIGNED_LIMBS of t*[f,g]; store it as output limb
487 * SIGNED_LIMBS-1.
488 */
489 f.limbs[len - 1] = (signed_limb_t)cf;
490 g.limbs[len - 1] = (signed_limb_t)cg;
491}
492} // namespace
493
495 // Compute a modular inverse based on a variant of the safegcd algorithm:
496 // - Paper: https://gcd.cr.yp.to/papers.html
497 // - Inspired by this code in libsecp256k1:
498 // https://github.com/bitcoin-core/secp256k1/blob/master/src/modinv32_impl.h
499 // - Explanation of the algorithm:
500 // https://github.com/bitcoin-core/secp256k1/blob/master/doc/safegcd_implementation.md
501
502 // Local variables d, e, f, g:
503 // - f and g are the variables whose gcd we compute (despite knowing the
504 // answer is 1):
505 // - f is always odd, and initialized as modulus
506 // - g is initialized as *this (called x in what follows)
507 // - d and e are the numbers for which at every step it is the case that:
508 // - f = d * x mod modulus; d is initialized as 0
509 // - g = e * x mod modulus; e is initialized as 1
510 Num3072Signed d, e, f, g;
511 e.limbs[0] = 1;
512 // F is initialized as modulus, which in signed limb representation can be
513 // expressed simply as 2^3072 + -MAX_PRIME_DIFF.
514 f.limbs[0] = -MAX_PRIME_DIFF;
515 f.limbs[FINAL_LIMB_POSITION] = ((limb_t)1) << FINAL_LIMB_MODULUS_BITS;
516 g.FromNum3072(*this);
517 int len = SIGNED_LIMBS;
518 signed_limb_t eta = -1;
519 // Perform divsteps on [f,g] until g=0 is reached, keeping (d,e)
520 // synchronized with them.
521 while (true) {
522 // Compute transformation matrix t that represents the next
523 // SIGNED_LIMB_SIZE divsteps to apply. This can be computed from just
524 // the bottom limb of f and g, and eta.
525 SignedMatrix t;
526 eta = ComputeDivstepMatrix(eta, f.limbs[0], g.limbs[0], t);
527 // Apply that transformation matrix to the full [f,g] vector.
528 UpdateFG(f, g, t, len);
529 // Apply that transformation matrix to the full [d,e] vector (mod
530 // modulus).
531 UpdateDE(d, e, t);
532
533 // Check if g is zero.
534 if (g.limbs[0] == 0) {
535 signed_limb_t cond = 0;
536 for (int j = 1; j < len; ++j) {
537 cond |= g.limbs[j];
538 }
539 // If so, we're done.
540 if (cond == 0) {
541 break;
542 }
543 }
544
545 // Check if the top limbs of both f and g are both 0 or -1.
546 signed_limb_t fn = f.limbs[len - 1], gn = g.limbs[len - 1];
547 signed_limb_t cond = ((signed_limb_t)len - 2) >> (LIMB_SIZE - 1);
548 cond |= fn ^ (fn >> (LIMB_SIZE - 1));
549 cond |= gn ^ (gn >> (LIMB_SIZE - 1));
550 if (cond == 0) {
551 // If so, drop the top limb, shrinking the size of f and g, by
552 // propagating the sign to the previous limb.
553 f.limbs[len - 2] |= (limb_t)f.limbs[len - 1] << SIGNED_LIMB_SIZE;
554 g.limbs[len - 2] |= (limb_t)g.limbs[len - 1] << SIGNED_LIMB_SIZE;
555 --len;
556 }
557 }
558 // At some point, [f,g] will have been rewritten into [f',0], such that
559 // gcd(f,g) = gcd(f',0). This is proven in the paper. As f started out being
560 // modulus, a prime number, we know that gcd is 1, and thus f' is 1 or -1.
561 Assume((f.limbs[0] & MAX_SIGNED_LIMB) == 1 ||
562 (f.limbs[0] & MAX_SIGNED_LIMB) == MAX_SIGNED_LIMB);
563 // As we've maintained the invariant that f = d * x mod modulus, we get d/f
564 // mod modulus is the modular inverse of x we're looking for. As f is 1 or
565 // -1, it is also true that d/f = d*f. Normalize d to prepare it for output,
566 // while negating it if f is negative.
567 d.Normalize(f.limbs[len - 1] >> (LIMB_SIZE - 1));
568 Num3072 ret;
569 d.ToNum3072(ret);
570 return ret;
571}
572
574 limb_t c0 = 0, c1 = 0, c2 = 0;
575 Num3072 tmp;
576
577 /* Compute limbs 0..N-2 of this*a into tmp, including one reduction. */
578 for (int j = 0; j < LIMBS - 1; ++j) {
579 limb_t d0 = 0, d1 = 0, d2 = 0;
580 mul(d0, d1, this->limbs[1 + j], a.limbs[LIMBS + j - (1 + j)]);
581 for (int i = 2 + j; i < LIMBS; ++i) {
582 muladd3(d0, d1, d2, this->limbs[i], a.limbs[LIMBS + j - i]);
583 }
584 mulnadd3(c0, c1, c2, d0, d1, d2, MAX_PRIME_DIFF);
585 for (int i = 0; i < j + 1; ++i) {
586 muladd3(c0, c1, c2, this->limbs[i], a.limbs[j - i]);
587 }
588 extract3(c0, c1, c2, tmp.limbs[j]);
589 }
590
591 /* Compute limb N-1 of a*b into tmp. */
592 assert(c2 == 0);
593 for (int i = 0; i < LIMBS; ++i) {
594 muladd3(c0, c1, c2, this->limbs[i], a.limbs[LIMBS - 1 - i]);
595 }
596 extract3(c0, c1, c2, tmp.limbs[LIMBS - 1]);
597
598 /* Perform a second reduction. */
599 muln2(c0, c1, MAX_PRIME_DIFF);
600 for (int j = 0; j < LIMBS; ++j) {
601 addnextract2(c0, c1, tmp.limbs[j], this->limbs[j]);
602 }
603
604 assert(c1 == 0);
605 assert(c0 == 0 || c0 == 1);
606
612 if (this->IsOverflow()) {
613 this->FullReduce();
614 }
615 if (c0) {
616 this->FullReduce();
617 }
618}
619
621 this->limbs[0] = 1;
622 for (int i = 1; i < LIMBS; ++i) {
623 this->limbs[i] = 0;
624 }
625}
626
627void Num3072::Divide(const Num3072 &a) {
628 if (this->IsOverflow()) {
629 this->FullReduce();
630 }
631
632 Num3072 inv{};
633 if (a.IsOverflow()) {
634 Num3072 b = a;
635 b.FullReduce();
636 inv = b.GetInverse();
637 } else {
638 inv = a.GetInverse();
639 }
640
641 this->Multiply(inv);
642 if (this->IsOverflow()) {
643 this->FullReduce();
644 }
645}
646
647Num3072::Num3072(const uint8_t (&data)[BYTE_SIZE]) {
648 for (int i = 0; i < LIMBS; ++i) {
649 if (sizeof(limb_t) == 4) {
650 this->limbs[i] = ReadLE32(data + 4 * i);
651 } else if (sizeof(limb_t) == 8) {
652 this->limbs[i] = ReadLE64(data + 8 * i);
653 }
654 }
655}
656
657void Num3072::ToBytes(uint8_t (&out)[BYTE_SIZE]) {
658 for (int i = 0; i < LIMBS; ++i) {
659 if (sizeof(limb_t) == 4) {
660 WriteLE32(out + i * 4, this->limbs[i]);
661 } else if (sizeof(limb_t) == 8) {
662 WriteLE64(out + i * 8, this->limbs[i]);
663 }
664 }
665}
666
668 uint8_t tmp[Num3072::BYTE_SIZE];
669
670 uint256 hashed_in{(HashWriter{} << in).GetSHA256()};
671 static_assert(sizeof(tmp) % ChaCha20Aligned::BLOCKLEN == 0);
672 ChaCha20Aligned{MakeByteSpan(hashed_in)}.Keystream(
674 Num3072 out{tmp};
675
676 return out;
677}
678
680 m_numerator = ToNum3072(in);
681}
682
683void MuHash3072::Finalize(uint256 &out) noexcept {
684 m_numerator.Divide(m_denominator);
685 // Needed to keep the MuHash object valid
686 m_denominator.SetToOne();
687
688 uint8_t data[Num3072::BYTE_SIZE];
689 m_numerator.ToBytes(data);
690
691 out = (HashWriter{} << data).GetSHA256();
692}
693
695 m_numerator.Multiply(mul.m_numerator);
696 m_denominator.Multiply(mul.m_denominator);
697 return *this;
698}
699
701 m_numerator.Multiply(div.m_denominator);
702 m_denominator.Multiply(div.m_numerator);
703 return *this;
704}
705
707 m_numerator.Multiply(ToNum3072(in));
708 return *this;
709}
710
712 m_denominator.Multiply(ToNum3072(in));
713 return *this;
714}
#define Assume(val)
Assume is the identity function.
Definition: check.h:97
ChaCha20 cipher that only operates on multiples of 64 bytes.
Definition: chacha20.h:25
static constexpr unsigned BLOCKLEN
Block size (inputs/outputs to Keystream / Crypt should be multiples of this).
Definition: chacha20.h:37
A writer stream (for serialization) that computes a 256-bit hash.
Definition: hash.h:100
A class representing MuHash sets.
Definition: muhash.h:107
Num3072 ToNum3072(Span< const uint8_t > in)
Definition: muhash.cpp:667
MuHash3072 & Remove(Span< const uint8_t > in) noexcept
Definition: muhash.cpp:711
void Finalize(uint256 &out) noexcept
Definition: muhash.cpp:683
MuHash3072() noexcept
Definition: muhash.h:116
MuHash3072 & operator/=(const MuHash3072 &div) noexcept
Definition: muhash.cpp:700
MuHash3072 & Insert(Span< const uint8_t > in) noexcept
Definition: muhash.cpp:706
MuHash3072 & operator*=(const MuHash3072 &mul) noexcept
Definition: muhash.cpp:694
Definition: muhash.h:18
Num3072 GetInverse() const
Definition: muhash.cpp:494
static constexpr int LIMBS
Definition: muhash.h:41
int64_t signed_double_limb_t
Definition: muhash.h:38
int32_t signed_limb_t
Definition: muhash.h:40
static constexpr size_t BYTE_SIZE
Definition: muhash.h:25
bool IsOverflow() const
Indicates whether d is larger than the modulus.
Definition: muhash.cpp:119
void ToBytes(uint8_t(&out)[BYTE_SIZE])
Definition: muhash.cpp:657
limb_t limbs[LIMBS]
Definition: muhash.h:46
static constexpr int SIGNED_LIMBS
Definition: muhash.h:42
void SetToOne()
Definition: muhash.cpp:620
static constexpr int LIMB_SIZE
Definition: muhash.h:43
void Divide(const Num3072 &a)
Definition: muhash.cpp:627
static constexpr int SIGNED_LIMB_SIZE
Definition: muhash.h:44
void FullReduce()
Definition: muhash.cpp:131
uint64_t double_limb_t
Definition: muhash.h:37
uint32_t limb_t
Definition: muhash.h:39
Num3072()
Definition: muhash.h:67
void Multiply(const Num3072 &a)
Definition: muhash.cpp:573
256-bit opaque blob.
Definition: uint256.h:129
static void WriteLE32(uint8_t *ptr, uint32_t x)
Definition: common.h:40
static uint64_t ReadLE64(const uint8_t *ptr)
Definition: common.h:29
static uint32_t ReadLE32(const uint8_t *ptr)
Definition: common.h:23
static void WriteLE64(uint8_t *ptr, uint64_t x)
Definition: common.h:45
Span< const std::byte > MakeByteSpan(V &&v) noexcept
Definition: span.h:302
Span< std::byte > MakeWritableByteSpan(V &&v) noexcept
Definition: span.h:305
assert(!tx.IsCoinBase())