Skip to content

chore: responding to external IPA audit#20334

Merged
notnotraju merged 11 commits into
merge-train/barretenbergfrom
rk/ipa-external-audit-1
Mar 12, 2026
Merged

chore: responding to external IPA audit#20334
notnotraju merged 11 commits into
merge-train/barretenbergfrom
rk/ipa-external-audit-1

Conversation

@notnotraju

@notnotraju notnotraju commented Feb 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Addresses findings from the Veridise external audit of the IPA (Inner Product Argument) implementation. All changes are in barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp and barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/ipa_recursive.test.cpp.

Commits

6b4582d — Fix BB_ASSERT syntax in IPA prover

The BB_ASSERT in compute_opening_proof used && to attach the error message string, which meant the string was part of the boolean expression (always truthy) rather than being passed as the diagnostic message via __VA_ARGS__. Changed && to , so the message is correctly forwarded to the assertion handler.

ecacc13 — Remove duplicate assertion in accumulate()

A BB_ASSERT_EQ after compute_opening_proof repeated the identical check (challenge_poly.evaluate(...) == evaluation) that already exists a few lines above. Removed the redundant copy.

21e9b99 — Add static_assert for log_poly_length >= 1

evaluate_challenge_poly computes log_poly_length - 1 in an unsigned loop bound — if log_poly_length were 0 this would underflow. Added a compile-time guard. (The default value CONST_ECCVM_LOG_N is safe, but this protects against future misuse of the template parameter.)

0422766 — Fix emplace_back on pre-sized vectors in recursive verifier

In reduce_verify_internal_recursive, msm_elements and msm_scalars are constructed with size 2 * log_poly_length + 2, but the last two entries were written via emplace_back — appending beyond the pre-allocated size and wasting circuit constraints on the default-constructed elements. Replaced with direct index assignment at [2 * log_poly_length] and [2 * log_poly_length + 1].

bbfb5de — Slice SRS elements in full_verify_recursive

The native IPA verifier slices the SRS to poly_length elements before the MSM, but full_verify_recursive passed the full SRS vector to batch_mul, which asserts scalars.size() == base_points.size(). If the SRS ever has more points than poly_length, this would fail. Added BB_ASSERT_GTE + resize(poly_length) to match native verifier behavior.

dec6be7 — Remove duplicate comment and inaccessible link

Removed a duplicate comment block (lines 178-180 were copies of lines 175-177) in the IPA prover documentation. Also removed an inaccessible HackMD link from the accumulate docstring.

f72bdd4 — Fix return value of reduce_verify_internal_recursive

The return statement accessed .verifier_accumulator on the result, but reduce_verify_internal_recursive already returns a VerifierAccumulator directly. Removed the erroneous member access.

a6a3b92 — Fix documentation of step 7 in reduce_verify_internal_recursive

Corrected the comment for the MSM computation to accurately reflect the formula: removed C' and fixed the sign within the last parenthesis, matching the actual code logic.

9e137aa — Add circuit satisfaction check to AccumulationAndFullRecursiveVerifier test

The test only verified running_truth_value (a witness boolean) but never checked that circuit constraints — including the claimed_G_zero.assert_equal(computed_G_zero) constraint from full_verify_recursive — are actually satisfied. Added EXPECT_TRUE(CircuitChecker::check(root_rollup)).

notnotraju and others added 6 commits February 10, 2026 11:56
…S__ instead of &&.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ck before compute_opening_proof.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…w in evaluate_challenge_poly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…index assignment instead.

The vectors were constructed with size 2*log_poly_length+2 but emplace_back appended
past the pre-allocated slots, leaving 2 default-zero entries that wasted circuit constraints.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ative verifier behavior.

batch_mul asserts strict size equality between points and scalars. The native verifier
passes only poly_length elements to pippenger, but full_verify_recursive was passing
all SRS points, which would abort if the VK contained more points than needed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…n accumulate docstring.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@notnotraju notnotraju self-assigned this Feb 10, 2026
@notnotraju notnotraju added ci-full Run all master checks. ci-no-fail-fast Sets NO_FAIL_FAST in the CI so the run is not aborted on the first failure labels Feb 10, 2026
msm_elements.emplace_back(-Commitment::one(builder));
msm_scalars.emplace_back(a_zero);
msm_scalars.emplace_back(generator_challenge * a_zero.madd(b_zero, { -opening_claim.opening_pair.evaluation }));
msm_elements[(2 * log_poly_length)] = -G_zero;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

