Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ cd ..
# - Generate a hash for versioning: sha256sum bb-civc-inputs.tar.gz
# - Upload the compressed results: aws s3 cp bb-civc-inputs.tar.gz s3://aztec-ci-artifacts/protocol/bb-civc-inputs-[hash(0:8)].tar.gz
# Note: In case of the "Test suite failed to run ... Unexpected token 'with' " error, need to run: docker pull aztecprotocol/build:3.0
pinned_civc_inputs_url="https://aztec-ci-artifacts.s3.us-east-2.amazonaws.com/protocol/bb-civc-inputs-33fe085e.tar.gz"
pinned_civc_inputs_url="https://aztec-ci-artifacts.s3.us-east-2.amazonaws.com/protocol/bb-civc-inputs-1e546faa.tar.gz"

# For easily rerunning the inputs generation
if [[ "${1:-}" == "--update_inputs" ]]; then
Expand Down
26 changes: 16 additions & 10 deletions barretenberg/cpp/src/barretenberg/client_ivc/acir_bincode_mocks.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,24 +79,25 @@ inline std::vector<uint8_t> create_simple_kernel(size_t vk_size, bool is_init_ke
Acir::FunctionInput input{ { Acir::ConstantOrWitnessEnum::Witness{ i } }, BIT_COUNT };
vk_inputs.push_back(input);
}
Acir::FunctionInput key_hash{ { Acir::ConstantOrWitnessEnum::Witness{ static_cast<uint32_t>(vk_size) } },
BIT_COUNT };
size_t total_num_witnesses = /* vk */ vk_size + /* key_hash */ 1;

// Modeled after noir-projects/mock-protocol-circuits/crates/mock-private-kernel-init/src/main.nr
// We mock the init or tail kernels using OINK or PG respectively.
Acir::BlackBoxFuncCall::RecursiveAggregation recursion{
.verification_key = vk_inputs,
.proof = {},
.public_inputs = {},
// NOTE: If this starts failing after key hash becomes required need to pass as witness! (possibly after the VK,
// adding +1 to witness index below)
.key_hash = Acir::FunctionInput{ { Acir::ConstantOrWitnessEnum::Witness{ Acir::Witness{ 0 } } }, BIT_COUNT },
.proof_type = is_init_kernel ? acir_format::PROOF_TYPE::OINK : acir_format::PROOF_TYPE::PG
};
Acir::BlackBoxFuncCall::RecursiveAggregation recursion{ .verification_key = vk_inputs,
.proof = {},
.public_inputs = {},
.key_hash = key_hash,
.proof_type = is_init_kernel
? acir_format::PROOF_TYPE::OINK
: acir_format::PROOF_TYPE::PG };

Acir::BlackBoxFuncCall black_box_call;
black_box_call.value = recursion;

circuit.opcodes.push_back(Acir::Opcode{ Acir::Opcode::BlackBoxFuncCall{ black_box_call } });
circuit.current_witness_index = static_cast<uint32_t>(vk_inputs.size());
circuit.current_witness_index = static_cast<uint32_t>(total_num_witnesses);
circuit.expression_width = Acir::ExpressionWidth{ Acir::ExpressionWidth::Bounded{ 3 } };

// Create the program with the circuit
Expand All @@ -120,6 +121,11 @@ inline std::vector<uint8_t> create_kernel_witness(const std::vector<bb::fr>& app
ss << app_vk_fields[i];
kernel_witness.stack.back().witness.value[Witnesses::Witness{ i }] = ss.str();
}
std::stringstream ss;
ss << crypto::Poseidon2<crypto::Poseidon2Bn254ScalarFieldParams>::hash(app_vk_fields);
kernel_witness.stack.back().witness.value[Witnesses::Witness{ static_cast<uint32_t>(app_vk_fields.size()) }] =
ss.str();

return kernel_witness.bincodeSerialize();
}

