feat(msm): vendor libsecp256k1 ecmult_multi_var as mpt_msm_variable_time#89
Open
tesseract-ripple wants to merge 1 commit into
Open
feat(msm): vendor libsecp256k1 ecmult_multi_var as mpt_msm_variable_time#89tesseract-ripple wants to merge 1 commit into
tesseract-ripple wants to merge 1 commit into
Conversation
bb662ef to
8578081
Compare
8578081 to
129864d
Compare
This was referenced May 27, 2026
Self-contained vendor of secp256k1_ecmult_multi_var (Pippenger/Straus MSM) from libsecp256k1 v0.7.1, supporting the upcoming *_verify_batch API for compact-sigma + aggregated-BP batch verification. Vendor layout (third_party/secp256k1-msm/) ------------------------------------------ - 39 .h files + precomputed_ecmult.c (~2.3 MB of generator table data) copied from libsecp256k1 src/ at tag v0.7.1, commit 1a53f4961f337b4d166c25fce72ef0dc88806618. See PROVENANCE. - mpt_msm.c: single wrapper translation unit that includes the vendored headers and exposes the one external API symbol, mpt_msm_variable_time. All upstream functions are file-static; no link-time collision with the still-linked libsecp256k1. - Two compile-time -D renames (-Dsecp256k1_pre_g=mpt_secp256k1_pre_g and the _128 variant) to namespace the only non-static data symbols (the generator precomputation tables, which the linked libsecp256k1 also exports). - Local edit to util.h: relative include "../include/secp256k1.h" changed to <secp256k1.h> so it resolves through the linked install. Only edit to upstream sources. Self-containment ---------------- The vendor includes dependent internal types (secp256k1_gej, secp256k1_scalar, secp256k1_fe, scratch-space layouts), not just ecmult_impl.h and the WNAF helpers. This decouples the vendored MSM's correctness from the linked libsecp256k1 binary's version, so this PR does NOT change the existing libsecp256k1 Conan pin. Threat model ------------ mpt_msm_variable_time is variable-time. Validator path (D4) only; the verifier has no secret inputs. The two-profile API shape (mpt_msm_variable_time vs the planned mpt_msm_constant_time -- see XRPLF#87) makes the constant-time requirement audit-visible at the call site. Build integration ----------------- - CMake OBJECT library mpt-crypto-msm-vendor; linked into mpt-crypto. - -Wno-pedantic only on the vendored TU; main library remains under -Wall -Wextra -Wpedantic -Werror. - .pre-commit-config.yaml: third_party/ excluded from style hooks so the vendored upstream files stay close to their upstream form (clean diffs on re-sync). Large-file limit raised to 4 MB to admit precomputed_ecmult.c. Tests ----- tests/test_mpt_msm.c: calibration test that compares the vendored MSM output to a reference computed via the public libsecp256k1 API (tweak_mul + pubkey_combine in a loop) on randomized inputs. Bit- identical match required across N_TRIALS. Confirms scalar/point encoding conventions, group-element layout, and end-to-end correctness of the vendoring. Drift detection --------------- None. We follow the same operational model as the Conan lockfile under conan/lockfile/ (XRPLF#95): pin known-good state, re-sync deliberately when there is a reason (security fix, performance gain). No automated tripwire -- same as for Conan-managed dependencies. Out of scope (tracked separately) --------------------------------- - mpt_msm_constant_time profile for the prover path: XRPLF#87. - *_verify_batch API for the four sigma proofs and aggregated BP: XRPLF#88. (Design in cmpt-ct-and-batch.tex.) - Lift the BP m in {1,2} aggregation restriction: XRPLF#46. - rippled-side integration. - Any change to the existing libsecp256k1 dep pin.
129864d to
5e968f9
Compare
tesseract-ripple
added a commit
to tesseract-ripple/mpt-crypto
that referenced
this pull request
May 29, 2026
…RPLF#100) Collapse secp256k1_bulletproof_verify_agg's two equality checks (the range-relation LHS/RHS and the inner-product-collapsed P+IPA check) into one mpt_msm_variable_time call that must return the identity. Variable-time MSM dispatch via the vendored Pippenger/Straus ecmult landed in PR XRPLF#89 (mpt-crypto-msm-vendor); this PR consumes it. Equation. With a fresh Fiat-Shamir batching weight c (BBB+18-style random-linear-combination), the check E1 + c*E2 = 0 unrolls to a (2n + 2*log n + m + 6)-term MSM plus an optional G coefficient (t_hat - delta) passed via inp_g_sc_be32. The H_k coefficient absorbs the y^{-k} factor that was previously applied to a separately-built Hprime vector, and the per-term s_k product (the IPA fold weight) is computed inline matching fold_generators()'s G-fold pattern; s_k^{-1} matches the H-fold pattern, recomputed directly to avoid n scalar inversions. Soundness. c is bound to the entire proof (last IPA round challenge + tau_x + mu + a + b) via SHA-256 with the dedicated tag "MPT_BP_VERIFY_BATCH_RLC". A malicious prover that makes E1 and E2 individually non-zero would need to predict c before committing the proof; Schwartz-Zippel gives the standard 1/q bound. The c == 0 case (~1/2^256) is explicitly rejected to keep the soundness reasoning clean. Perf (Apple M-series, m=2, n=128, 5-iteration avg): before: 10.0 ms after: 1.68 ms speedup: ~6x This exceeds the 2-4x estimate in XRPLF#100; the extra factor comes from also folding the (m+4)-term range check and the rounds-many IPA folding mults into the same MSM, where the constant-fan-out terms contribute to the GLV/Pippenger amortisation. Other changes. * secp256k1_bulletproof_ipa_msm() is untouched; the prover's calculate_commitment_term() still routes through it. Verifier-only swap, prover CT contract preserved. The constant-time MSM profile for the prover is tracked separately in XRPLF#87. * Static helper ipa_verify_explicit() removed; tests/test_ipa.c carries its own copy of the round-by-round IPA-verify check. * fold_generators() and apply_ipa_folding_to_P() retained because tests/test_ipa.c still uses them. Tests. 11/11 ctest green (test_bulletproof_agg covers positive + negative paths for m in {1, 2} including v=0, v=1, v=UINT64_MAX, and the two tampered-commitment cases that exercise the rejection branch of the consolidated MSM).
tesseract-ripple
added a commit
to tesseract-ripple/mpt-crypto
that referenced
this pull request
May 29, 2026
…RPLF#100) Collapse secp256k1_bulletproof_verify_agg's two equality checks (the range-relation LHS/RHS and the inner-product-collapsed P+IPA check) into one mpt_msm_variable_time call that must return the identity. Variable-time MSM dispatch via the vendored Pippenger/Straus ecmult landed in PR XRPLF#89 (mpt-crypto-msm-vendor); this PR consumes it. Equation. With a fresh Fiat-Shamir batching weight c (BBB+18-style random-linear-combination), the check E1 + c*E2 = 0 unrolls to a (2n + 2*log n + m + 6)-term MSM plus an optional G coefficient (t_hat - delta) passed via inp_g_sc_be32. The H_k coefficient absorbs the y^{-k} factor that was previously applied to a separately-built Hprime vector, and the per-term s_k product (the IPA fold weight) is computed inline matching fold_generators()'s G-fold pattern; s_k^{-1} matches the H-fold pattern, recomputed directly to avoid n scalar inversions. Soundness. c is bound to the entire proof (last IPA round challenge + tau_x + mu + a + b) via SHA-256 with the dedicated tag "MPT_BP_VERIFY_BATCH_RLC". A malicious prover that makes E1 and E2 individually non-zero would need to predict c before committing the proof; Schwartz-Zippel gives the standard 1/q bound. The c == 0 case (~1/2^256) is explicitly rejected to keep the soundness reasoning clean. Perf (Apple M-series, m=2, n=128, 5-iteration avg): before: 10.0 ms after: 1.68 ms speedup: ~6x This exceeds the 2-4x estimate in XRPLF#100; the extra factor comes from also folding the (m+4)-term range check and the rounds-many IPA folding mults into the same MSM, where the constant-fan-out terms contribute to the GLV/Pippenger amortisation. Other changes. * secp256k1_bulletproof_ipa_msm() is untouched; the prover's calculate_commitment_term() still routes through it. Verifier-only swap, prover CT contract preserved. The constant-time MSM profile for the prover is tracked separately in XRPLF#87. * Static helper ipa_verify_explicit() removed; tests/test_ipa.c carries its own copy of the round-by-round IPA-verify check. * fold_generators() and apply_ipa_folding_to_P() retained because tests/test_ipa.c still uses them. Tests. 11/11 ctest green (test_bulletproof_agg covers positive + negative paths for m in {1, 2} including v=0, v=1, v=UINT64_MAX, and the two tampered-commitment cases that exercise the rejection branch of the consolidated MSM).
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.
Self-contained vendor of
secp256k1_ecmult_multi_var(Pippenger/StrausMSM) from libsecp256k1 v0.7.1, supporting the upcoming
*_verify_batchAPI for compact-sigma + aggregated-BP batch verification (#88).
Companion CT prover-side profile tracked in #87.
Vendor layout (
third_party/secp256k1-msm/).hfiles +precomputed_ecmult.c(~2.3 MB of generator tabledata) copied from libsecp256k1
src/at tagv0.7.1, commit1a53f4961f337b4d166c25fce72ef0dc88806618. SeePROVENANCE.mpt_msm.c: single wrapper translation unit that includes thevendored headers and exposes the one external API symbol,
mpt_msm_variable_time. All upstream functions are file-static;no link-time collision with the still-linked libsecp256k1.
-Drenames (-Dsecp256k1_pre_g=mpt_secp256k1_pre_gand the
_128variant) to namespace the only non-static datasymbols (the generator precomputation tables, which the linked
libsecp256k1 also exports).
util.h: relative include"../include/secp256k1.h"changed to
<secp256k1.h>so it resolves through the linkedinstall. Only edit to upstream sources.
Self-containment
The vendor includes dependent internal types (
secp256k1_gej,secp256k1_scalar,secp256k1_fe, scratch-space layouts), not justecmult_impl.hand the WNAF helpers. This decouples the vendoredMSM's correctness from the linked libsecp256k1 binary's version, so
this PR does not change the existing libsecp256k1 Conan pin.
Threat model
mpt_msm_variable_timeis variable-time. Validator path only; theverifier has no secret inputs. The two-profile API shape
(
mpt_msm_variable_timevs the plannedmpt_msm_constant_time—#87) makes the constant-time requirement audit-visible at the call
site. Full threat-model treatment in
cmpt-ct-and-batch.tex(
internal-ripplex-research,proposed-changes-writeupbranch).Build integration
OBJECTlibrarympt-crypto-msm-vendor; linked intompt-crypto.-Wno-pedanticonly on the vendored TU; main library remainsunder
-Wall -Wextra -Wpedantic -Werror..pre-commit-config.yaml:third_party/excluded from stylehooks so the vendored upstream files stay close to upstream form
(clean diffs on re-sync). Large-file limit raised to 4 MB to
admit
precomputed_ecmult.c.Tests
tests/test_mpt_msm.c: calibration test that compares thevendored MSM output to a reference computed via the public
libsecp256k1 API (
tweak_mul+pubkey_combinein a loop) onrandomized inputs. Bit-identical match required across
N_TRIALS. Confirms scalar/point encoding conventions,group-element layout, and end-to-end correctness of the vendoring.
All 11 existing tests continue to pass.
Drift detection
None. We follow the same operational model as the Conan lockfile
under
conan/lockfile/(#95): pin known-good state, re-syncdeliberately when there is a reason (security fix, performance
gain). No automated tripwire — same as for Conan-managed
dependencies.
Out of scope (tracked separately)
mpt_msm_constant_timeprofile for the prover path: mpt_msm_constant_time: constant-time MSM profile for the prover path #87.*_verify_batchAPI for the four sigma proofs and aggregatedBP: *_verify_batch: batched verification for compact sigma + aggregated BP #88.