Skip to content

Commit 9d65f09

Browse files
committed
fix: minor bbapi fuzzing results
Small cleanliness. Also, a separate requirement from alpha team wanted a fixed proof size to prevent any malleability concerns from adding 0s. It's easier for us to make sure this buffer is the correct size. Closes https://linear.app/aztec-labs/issue/A-382 (Investigate issues on malleable tx proofs)
1 parent b0c1e78 commit 9d65f09

File tree

5 files changed

+264
-6
lines changed

5 files changed

+264
-6
lines changed

barretenberg/cpp/src/barretenberg/bbapi/bbapi_chonk.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ ChonkAccumulate::Response ChonkAccumulate::execute(BBApiRequest& request) &&
6262
precomputed_vk = nullptr;
6363
} else if (request.vk_policy == VkPolicy::DEFAULT || request.vk_policy == VkPolicy::CHECK) {
6464
if (!request.loaded_circuit_vk.empty()) {
65+
validate_vk_size<Chonk::MegaVerificationKey>(request.loaded_circuit_vk);
6566
precomputed_vk = from_buffer<std::shared_ptr<Chonk::MegaVerificationKey>>(request.loaded_circuit_vk);
6667

6768
if (request.vk_policy == VkPolicy::CHECK) {
@@ -132,8 +133,20 @@ ChonkProve::Response ChonkProve::execute(BBApiRequest& request) &&
132133
ChonkVerify::Response ChonkVerify::execute(const BBApiRequest& /*request*/) &&
133134
{
134135
BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
136+
137+
using VerificationKey = Chonk::MegaVerificationKey;
138+
validate_vk_size<VerificationKey>(vk);
139+
135140
// Deserialize the hiding kernel verification key directly from buffer
136-
auto hiding_kernel_vk = std::make_shared<Chonk::MegaVerificationKey>(from_buffer<Chonk::MegaVerificationKey>(vk));
141+
auto hiding_kernel_vk = std::make_shared<VerificationKey>(from_buffer<VerificationKey>(vk));
142+
143+
// Validate proof size using VK's num_public_inputs before expensive verification
144+
const size_t expected_proof_size =
145+
static_cast<size_t>(hiding_kernel_vk->num_public_inputs) + ChonkProof::PROOF_LENGTH_WITHOUT_PUB_INPUTS;
146+
if (proof.size() != expected_proof_size) {
147+
throw_or_abort("proof has wrong size: expected " + std::to_string(expected_proof_size) + ", got " +
148+
std::to_string(proof.size()));
149+
}
137150

138151
// Verify the proof using ChonkNativeVerifier
139152
auto vk_and_hash = std::make_shared<ChonkNativeVerifier::VKAndHash>(hiding_kernel_vk);
@@ -198,6 +211,8 @@ ChonkCheckPrecomputedVk::Response ChonkCheckPrecomputedVk::execute([[maybe_unuse
198211
throw_or_abort("Missing precomputed VK");
199212
}
200213

214+
validate_vk_size<Chonk::MegaVerificationKey>(circuit.verification_key);
215+
201216
// Deserialize directly from buffer
202217
auto precomputed_vk = from_buffer<std::shared_ptr<Chonk::MegaVerificationKey>>(circuit.verification_key);
203218

barretenberg/cpp/src/barretenberg/bbapi/bbapi_shared.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99

1010
#include "barretenberg/chonk/chonk.hpp"
11+
#include "barretenberg/common/throw_or_abort.hpp"
1112
#include "barretenberg/dsl/acir_format/acir_format.hpp"
1213
#include "barretenberg/honk/execution_trace/mega_execution_trace.hpp"
1314
#include <cstdint>
@@ -16,6 +17,21 @@
1617

1718
namespace bb::bbapi {
1819

20+
/**
21+
* @brief Validate verification key size before deserialization
22+
* @tparam VK The verification key type
23+
* @param vk_bytes The serialized verification key bytes
24+
* @throws If the size doesn't match the expected size for the VK type
25+
*/
26+
template <typename VK> inline void validate_vk_size(const std::vector<uint8_t>& vk_bytes)
27+
{
28+
const size_t expected_size = VK::calc_num_data_types() * sizeof(bb::fr);
29+
if (vk_bytes.size() != expected_size) {
30+
throw_or_abort("verification key has wrong size: expected " + std::to_string(expected_size) + ", got " +
31+
std::to_string(vk_bytes.size()));
32+
}
33+
}
34+
1935
/**
2036
* @enum VkPolicy
2137
* @brief Policy for handling verification keys during IVC accumulation

barretenberg/cpp/src/barretenberg/bbapi/bbapi_ultra_honk.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,14 @@ bool _verify(const std::vector<uint8_t>& vk_bytes,
138138
using Transcript = typename Flavor::Transcript;
139139
using DataType = typename Transcript::DataType;
140140

141+
// Validate VK size upfront before deserialization
142+
const size_t expected_vk_size = VerificationKey::calc_num_data_types() * sizeof(bb::fr);
143+
if (vk_bytes.size() != expected_vk_size) {
144+
info(
145+
"Proof verification failed: invalid VK size. Expected ", expected_vk_size, " bytes, got ", vk_bytes.size());
146+
return false;
147+
}
148+
141149
std::shared_ptr<VerificationKey> vk = std::make_shared<VerificationKey>(from_buffer<VerificationKey>(vk_bytes));
142150
auto vk_and_hash = std::make_shared<VKAndHash>(vk);
143151

@@ -335,10 +343,13 @@ CircuitVerify::Response CircuitVerify::execute(BB_UNUSED const BBApiRequest& req
335343
VkAsFields::Response VkAsFields::execute(BB_UNUSED const BBApiRequest& request) &&
336344
{
337345
BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
338-
std::vector<bb::fr> fields;
346+
347+
using VK = UltraFlavor::VerificationKey;
348+
validate_vk_size<VK>(verification_key);
339349

340350
// Standard UltraHonk flavors
341-
auto vk = from_buffer<UltraFlavor::VerificationKey>(verification_key);
351+
auto vk = from_buffer<VK>(verification_key);
352+
std::vector<bb::fr> fields;
342353
fields = vk.to_field_elements();
343354

344355
return { std::move(fields) };
@@ -347,10 +358,13 @@ VkAsFields::Response VkAsFields::execute(BB_UNUSED const BBApiRequest& request)
347358
MegaVkAsFields::Response MegaVkAsFields::execute(BB_UNUSED const BBApiRequest& request) &&
348359
{
349360
BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
350-
std::vector<bb::fr> fields;
361+
362+
using VK = MegaFlavor::VerificationKey;
363+
validate_vk_size<VK>(verification_key);
351364

352365
// MegaFlavor for private function verification keys
353-
auto vk = from_buffer<MegaFlavor::VerificationKey>(verification_key);
366+
auto vk = from_buffer<VK>(verification_key);
367+
std::vector<bb::fr> fields;
354368
fields = vk.to_field_elements();
355369

356370
return { std::move(fields) };
@@ -360,6 +374,8 @@ CircuitWriteSolidityVerifier::Response CircuitWriteSolidityVerifier::execute(BB_
360374
{
361375
BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
362376
using VK = UltraKeccakFlavor::VerificationKey;
377+
validate_vk_size<VK>(verification_key);
378+
363379
auto vk = std::make_shared<VK>(from_buffer<VK>(verification_key));
364380

365381
std::string contract = settings.disable_zk ? get_honk_solidity_verifier(vk) : get_honk_zk_solidity_verifier(vk);

0 commit comments

Comments
 (0)