we've only filled in the elements up to 2 * log_poly_length - 1, but we've allocated 2 * log_poly_length + 2, so emplace_back is not what we naively have in mind. (of course, default values are neutral, so the value of the MSM is the same, but wrongheaded nonetheless.)

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.

makes sense

const std::vector<Commitment> srs_elements = vk.get_monomial_points();
// In the native verifier, this uses pippenger. Here we use batch_mul.
std::vector<Commitment> srs_elements = vk.get_monomial_points();
BB_ASSERT_GTE(srs_elements.size(), poly_length, "Not enough SRS points for IPA!");

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

allow for more srs elements than the poly_length, makes a bit less brittle.


IPA<NativeCurve, log_poly_length>::compute_opening_proof(
ck, { challenge_poly, opening_pair }, prover_transcript);
BB_ASSERT_EQ(challenge_poly.evaluate(bb::fq(output_claim.opening_pair.challenge.get_value())),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

duplicated a few lines above.

@AztecBot

Copy link
Copy Markdown
Collaborator

⚠️ Docs Examples Validation Failed

Compile (Noir contracts)

(truncated)...
 contracts/recursive_verification_contract examples
contracts/counter_contract	compile contracts/counter_contract examples
contracts/counter_contract	Cache download of contract-0b765829b4d999ef.tar.gz failed.
contracts/bob_token_contract	Cache download of contract-8fb6667e027071d9.tar.gz failed.
contracts/nft	Cache download of contract-c1265935ab40a086.tar.gz failed.
contracts/nft_bridge	Cache download of contract-d68ae1e82ca89654.tar.gz failed.
contracts/recursive_verification_contract	Cache download of contract-4b51d3a5fe1c1dd9.tar.gz failed.
contracts/nft	error: `dep::aztec` path is deprecated
contracts/nft	  ┌─ examples/contracts/nft/src/nft.nr:2:5
contracts/nft	  │
contracts/nft	2 │ use dep::aztec::{macros::notes::note, protocol::traits::Packable};
contracts/nft	  │     --- Please use `::aztec` instead
contracts/nft	  │
contracts/nft	
contracts/nft	error: `dep::aztec` path is deprecated
contracts/nft	  ┌─ examples/contracts/nft/src/main.nr:8:9
contracts/nft	  │
contracts/nft	8 │     use dep::aztec::{
contracts/nft	  │         --- Please use `::aztec` instead
contracts/nft	  │
contracts/nft	
contracts/nft	error: `dep::aztec` path is deprecated
contracts/nft	   ┌─ examples/contracts/nft/src/main.nr:13:9
contracts/nft	   │
contracts/nft	13 │     use dep::aztec::messages::message_delivery::MessageDelivery;
contracts/nft	   │         --- Please use `::aztec` instead
contracts/nft	   │
contracts/nft	
contracts/counter_contract	error: `dep::aztec` path is deprecated
contracts/counter_contract	  ┌─ examples/contracts/counter_contract/src/main.nr:2:5
contracts/counter_contract	  │
contracts/counter_contract	2 │ use dep::aztec::macros::aztec;
contracts/counter_contract	  │     --- Please use `::aztec` instead
contracts/counter_contract	  │
contracts/counter_contract	
contracts/counter_contract	Aborting due to 1 previous error
parallel: This job failed:
compile contracts/counter_contract examples
contracts/nft	Aborting due to 3 previous errors
parallel: This job failed:
compile contracts/nft examples
Seq	Host	Starttime	JobRuntime	Send	Receive	Exitval	Signal	Command
1	:	1770728724.296	     1.802	0	329	1	0	compile contracts/counter_contract examples
3	:	1770728724.323	     1.776	0	738	1	0	compile contracts/nft examples

TypeScript validation

(truncated)...
 files
aztecjs_advanced	✓ @aztec/accounts: 27 .d.ts files
aztecjs_getting_started	Verifying linked packages...
aztecjs_connection	✓ @aztec/aztec.js: 77 .d.ts files
aztecjs_advanced	✓ @aztec/test-wallet: 8 .d.ts files
aztecjs_getting_started	✓ @aztec/aztec.js: 77 .d.ts files
aztecjs_connection	✓ @aztec/accounts: 27 .d.ts files
aztecjs_advanced	✓ @aztec/noir-contracts.js: 33 .d.ts files
aztecjs_connection	✓ @aztec/test-wallet: 8 .d.ts files
aztecjs_getting_started	✓ @aztec/accounts: 27 .d.ts files
aztecjs_advanced	✓ @aztec/ethereum: 85 .d.ts files
aztecjs_connection	✓ @aztec/noir-contracts.js: 33 .d.ts files
aztecjs_getting_started	✓ @aztec/test-wallet: 8 .d.ts files
aztecjs_getting_started	✓ @aztec/noir-contracts.js: 33 .d.ts files
aztecjs_advanced	✓ @aztec/stdlib: 477 .d.ts files
aztecjs_connection	✓ @aztec/stdlib: 477 .d.ts files
aztecjs_authwit	Type checking 'aztecjs_authwit'...
aztecjs_advanced	Type checking 'aztecjs_advanced'...
aztecjs_getting_started	Type checking 'aztecjs_getting_started'...
aztecjs_connection	Type checking 'aztecjs_connection'...
aztecjs_connection	✓ 'aztecjs_connection' validated successfully
aztecjs_connection	Cleaning up temporary files for 'aztecjs_connection'...
aztecjs_advanced	✓ 'aztecjs_advanced' validated successfully
aztecjs_advanced	Cleaning up temporary files for 'aztecjs_advanced'...
aztecjs_testing	validate_project aztecjs_testing
bob_token_contract	validate_project bob_token_contract
aztecjs_testing	�[38;2;188;109;208m---�[0m �[38;2;95;167;241m�[1mValidating aztecjs_testing�[0m �[38;2;188;109;208m---�[0m
aztecjs_testing	No custom contracts for 'aztecjs_testing', skipping codegen...
aztecjs_testing	Setting up yarn for 'aztecjs_testing'...
bob_token_contract	ERROR: Artifact not found for 'bob_token_contract': /home/aztec-dev/aztec-packages/docs/target/bob_token_contract-BobToken.json
parallel: This job failed:
validate_project bob_token_contract
Seq	Host	Starttime	JobRuntime	Send	Receive	Exitval	Signal	Command
3	:	1770728728.614	     4.935	0	1999	0	0	validate_project aztecjs_connection
1	:	1770728728.608	     4.957	0	2091	0	0	validate_project aztecjs_advanced
6	:	1770728733.569	     0.052	0	164	1	0	validate_project bob_token_contract
ERROR: Some project(s) failed validation

Action required: Please fix the docs examples or update them to match the current API.

cc @AztecProtocol/devrel

@suyash67 suyash67 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.

Thanks for such a neat PR, looks good!

@notnotraju notnotraju merged commit 1de23fb into merge-train/barretenberg Mar 12, 2026
10 checks passed
@notnotraju notnotraju deleted the rk/ipa-external-audit-1 branch March 12, 2026 12:07
github-merge-queue Bot pushed a commit that referenced this pull request Mar 12, 2026
BEGIN_COMMIT_OVERRIDE
chore: unify tests in ecc/curves and ecc/groups (#21392)
chore: `ecc/fields` ASM audit (#20892)
chore: audit the `ecc/field` extension field (#21409)
chore: responding to external IPA audit (#20334)
feat: committed sumcheck for batched Hiding Translator (#21376)
chore: documentation fixes for ECCVM after first external audit (#20348)
chore: Document RAM gate cost optimization opportunity (#21426)
refactor: rename MSGPACK_FIELDS to SERIALIZATION_FIELDS (#21175)
END_COMMIT_OVERRIDE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci-full Run all master checks. ci-no-fail-fast Sets NO_FAIL_FAST in the CI so the run is not aborted on the first failure

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants