Skip to content

Commit b086964

Browse files
committed
Merge bitcoin#21590: Safegcd-based modular inverses in MuHash3072
f588328 Add a fuzz test for Num3072 multiplication and inversion (Pieter Wuille) a26ce62 Safegcd based modular inverse for Num3072 (Pieter Wuille) 91ce8ce Add benchmark for MuHash finalization (Pieter Wuille) Pull request description: This implements a safegcd-based modular inverse for MuHash3072. It is a fairly straightforward translation of [the libsecp256k1 implementation](bitcoin-core/secp256k1#831), with the following changes: * Generic for 32-bit and 64-bit * Specialized for the specific MuHash3072 modulus (2^3072 - 1103717). * A bit more C++ish * Far fewer sanity checks A benchmark is also included for MuHash3072::Finalize. The new implementation is around 100x faster on x86_64 for me (from 5.8 ms to 57 μs); for 32-bit code the factor is likely even larger. For more information: * [Original paper](https://gcd.cr.yp.to/papers.html) by Daniel J. Bernstein and Bo-Yin Yang * [Implementation](bitcoin-core/secp256k1#767) for libsecp256k1 by Peter Dettman; and the [final](bitcoin-core/secp256k1#831) version * [Explanation](https://github.com/bitcoin-core/secp256k1/blob/master/doc/safegcd_implementation.md) of the algorithm using Python snippets * [Analysis](https://github.com/sipa/safegcd-bounds) of the maximum number of iterations the algorithm needs * [Formal proof in Coq](https://medium.com/blockstream/a-formal-proof-of-safegcd-bounds-695e1735a348) by Russell O'Connor (for the 256-bit version of the algorithm; here we use a 3072-bit one). ACKs for top commit: achow101: ACK f588328 TheCharlatan: Re-ACK f588328 dergoegge: tACK f588328 Tree-SHA512: 275872c61d30817a82901dee93fc7153afca55c32b72a95b8768f3fd464da1b09b36f952f30e70225e766b580751cfb9b874b2feaeb73ffaa6943c8062aee19a
2 parents 0a931a9 + f588328 commit b086964

File tree

6 files changed

+513
-92
lines changed

6 files changed

+513
-92
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,7 @@ target_link_libraries(core_interface INTERFACE warn_interface)
397397
if(MSVC)
398398
try_append_cxx_flags("/W3" TARGET warn_interface SKIP_LINK)
399399
try_append_cxx_flags("/wd4018" TARGET warn_interface SKIP_LINK)
400+
try_append_cxx_flags("/wd4146" TARGET warn_interface SKIP_LINK)
400401
try_append_cxx_flags("/wd4244" TARGET warn_interface SKIP_LINK)
401402
try_append_cxx_flags("/wd4267" TARGET warn_interface SKIP_LINK)
402403
try_append_cxx_flags("/wd4715" TARGET warn_interface SKIP_LINK)

src/arith_uint256.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,3 +229,7 @@ arith_uint256 UintToArith256(const uint256 &a)
229229
b.pn[x] = ReadLE32(a.begin() + x*4);
230230
return b;
231231
}
232+
233+
// Explicit instantiations for base_uint<6144> (used in test/fuzz/muhash.cpp).
234+
template base_uint<6144>& base_uint<6144>::operator*=(const base_uint<6144>& b);
235+
template base_uint<6144>& base_uint<6144>::operator/=(const base_uint<6144>& b);

src/bench/crypto_hash.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,19 @@ static void MuHashPrecompute(benchmark::Bench& bench)
249249
});
250250
}
251251

252+
static void MuHashFinalize(benchmark::Bench& bench)
253+
{
254+
FastRandomContext rng(true);
255+
MuHash3072 acc{rng.randbytes(32)};
256+
acc /= MuHash3072{rng.rand256()};
257+
258+
bench.run([&] {
259+
uint256 out;
260+
acc.Finalize(out);
261+
acc /= MuHash3072{out};
262+
});
263+
}
264+
252265
BENCHMARK(BenchRIPEMD160, benchmark::PriorityLevel::HIGH);
253266
BENCHMARK(SHA1, benchmark::PriorityLevel::HIGH);
254267
BENCHMARK(SHA256_STANDARD, benchmark::PriorityLevel::HIGH);
@@ -272,3 +285,4 @@ BENCHMARK(MuHash, benchmark::PriorityLevel::HIGH);
272285
BENCHMARK(MuHashMul, benchmark::PriorityLevel::HIGH);
273286
BENCHMARK(MuHashDiv, benchmark::PriorityLevel::HIGH);
274287
BENCHMARK(MuHashPrecompute, benchmark::PriorityLevel::HIGH);
288+
BENCHMARK(MuHashFinalize, benchmark::PriorityLevel::HIGH);

0 commit comments

Comments
 (0)