Expand Down
17 changes: 4 additions & 13 deletions barretenberg/cpp/src/barretenberg/flavor/flavor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,13 +184,8 @@ class NativeVerificationKey_ : public PrecomputedCommitments {
*/
fr hash()
{
fr challenge = crypto::Poseidon2<crypto::Poseidon2Bn254ScalarFieldParams>::hash(this->to_field_elements());
// match the parameter used in stdlib, which is derived from cycle_scalar (is 128)
static constexpr size_t LO_BITS = fr::Params::MAX_BITS_PER_ENDOMORPHISM_SCALAR;

auto converted = static_cast<uint256_t>(challenge);
uint256_t lo = converted.slice(0, LO_BITS);
return lo;
fr vk_hash = crypto::Poseidon2<crypto::Poseidon2Bn254ScalarFieldParams>::hash(this->to_field_elements());
return vk_hash;
}

/**
Expand Down Expand Up @@ -253,12 +248,8 @@ class StdlibVerificationKey_ : public PrecomputedCommitments {
*/
FF hash(Builder& builder)
{
// use existing field-splitting code in cycle_scalar
FF challenge = stdlib::poseidon2<Builder>::hash(builder, to_field_elements());
using cycle_scalar = typename stdlib::cycle_group<Builder>::cycle_scalar;
const cycle_scalar scalar = cycle_scalar(challenge);
scalar.lo.create_range_constraint(cycle_scalar::LO_BITS);
return scalar.lo;
FF vk_hash = stdlib::poseidon2<Builder>::hash(builder, to_field_elements());
return vk_hash;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ using FlavorTypes = testing::Types<UltraFlavor, UltraKeccakFlavor, UltraRollupFl
TYPED_TEST_SUITE(NativeVerificationKeyTests, FlavorTypes);

/**
* @brief Checks that the hash produced from calling to_field_elements and then add_to_hash_buffer is the same as the
* hash() call and also the same as the add_hash_to_transcript.
* @brief Checks that the hash produced from calling to_field_elements and then add_to_independent_hash_buffer is the
* same as the hash() call and also the same as the add_hash_to_transcript.
*
*/
TYPED_TEST(NativeVerificationKeyTests, VKHashingConsistency)
Expand All @@ -56,9 +56,9 @@ TYPED_TEST(NativeVerificationKeyTests, VKHashingConsistency)
std::vector<fr> vk_field_elements = vk.to_field_elements();
NativeTranscript transcript;
for (const auto& field_element : vk_field_elements) {
transcript.add_to_hash_buffer("vk_element", field_element);
transcript.add_to_independent_hash_buffer("vk_element", field_element);
}
fr vkey_hash_1 = transcript.get_challenge<fr>("vk_hash");
fr vkey_hash_1 = transcript.hash_independent_buffer("vk_hash");
// Second method of hashing: using hash().
fr vkey_hash_2 = vk.hash();
EXPECT_EQ(vkey_hash_1, vkey_hash_2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ using FlavorTypes = testing::Types<UltraRecursiveFlavor_<UltraCircuitBuilder>,
TYPED_TEST_SUITE(StdlibVerificationKeyTests, FlavorTypes);

/**
* @brief Checks that the hash produced from calling to_field_elements and then add_to_hash_buffer is the same as the
* hash() call and also the same as the add_hash_to_transcript.
* @brief Checks that the hash produced from calling to_field_elements and then add_to_independent_hash_buffer is the
* same as the hash() call and also the same as the add_hash_to_transcript.
*
*/
TYPED_TEST(StdlibVerificationKeyTests, VKHashingConsistency)
Expand Down Expand Up @@ -68,9 +68,9 @@ TYPED_TEST(StdlibVerificationKeyTests, VKHashingConsistency)
std::vector<FF> vk_field_elements = vk.to_field_elements();
StdlibTranscript transcript;
for (const auto& field_element : vk_field_elements) {
transcript.add_to_hash_buffer("vk_element", field_element);
transcript.add_to_independent_hash_buffer("vk_element", field_element);
}
FF vkey_hash_1 = transcript.template get_challenge<FF>("vk_hash");
FF vkey_hash_1 = transcript.hash_independent_buffer("vk_hash");
// Second method of hashing: using hash().
FF vkey_hash_2 = vk.hash(outer_builder);
EXPECT_EQ(vkey_hash_1.get_value(), vkey_hash_2.get_value());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ template <typename Flavor> void OinkRecursiveVerifier_<Flavor>::verify()
FF vkey_hash = decider_vk->vk_and_hash->vk->add_hash_to_transcript(domain_separator, *transcript);
vinfo("vk hash in Oink recursive verifier: ", vkey_hash);
vinfo("expected vk hash: ", decider_vk->vk_and_hash->hash);
// Check that the vk hash matches the hash of the verification key
decider_vk->vk_and_hash->hash.assert_equal(vkey_hash);

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.

core change

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.

maybe worth a comment explanation?


size_t num_public_inputs =
static_cast<size_t>(static_cast<uint32_t>(decider_vk->vk_and_hash->vk->num_public_inputs.get_value()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ template <typename RecursiveFlavor> class RecursiveVerifierTest : public testing
}
// Check the size of the recursive verifier
if constexpr (std::same_as<RecursiveFlavor, MegaZKRecursiveFlavor_<UltraCircuitBuilder>>) {
uint32_t NUM_GATES_EXPECTED = 870572;
uint32_t NUM_GATES_EXPECTED = 870546;

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.

big moves. Is it clear what this is from?

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.

I guess splitting a 254 challenge into two adds some gates.

BB_ASSERT_EQ(static_cast<uint32_t>(outer_circuit.get_num_finalized_gates()),
NUM_GATES_EXPECTED,
"MegaZKHonk Recursive verifier changed in Ultra gate count! Update this value if you "
Expand Down
7 changes: 3 additions & 4 deletions barretenberg/cpp/src/barretenberg/transcript/transcript.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -452,11 +452,10 @@ template <typename TranscriptParams> class BaseTranscript {
*/
Fr hash_independent_buffer(const std::string& label)
{
Fr new_challenge = TranscriptParams::hash(independent_hash_buffer);
std::array<Fr, 2> new_challenges = TranscriptParams::split_challenge(new_challenge);
Fr buffer_hash = TranscriptParams::hash(independent_hash_buffer);
independent_hash_buffer.clear();
add_to_hash_buffer(label, new_challenge);
return new_challenges[0];
add_to_hash_buffer(label, buffer_hash);

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.

👍

return buffer_hash;
}

/**
Expand Down
5 changes: 1 addition & 4 deletions yarn-project/stdlib/src/hash/hash.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { GeneratorIndex } from '@aztec/constants';
import { toBigIntBE } from '@aztec/foundation/bigint-buffer';
import { poseidon2Hash, poseidon2HashWithSeparator, sha256ToField } from '@aztec/foundation/crypto';
import type { EthAddress } from '@aztec/foundation/eth-address';
import { Fr } from '@aztec/foundation/fields';
Expand All @@ -13,9 +12,7 @@ import type { AztecAddress } from '../aztec-address/index.js';
*/
export async function hashVK(keyAsFields: Fr[]): Promise<Fr> {
// Should match the implementation in barretenberg/cpp/src/barretenberg/flavor/flavor.hpp > hash()
const hash = (await poseidon2Hash(keyAsFields)).toBuffer();
// Taking the last 16 bytes (128 bits) of the hash.
return new Fr(toBigIntBE(hash.subarray(Fr.SIZE_IN_BYTES - 16)));
return await poseidon2Hash(keyAsFields);
}

/**
Expand Down
Loading