bch/abla: MSVC-portable 128-bit muldiv (fixes c2pool-bch Windows build) - #688
Merged
Conversation
… build) abla.hpp evaluated the ABLA control-function muldiv(x,y,z)=x*y/z in a native unsigned __int128 intermediate. __int128 is a GCC/Clang extension MSVC does not provide (error C4235 __int128 keyword not supported on this architecture), so c2pool-bch failed to compile on Windows while Linux/macOS passed -- blocking the v0.2.1 c2pool-bch-windows package. Keep the native __int128 path BYTE-EXACT for GCC/Clang (the shipping Linux/macOS builds are unchanged) under #if defined(__SIZEOF_INT128__). For any compiler without __int128 (MSVC), fall back to boost::multiprecision::uint128_t -- a fixed 128-bit unsigned type, header-only, already a project dependency (conan + system libboost). ABLA math stays exact. Guard: new bch_muldiv_kat_test pins the two paths equal. Layer A is a set of cross-platform known answers (several with >2^64 products, so a 64-bit multiply would fail) that muldiv must satisfy on every compiler incl. MSVC. Layer B, on platforms with __int128, asserts muldiv_native == muldiv_portable across the full ABLA operand space plus a deterministic 200k-vector wide fuzz -- proving the portable arithmetic is bit-identical to native on the trusted platform, which certifies the MSVC path we cannot run in this CI. Verified locally: KAT PASS (native==portable over 150260 in-domain fuzz vectors, release+debug); ABLA growth soak unchanged (mainnet final=41305530). Wired bch_muldiv_kat_test into src/impl/bch/test/CMakeLists.txt and both build.yml COIN_BCH target lists. p2pool-merged-v36 surface: NONE (ABLA is a local build-time block-size budget only; no PoW/share/coinbase/PPLNS math touched).
frstrtr
added a commit
that referenced
this pull request
Jul 13, 2026
Add the consensus-arithmetic KAT integrator required to merge #690: assert the MSVC-portability rework of the DigiShield 256-bit retarget math is BIT-IDENTICAL across the native and portable branches, mirroring the bch #688 muldiv_kat precedent. The MSVC branch routes through the x64 _umul128/_udiv128 intrinsics that cannot be compiled or run on the Linux/macOS CI, so dgb_arith256.hpp now exposes a third, fully SOFTWARE oracle (detail::umul128_soft/udiv128_soft, the *_portable primitive twins, and u256_portable) using only 32-bit-limb arithmetic -- no __int128, no intrinsic. It is a genuinely independent computation; proving software == native across the DigiShield operand domain on Linux certifies the MSVC path we cannot run, since the x64 intrinsics are by ISA definition exactly the 64x64->128 product and 128/64 quotient the software reproduces. The oracle is header-only, compiled unconditionally, and NEVER referenced by the shipping u256 / mul_div_u256 -- the GCC/Clang retarget bytes stay byte-identical. arith256_muldiv_kat_test asserts mul_add_u128 / div_u128 / add_u128 and u256 mul_u64 / div_u64 / operator+= are bit-identical native-vs-portable across DigiShield target/scalar vectors + a 100k deterministic LCG fuzz, with dedicated stress of the _udiv128 hi<d running-remainder boundary (hi = d-1) so a precondition violation surfaces as a KAT fail, not field UB. Registered unconditionally in CMake and in BOTH build.yml --target allowlists (#143 NOT_BUILT trap). Pure header math: links only GTest. Local: 7/7 PASS; digishield_walk 6/6 + header_chain 35/35 unregressed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Make the BCH ABLA 128-bit
muldivMSVC-portable. Fixes thec2pool-bchWindows compile failure blocking the v0.2.1 Windows package:How
#if defined(__SIZEOF_INT128__)-> nativeunsigned __int128path, byte-exact / unchanged (this is what the shipping Linux/macOS merged builds already have).#else(MSVC, no__int128) ->boost::multiprecision::uint128_tfallback. Header-only, boost already a project dep (conan + system libboost). Exact 128-bit intermediate.__int128token reaches a non-__int128compiler (all native code is inside the guard).Guard (the KAT the task asked for)
New
bch_muldiv_kat_test:>2^64products, so a 64-bit multiply would fail);muldivmust satisfy these on every compiler incl. MSVC.__int128) —muldiv_native == muldiv_portableacross the full ABLA operand space + a deterministic 200k-vector wide fuzz. Proves the portable arithmetic is bit-identical to native on the trusted platform, which certifies the MSVC path CI cannot execute here.Wired into
src/impl/bch/test/CMakeLists.txtand bothbuild.ymlCOIN_BCH target lists.Verified locally (dev host, gcc-13 c++20)
bch_muldiv_kat_test: ALL PASS — native==portable over 150260 in-domain fuzz vectors, release and debug.Scope / safety
src/impl/bchonly. p2pool-merged-v36 surface: NONE — ABLA is a local build-time block-size budget; no PoW / share / coinbase / PPLNS math touched.c2pool-bch-windowspackage.Related: btc / dgb / dash Windows cells failed this run too (each likely its own MSVC gap) — separate look, ci-steward CC'd.