Commit ba10097
committed
perf(bp): batched aggregated-BP verification via RLC stacking (part of #88)
Adds secp256k1_bulletproof_verify_batch_agg: BBB+18 sec. 6.1
random-linear-combination batching that verifies n_proofs aggregated
Bulletproofs in a single mpt_msm_variable_time call. Stacked on
API
---
int secp256k1_bulletproof_verify_batch_agg(
ctx, G_vec, H_vec, /* sized for max(m_vec[i]) */
proofs, proof_lens,
commitment_C_vecs, m_vec,
pk_base,
context_ids,
n_proofs);
Mixed-m batches are supported: G_vec / H_vec are sized for the
largest m and lower-m proofs touch only a prefix.
Math
----
For each proof i, the same E1_i + c_i*E2_i = 0 residual from #100
holds. The batch verifier checks
sum_i rho^i * (E1_i + c_i * E2_i) = 0
with rho = H("MPT_BP_VERIFY_BATCH" || c_0 || ... || c_{n-1}).
Each c_i transitively binds proof_i's bytes (incl. commitments and
context_id) via the FS chain, so rho binds every batch input.
The shared generators G_vec, H_vec, pk_base, U contribute one MSM
term each regardless of batch size because their per-proof
coefficients are SUMMED into the corresponding accumulator before
the MSM is built. This collapses ~B * (2n + 2*log n + m + 6) terms
down to ~(2*max_n + 2) + B * (m + 4 + 2*log n).
Soundness: a single invalid proof makes its residual non-zero, and
Schwartz-Zippel on the freshly-derived rho gives <= n_proofs / q
rejection probability for a malicious batch. rho == 0 is explicitly
rejected (~2^-256).
Refactor
--------
Factored the per-proof derivation (parse, FS y/z/x, delta,
y_inv_powers, IPA round challenges u/uinv, s_G, ipa_transcript_id,
ux_scalar, intra-proof c_scalar) into bp_proof_state_init /
bp_proof_state_free. secp256k1_bulletproof_verify_agg now uses
the same state setup as the batch verifier (single-proof = batch
of one with rho = 1).
Perf (Apple M-series, m=2)
--------------------------
B=8: serial 13.3 ms, batch 3.46 ms (3.85x)
B=64: serial 108 ms, batch 18.0 ms (5.98x, 0.28 ms/proof)
Beats #88's 2-4x estimate; gap comes from the shared-generator
amortisation: at B=64 the 256 G_k+H_k slots are paid once instead
of 64 times.
Tests
-----
New tests/test_bulletproof_batch.c covers:
- n_proofs in {1, 2, 8, 64} with uniform m=2
- n_proofs=4 with mixed m in {1, 2}
- positive: each proof verifies individually AND batch verifies
- negative: tamper the last proof's last commitment -> batch
must reject (exercises the shared-accumulator rejection path)
- throughput benchmark vs serial (B=8 and B=64)
All 12 ctests green. Pre-commit + clang-format clean.
Out of scope
------------
- Cross-proof MSM amortisation for the four compact sigma families
(also mentioned in #88) is a separate mechanism (no RLC; reuses
shared CMPT generators); ship as a follow-up PR.
- rippled-side integration.1 parent 6a5016d commit ba10097
4 files changed
Lines changed: 1143 additions & 458 deletions
File tree
- include
- src
- tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
265 | 265 | | |
266 | 266 | | |
267 | 267 | | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
268 | 302 | | |
269 | 303 | | |
270 | 304 | | |
| |||
0 commit comments