Skip to content

chore: crypto primitives external audit response 0#22263

Merged
johnathan79717 merged 6 commits into
merge-train/barretenbergfrom
jh/crypto-primitives-external-audit-response
Apr 2, 2026
Merged

chore: crypto primitives external audit response 0#22263
johnathan79717 merged 6 commits into
merge-train/barretenbergfrom
jh/crypto-primitives-external-audit-response

Conversation

@johnathan79717

Copy link
Copy Markdown
Contributor

Audit Context

Addresses findings from the "Aztec - Cryptographic Primitives" external audit. This is response 0, covering the findings that have straightforward fixes.

Changes Made

Finding 1: Off-Curve Proof Commitment Crashes WASM Verifier
Replace BB_ASSERT(val.on_curve()) with explicit throw_or_abort in both FrCodec and U256Codec deserialization paths (field_conversion.hpp). This routes the error through the standard error path that is catchable by bbapi's try-catch in native builds, rather than going through assert_failure.

Finding 2: WASM Process DOS via Oversized Polynomial in Prover Commit Path
No changes in this PR. Requires a WASM-compatible recovery boundary (setjmp/longjmp or extending try_catch_shim.hpp). Will be addressed in a follow-up.

Finding 3: SRS Downloaded Using HTTP
No changes in this PR. Already mitigated by SHA-256 chunk hash verification (PR #21113). Switching to HTTPS requires resolving the OpenSSL cross-compilation dependency. Deferred.

Finding 4: bbapi Unix Socket Accepts Unauthenticated SRS Replacement

  • Add chmod(socket_path, 0600) after bind() on both macOS and Linux socket paths, matching the 0600 mode already used for the SHM transport.
  • Add null-guard to init_bn254_mem_crs_factory() to prevent replacing an already-initialized SRS, matching the existing guards on init_bn254_net_crs_factory and init_bn254_file_crs_factory.

Finding 5: Latent Shift-UB in get_scalar_slice
Add static_assert(MAX_SLICE_BITS < 64, ...) to encode the invariant that the shift in get_scalar_slice remains well-defined.

Finding 6: batch_commit() Subspan Constructed Before Bounds Check
Move the SRS bounds check before the subspan() call in batch_commit(). std::span::subspan() has UB when offset > size(). This brings batch_commit in line with commit() which already validates first.

Finding 7: Witness Polynomial Coefficients Vulnerable to Leakage
No changes. Threat model does not support this being a real vector: PXE in an extension runs in a separate origin, and for embedded wallets there is no trust boundary. Not prioritized.

Finding 8: BitVector::set() Non-Atomic RMW Has No Thread-Safety Guard
Add NOT THREAD-SAFE documentation to BitVector class noting that concurrent set() calls on indices in the same 64-bit word will race. Current usage is safe due to per-thread BucketAccumulators ownership.

Finding 9: batch_mul Mutates Scalars Through const Interface
Change batch_mul's public interface from std::span<const Fr> to std::span<Fr>, making the mutation contract explicit. The MSM internally converts scalars from/to Montgomery form, so callers must provide mutable scalars. Updated HyperNova prover/verifier wrappers (drop const) and IPA reduce_batch_opening_claim (mutable copy).

Checklist

  • Confirmed and documented security issues found
  • Verified that tests cover all critical paths
  • Verified build passes (ninja clean build)
  • Ran ecc_tests (830 passed), srs_tests (29 passed), commitment_schemes_tests (88 passed), hypernova_tests (9 passed)

…onversion

Replace BB_ASSERT(val.on_curve()) with an explicit throw_or_abort call in
both FrCodec and U256Codec deserialization paths. BB_ASSERT always aborts
via assert_failure(); throw_or_abort follows the standard error path that
is catchable by bbapi's try-catch in native builds.
Add chmod(0600) after bind() on both macOS and Linux socket paths,
matching the permission mode already used for the SHM transport.

Add null-guard to init_bn254_mem_crs_factory() to prevent replacing
an already-initialized SRS, matching the existing guards on the
net and file CRS factory initializers.
Encodes the invariant that MAX_SLICE_BITS < 64 so that get_scalar_slice's
1ULL << lo_slice_bits shift remains well-defined. Currently MAX_SLICE_BITS
is 20, far from the threshold, but this documents the constraint explicitly.
Move the SRS bounds check before the subspan() call in batch_commit().
std::span::subspan() has UB when offset > size(); validating first
eliminates this and brings batch_commit in line with commit().
Document that BitVector::set() performs a non-atomic read-modify-write
and is not safe for concurrent use on indices in the same 64-bit word.
Current usage is safe due to per-thread BucketAccumulators ownership.
Change batch_mul's public interface from std::span<const Fr> to
std::span<Fr>, making the mutation contract explicit. The MSM internally
converts scalars from/to Montgomery form, so callers must provide
mutable scalars. This eliminates the const_cast UB risk for callers
that pass genuinely const-backed memory.

Updated call sites: HyperNova prover/verifier wrappers (drop const),
IPA reduce_batch_opening_claim (mutable copy of scalars).
@johnathan79717 johnathan79717 added the ci-barretenberg Run all barretenberg/cpp checks. label Apr 2, 2026
@johnathan79717 johnathan79717 enabled auto-merge (squash) April 2, 2026 12:40

@iakovenkos iakovenkos left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for addressing these issues!

@johnathan79717 johnathan79717 merged commit 5c2e6d9 into merge-train/barretenberg Apr 2, 2026
21 of 25 checks passed
@johnathan79717 johnathan79717 deleted the jh/crypto-primitives-external-audit-response branch April 2, 2026 13:24
AztecBot added a commit that referenced this pull request Apr 2, 2026
…lidation

PR #22263 replaced BB_ASSERT(val.on_curve()) with throw_or_abort() in
field_conversion.hpp. This bypasses BB_DISABLE_ASSERTS() and causes
batch_check to crash when deserializing corrupted IPA proof points.

Wrap batch_check internals in try-catch so corrupted proofs trigger
bisection instead of terminating the process.
johnathan79717 pushed a commit that referenced this pull request Apr 2, 2026
## Summary

PR #22263 replaced `BB_ASSERT(val.on_curve())` with `throw_or_abort()`
in `field_conversion.hpp` for the external audit response. This bypasses
`BB_DISABLE_ASSERTS()` and causes
`ChonkBatchVerifierTests.RandomMixedBatches` to crash when deserializing
corrupted IPA proof points during `batch_check()`.

Added try-catch in `batch_check()` so exceptions from corrupted proof
data return `false` (triggering bisection) instead of terminating the
process. This is consistent with the existing try-catch in
`parallel_reduce()`.

All 29 chonk tests pass.

Full analysis:
https://gist.github.com/AztecBot/71089def650112d95757a7d3af6c0d67

ClaudeBox log: https://claudebox.work/s/fd385651d6fa6262?run=1
AztecBot added a commit that referenced this pull request Apr 2, 2026
…d proofs

PR #22263 replaced BB_ASSERT(val.on_curve()) with throw_or_abort in
field_conversion.hpp. Unlike BB_ASSERT, throw_or_abort is not gated by
BB_DISABLE_ASSERTS(), so corrupted IPA proof data now throws
std::runtime_error during deserialization in batch_check(). This
crashed ChonkBatchVerifierTests.RandomMixedBatches which relies on
graceful failure handling for tampered proofs.

Wrap batch_reduce_verify in try-catch so exceptions trigger bisection
(isolating the bad proof) instead of crashing.
github-merge-queue Bot pushed a commit that referenced this pull request Apr 2, 2026
BEGIN_COMMIT_OVERRIDE
fix: verify accumulated pairing points in native ChonkVerifier (#22224)
chore: enable _GLIBCXX_DEBUG in debug build presets (#22218)
feat: add --memory_profile_out flag for Chonk memory profiling (#22145)
fix: disable max capacity test in debug + tiny gate separator
improvements (#22215)
fix: WASM build for memory_profile.cpp (#22231)
fix: translator audit fixes (#22242)
fix: remove constexpr from functions using std::vector for
_GLIBCXX_DEBUG compat (#22239)
fix: pippenger edge case (#22256)
fix: avoid dereferencing past-the-end vector iterators in serialize.hpp
(#22261)
chore: crypto primitives external audit response 0 (#22263)
feat: switch memory profiling from peak RSS to live heap usage (#22266)
fix: replace UB end-iterator dereference in serialize.hpp (#22262)
fix: catch exceptions in ChonkBatchVerifier::batch_check (#22270)
END_COMMIT_OVERRIDE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci-barretenberg Run all barretenberg/cpp checks.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants