diff --git a/barretenberg/cpp/scripts/test_civc_standalone_vks_havent_changed.sh b/barretenberg/cpp/scripts/test_civc_standalone_vks_havent_changed.sh index bde36d5cce32..c102e9862c06 100755 --- a/barretenberg/cpp/scripts/test_civc_standalone_vks_havent_changed.sh +++ b/barretenberg/cpp/scripts/test_civc_standalone_vks_havent_changed.sh @@ -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 diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/acir_bincode_mocks.hpp b/barretenberg/cpp/src/barretenberg/client_ivc/acir_bincode_mocks.hpp index dfcc40daf7f9..c1b209c12d86 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/acir_bincode_mocks.hpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/acir_bincode_mocks.hpp @@ -79,24 +79,25 @@ inline std::vector 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(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(vk_inputs.size()); + circuit.current_witness_index = static_cast(total_num_witnesses); circuit.expression_width = Acir::ExpressionWidth{ Acir::ExpressionWidth::Bounded{ 3 } }; // Create the program with the circuit @@ -120,6 +121,11 @@ inline std::vector create_kernel_witness(const std::vector& app ss << app_vk_fields[i]; kernel_witness.stack.back().witness.value[Witnesses::Witness{ i }] = ss.str(); } + std::stringstream ss; + ss << crypto::Poseidon2::hash(app_vk_fields); + kernel_witness.stack.back().witness.value[Witnesses::Witness{ static_cast(app_vk_fields.size()) }] = + ss.str(); + return kernel_witness.bincodeSerialize(); } diff --git a/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp index b588635eae02..566dbfdad7b4 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp @@ -184,13 +184,8 @@ class NativeVerificationKey_ : public PrecomputedCommitments { */ fr hash() { - fr challenge = crypto::Poseidon2::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(challenge); - uint256_t lo = converted.slice(0, LO_BITS); - return lo; + fr vk_hash = crypto::Poseidon2::hash(this->to_field_elements()); + return vk_hash; } /** @@ -253,12 +248,8 @@ class StdlibVerificationKey_ : public PrecomputedCommitments { */ FF hash(Builder& builder) { - // use existing field-splitting code in cycle_scalar - FF challenge = stdlib::poseidon2::hash(builder, to_field_elements()); - using cycle_scalar = typename stdlib::cycle_group::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::hash(builder, to_field_elements()); + return vk_hash; } /** diff --git a/barretenberg/cpp/src/barretenberg/flavor/native_verification_key.test.cpp b/barretenberg/cpp/src/barretenberg/flavor/native_verification_key.test.cpp index 0df12eb8fff2..849cc386a150 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/native_verification_key.test.cpp +++ b/barretenberg/cpp/src/barretenberg/flavor/native_verification_key.test.cpp @@ -35,8 +35,8 @@ using FlavorTypes = testing::Types 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("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); diff --git a/barretenberg/cpp/src/barretenberg/flavor/stdlib_verification_key.test.cpp b/barretenberg/cpp/src/barretenberg/flavor/stdlib_verification_key.test.cpp index fb81f6dd3c8b..455b9b3d10ce 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/stdlib_verification_key.test.cpp +++ b/barretenberg/cpp/src/barretenberg/flavor/stdlib_verification_key.test.cpp @@ -39,8 +39,8 @@ using FlavorTypes = testing::Types, 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) @@ -68,9 +68,9 @@ TYPED_TEST(StdlibVerificationKeyTests, VKHashingConsistency) std::vector 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("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()); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/oink_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/oink_recursive_verifier.cpp index 672b25d8ea54..1b095b261429 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/oink_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/oink_recursive_verifier.cpp @@ -53,6 +53,8 @@ template void OinkRecursiveVerifier_::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); size_t num_public_inputs = static_cast(static_cast(decider_vk->vk_and_hash->vk->num_public_inputs.get_value())); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp index 06d4bf15a171..4f2de57caee4 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp @@ -268,7 +268,7 @@ template class RecursiveVerifierTest : public testing } // Check the size of the recursive verifier if constexpr (std::same_as>) { - uint32_t NUM_GATES_EXPECTED = 870572; + uint32_t NUM_GATES_EXPECTED = 870546; BB_ASSERT_EQ(static_cast(outer_circuit.get_num_finalized_gates()), NUM_GATES_EXPECTED, "MegaZKHonk Recursive verifier changed in Ultra gate count! Update this value if you " diff --git a/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp b/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp index 7a5f9fe67ad0..05cdd154de21 100644 --- a/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp +++ b/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp @@ -452,11 +452,10 @@ template class BaseTranscript { */ Fr hash_independent_buffer(const std::string& label) { - Fr new_challenge = TranscriptParams::hash(independent_hash_buffer); - std::array 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); + return buffer_hash; } /** diff --git a/yarn-project/stdlib/src/hash/hash.ts b/yarn-project/stdlib/src/hash/hash.ts index 3091ba3ea7db..de5436c7e236 100644 --- a/yarn-project/stdlib/src/hash/hash.ts +++ b/yarn-project/stdlib/src/hash/hash.ts @@ -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'; @@ -13,9 +12,7 @@ import type { AztecAddress } from '../aztec-address/index.js'; */ export async function hashVK(keyAsFields: Fr[]): Promise { // 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); } /**