diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp index 071d24fd4a6d..61a06fc4dbc6 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp @@ -366,14 +366,12 @@ library TranscriptLib { function generateTranscript( Honk.Proof memory proof, bytes32[] calldata publicInputs, - uint256 circuitSize, - uint256 publicInputsSize, - uint256 pubInputsOffset + uint256 vkHash, + uint256 publicInputsSize ) internal pure returns (Transcript memory t) { Fr previousChallenge; - (t.relationParameters, previousChallenge) = generateRelationParametersChallenges( - proof, publicInputs, circuitSize, publicInputsSize, pubInputsOffset, previousChallenge - ); + (t.relationParameters, previousChallenge) = + generateRelationParametersChallenges(proof, publicInputs, vkHash, publicInputsSize, previousChallenge); (t.alphas, previousChallenge) = generateAlphaChallenges(previousChallenge, proof); @@ -403,13 +401,12 @@ library TranscriptLib { function generateRelationParametersChallenges( Honk.Proof memory proof, bytes32[] calldata publicInputs, - uint256 circuitSize, + uint256 vkHash, uint256 publicInputsSize, - uint256 pubInputsOffset, Fr previousChallenge ) internal pure returns (Honk.RelationParameters memory rp, Fr nextPreviousChallenge) { (rp.eta, rp.etaTwo, rp.etaThree, previousChallenge) = - generateEtaChallenge(proof, publicInputs, circuitSize, publicInputsSize, pubInputsOffset); + generateEtaChallenge(proof, publicInputs, vkHash, publicInputsSize); (rp.beta, rp.gamma, nextPreviousChallenge) = generateBetaAndGammaChallenges(previousChallenge, proof); } @@ -417,36 +414,33 @@ library TranscriptLib { function generateEtaChallenge( Honk.Proof memory proof, bytes32[] calldata publicInputs, - uint256 circuitSize, - uint256 publicInputsSize, - uint256 pubInputsOffset + uint256 vkHash, + uint256 publicInputsSize ) internal pure returns (Fr eta, Fr etaTwo, Fr etaThree, Fr previousChallenge) { - bytes32[] memory round0 = new bytes32[](3 + publicInputsSize + 12); - round0[0] = bytes32(circuitSize); - round0[1] = bytes32(publicInputsSize); - round0[2] = bytes32(pubInputsOffset); + bytes32[] memory round0 = new bytes32[](1 + publicInputsSize + 12); + round0[0] = bytes32(vkHash); for (uint256 i = 0; i < publicInputsSize - PAIRING_POINTS_SIZE; i++) { - round0[3 + i] = bytes32(publicInputs[i]); + round0[1 + i] = bytes32(publicInputs[i]); } for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) { - round0[3 + publicInputsSize - PAIRING_POINTS_SIZE + i] = FrLib.toBytes32(proof.pairingPointObject[i]); + round0[1 + publicInputsSize - PAIRING_POINTS_SIZE + i] = FrLib.toBytes32(proof.pairingPointObject[i]); } // Create the first challenge // Note: w4 is added to the challenge later on - round0[3 + publicInputsSize] = bytes32(proof.w1.x_0); - round0[3 + publicInputsSize + 1] = bytes32(proof.w1.x_1); - round0[3 + publicInputsSize + 2] = bytes32(proof.w1.y_0); - round0[3 + publicInputsSize + 3] = bytes32(proof.w1.y_1); - round0[3 + publicInputsSize + 4] = bytes32(proof.w2.x_0); - round0[3 + publicInputsSize + 5] = bytes32(proof.w2.x_1); - round0[3 + publicInputsSize + 6] = bytes32(proof.w2.y_0); - round0[3 + publicInputsSize + 7] = bytes32(proof.w2.y_1); - round0[3 + publicInputsSize + 8] = bytes32(proof.w3.x_0); - round0[3 + publicInputsSize + 9] = bytes32(proof.w3.x_1); - round0[3 + publicInputsSize + 10] = bytes32(proof.w3.y_0); - round0[3 + publicInputsSize + 11] = bytes32(proof.w3.y_1); + round0[1 + publicInputsSize] = bytes32(proof.w1.x_0); + round0[1 + publicInputsSize + 1] = bytes32(proof.w1.x_1); + round0[1 + publicInputsSize + 2] = bytes32(proof.w1.y_0); + round0[1 + publicInputsSize + 3] = bytes32(proof.w1.y_1); + round0[1 + publicInputsSize + 4] = bytes32(proof.w2.x_0); + round0[1 + publicInputsSize + 5] = bytes32(proof.w2.x_1); + round0[1 + publicInputsSize + 6] = bytes32(proof.w2.y_0); + round0[1 + publicInputsSize + 7] = bytes32(proof.w2.y_1); + round0[1 + publicInputsSize + 8] = bytes32(proof.w3.x_0); + round0[1 + publicInputsSize + 9] = bytes32(proof.w3.x_1); + round0[1 + publicInputsSize + 10] = bytes32(proof.w3.y_0); + round0[1 + publicInputsSize + 11] = bytes32(proof.w3.y_1); previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round0))); (eta, etaTwo) = splitChallenge(previousChallenge); @@ -1731,11 +1725,13 @@ abstract contract BaseHonkVerifier is IVerifier { uint256 immutable $N; uint256 immutable $LOG_N; + uint256 immutable $VK_HASH; uint256 immutable $NUM_PUBLIC_INPUTS; - constructor(uint256 _N, uint256 _logN, uint256 _numPublicInputs) { + constructor(uint256 _N, uint256 _logN, uint256 _vkHash, uint256 _numPublicInputs) { $N = _N; $LOG_N = _logN; + $VK_HASH = _vkHash; $NUM_PUBLIC_INPUTS = _numPublicInputs; } @@ -1764,9 +1760,7 @@ abstract contract BaseHonkVerifier is IVerifier { } // Generate the fiat shamir challenges for the whole protocol - Transcript memory t = TranscriptLib.generateTranscript( - p, publicInputs, vk.circuitSize, $NUM_PUBLIC_INPUTS, /*pubInputsOffset=*/ 1 - ); + Transcript memory t = TranscriptLib.generateTranscript(p, publicInputs, $VK_HASH, $NUM_PUBLIC_INPUTS); // Derive public input delta t.relationParameters.publicInputsDelta = computePublicInputDelta( @@ -2170,7 +2164,7 @@ abstract contract BaseHonkVerifier is IVerifier { } } -contract HonkVerifier is BaseHonkVerifier(N, LOG_N, NUMBER_OF_PUBLIC_INPUTS) { +contract HonkVerifier is BaseHonkVerifier(N, LOG_N, VK_HASH, NUMBER_OF_PUBLIC_INPUTS) { function loadVerificationKey() internal pure override returns (Honk.VerificationKey memory) { return HonkVerificationKey.loadVerificationKey(); } diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_zk_contract.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_zk_contract.hpp index 68883159fd71..d6d0fcae194d 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_zk_contract.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_zk_contract.hpp @@ -368,14 +368,12 @@ library ZKTranscriptLib { function generateTranscript( Honk.ZKProof memory proof, bytes32[] calldata publicInputs, - uint256 circuitSize, - uint256 publicInputsSize, - uint256 pubInputsOffset + uint256 vkHash, + uint256 publicInputsSize ) external pure returns (ZKTranscript memory t) { Fr previousChallenge; - (t.relationParameters, previousChallenge) = generateRelationParametersChallenges( - proof, publicInputs, circuitSize, publicInputsSize, pubInputsOffset, previousChallenge - ); + (t.relationParameters, previousChallenge) = + generateRelationParametersChallenges(proof, publicInputs, vkHash, publicInputsSize, previousChallenge); (t.alphas, previousChallenge) = generateAlphaChallenges(previousChallenge, proof); @@ -404,13 +402,12 @@ library ZKTranscriptLib { function generateRelationParametersChallenges( Honk.ZKProof memory proof, bytes32[] calldata publicInputs, - uint256 circuitSize, + uint256 vkHash, uint256 publicInputsSize, - uint256 pubInputsOffset, Fr previousChallenge ) internal pure returns (Honk.RelationParameters memory rp, Fr nextPreviousChallenge) { (rp.eta, rp.etaTwo, rp.etaThree, previousChallenge) = - generateEtaChallenge(proof, publicInputs, circuitSize, publicInputsSize, pubInputsOffset); + generateEtaChallenge(proof, publicInputs, vkHash, publicInputsSize); (rp.beta, rp.gamma, nextPreviousChallenge) = generateBetaAndGammaChallenges(previousChallenge, proof); } @@ -418,35 +415,33 @@ library ZKTranscriptLib { function generateEtaChallenge( Honk.ZKProof memory proof, bytes32[] calldata publicInputs, - uint256 circuitSize, - uint256 publicInputsSize, - uint256 pubInputsOffset + uint256 vkHash, + uint256 publicInputsSize ) internal pure returns (Fr eta, Fr etaTwo, Fr etaThree, Fr previousChallenge) { - bytes32[] memory round0 = new bytes32[](3 + publicInputsSize + 12); - round0[0] = bytes32(circuitSize); - round0[1] = bytes32(publicInputsSize); - round0[2] = bytes32(pubInputsOffset); + bytes32[] memory round0 = new bytes32[](1 + publicInputsSize + 12); + round0[0] = bytes32(vkHash); + for (uint256 i = 0; i < publicInputsSize - PAIRING_POINTS_SIZE; i++) { - round0[3 + i] = bytes32(publicInputs[i]); + round0[1 + i] = bytes32(publicInputs[i]); } for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) { - round0[3 + publicInputsSize - PAIRING_POINTS_SIZE + i] = FrLib.toBytes32(proof.pairingPointObject[i]); + round0[1 + publicInputsSize - PAIRING_POINTS_SIZE + i] = FrLib.toBytes32(proof.pairingPointObject[i]); } // Create the first challenge // Note: w4 is added to the challenge later on - round0[3 + publicInputsSize] = bytes32(proof.w1.x_0); - round0[3 + publicInputsSize + 1] = bytes32(proof.w1.x_1); - round0[3 + publicInputsSize + 2] = bytes32(proof.w1.y_0); - round0[3 + publicInputsSize + 3] = bytes32(proof.w1.y_1); - round0[3 + publicInputsSize + 4] = bytes32(proof.w2.x_0); - round0[3 + publicInputsSize + 5] = bytes32(proof.w2.x_1); - round0[3 + publicInputsSize + 6] = bytes32(proof.w2.y_0); - round0[3 + publicInputsSize + 7] = bytes32(proof.w2.y_1); - round0[3 + publicInputsSize + 8] = bytes32(proof.w3.x_0); - round0[3 + publicInputsSize + 9] = bytes32(proof.w3.x_1); - round0[3 + publicInputsSize + 10] = bytes32(proof.w3.y_0); - round0[3 + publicInputsSize + 11] = bytes32(proof.w3.y_1); + round0[1 + publicInputsSize] = bytes32(proof.w1.x_0); + round0[1 + publicInputsSize + 1] = bytes32(proof.w1.x_1); + round0[1 + publicInputsSize + 2] = bytes32(proof.w1.y_0); + round0[1 + publicInputsSize + 3] = bytes32(proof.w1.y_1); + round0[1 + publicInputsSize + 4] = bytes32(proof.w2.x_0); + round0[1 + publicInputsSize + 5] = bytes32(proof.w2.x_1); + round0[1 + publicInputsSize + 6] = bytes32(proof.w2.y_0); + round0[1 + publicInputsSize + 7] = bytes32(proof.w2.y_1); + round0[1 + publicInputsSize + 8] = bytes32(proof.w3.x_0); + round0[1 + publicInputsSize + 9] = bytes32(proof.w3.x_1); + round0[1 + publicInputsSize + 10] = bytes32(proof.w3.y_0); + round0[1 + publicInputsSize + 11] = bytes32(proof.w3.y_1); previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round0))); (eta, etaTwo) = splitChallenge(previousChallenge); @@ -1793,11 +1788,13 @@ abstract contract BaseZKHonkVerifier is IVerifier { uint256 immutable $N; uint256 immutable $LOG_N; + uint256 immutable $VK_HASH; uint256 immutable $NUM_PUBLIC_INPUTS; - constructor(uint256 _N, uint256 _logN, uint256 _numPublicInputs) { + constructor(uint256 _N, uint256 _logN, uint256 _vkHash, uint256 _numPublicInputs) { $N = _N; $LOG_N = _logN; + $VK_HASH = _vkHash; $NUM_PUBLIC_INPUTS = _numPublicInputs; } @@ -1834,9 +1831,7 @@ abstract contract BaseZKHonkVerifier is IVerifier { } // Generate the fiat shamir challenges for the whole protocol - ZKTranscript memory t = ZKTranscriptLib.generateTranscript( - p, publicInputs, vk.circuitSize, $NUM_PUBLIC_INPUTS, /*pubInputsOffset=*/ 1 - ); + ZKTranscript memory t = ZKTranscriptLib.generateTranscript(p, publicInputs, $VK_HASH, $NUM_PUBLIC_INPUTS); // Derive public input delta t.relationParameters.publicInputsDelta = computePublicInputDelta( @@ -2321,7 +2316,7 @@ abstract contract BaseZKHonkVerifier is IVerifier { } } -contract HonkVerifier is BaseZKHonkVerifier(N, LOG_N, NUMBER_OF_PUBLIC_INPUTS) { +contract HonkVerifier is BaseZKHonkVerifier(N, LOG_N, VK_HASH, NUMBER_OF_PUBLIC_INPUTS) { function loadVerificationKey() internal pure override returns (Honk.VerificationKey memory) { return HonkVerificationKey.loadVerificationKey(); } diff --git a/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp index 85261fce212e..7096559b7f65 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp @@ -197,9 +197,10 @@ class NativeVerificationKey_ : public PrecomputedCommitments { * @details Currently only used in testing. * @return FF */ - fr hash() + fr hash() const { - fr vk_hash = crypto::Poseidon2::hash(this->to_field_elements()); + // TODO(https://github.com/AztecProtocol/barretenberg/issues/1498): should hash be dependent on transcript? + fr vk_hash = Transcript::hash(this->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 0aa8110ddc1a..d008b67a1e8c 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/native_verification_key.test.cpp +++ b/barretenberg/cpp/src/barretenberg/flavor/native_verification_key.test.cpp @@ -68,12 +68,13 @@ TYPED_TEST(NativeVerificationKeyTests, VKHashingConsistency) { using Flavor = TypeParam; using VerificationKey = typename Flavor::VerificationKey; + using Transcript = typename Flavor::Transcript; VerificationKey vk(TestFixture::create_vk()); // First method of hashing: using to_field_elements and add_to_hash_buffer. std::vector vk_field_elements = vk.to_field_elements(); - NativeTranscript transcript; + Transcript transcript; for (const auto& field_element : vk_field_elements) { transcript.add_to_independent_hash_buffer("vk_element", field_element); } @@ -81,9 +82,7 @@ TYPED_TEST(NativeVerificationKeyTests, VKHashingConsistency) // Second method of hashing: using hash(). fr vkey_hash_2 = vk.hash(); EXPECT_EQ(vkey_hash_1, vkey_hash_2); - // TODO(https://github.com/AztecProtocol/barretenberg/issues/1427): Solidity verifier does not fiat shamir the full - // verification key. This will be fixed in a followup PR. - if constexpr (!IsAnyOf) { + if constexpr (!IsAnyOf) { // Third method of hashing: using add_hash_to_transcript. typename Flavor::Transcript transcript_2; fr vkey_hash_3 = vk.add_hash_to_transcript("", transcript_2); diff --git a/barretenberg/cpp/src/barretenberg/flavor/ultra_keccak_flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/ultra_keccak_flavor.hpp index 4ac708d94c3c..fe838b16dc12 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/ultra_keccak_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/ultra_keccak_flavor.hpp @@ -76,14 +76,11 @@ class UltraKeccakFlavor : public bb::UltraFlavor { */ fr add_hash_to_transcript(const std::string& domain_separator, Transcript& transcript) const override { - // TODO(https://github.com/AztecProtocol/barretenberg/issues/1427): We need to update this function to look - // like UltraFlavor's add_hash_to_transcript. Alternatively, the VerificationKey class will go away when we - // add pairing point aggregation to the solidity verifier. - uint64_t circuit_size = 1 << this->log_circuit_size; - transcript.add_to_hash_buffer(domain_separator + "vk_log_circuit_size", circuit_size); - transcript.add_to_hash_buffer(domain_separator + "vk_num_public_inputs", this->num_public_inputs); - transcript.add_to_hash_buffer(domain_separator + "vk_pub_inputs_offset", this->pub_inputs_offset); - return 0; + // This hash contains a hash of the entire vk - including all of the elements + const fr hash = this->hash(); + + transcript.add_to_hash_buffer(domain_separator + "vk_hash", hash); + return hash; } // Don't statically check for object completeness. diff --git a/barretenberg/cpp/src/barretenberg/honk/utils/honk_key_gen.hpp b/barretenberg/cpp/src/barretenberg/honk/utils/honk_key_gen.hpp index a26c0576c496..939242e77b59 100644 --- a/barretenberg/cpp/src/barretenberg/honk/utils/honk_key_gen.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/utils/honk_key_gen.hpp @@ -67,6 +67,7 @@ inline void output_vk_sol_ultra_honk(std::ostream& os, print_u256_const(1 << key->log_circuit_size, "N"); print_u256_const(key->log_circuit_size, "LOG_N"); print_u256_const(key->num_public_inputs, "NUMBER_OF_PUBLIC_INPUTS"); + print_u256_const(key->hash(), "VK_HASH"); os << "" "library " << class_name << " {\n" " function loadVerificationKey() internal pure returns (Honk.VerificationKey memory) {\n" diff --git a/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp b/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp index 29cf828a63ca..d93c1277ae83 100644 --- a/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp +++ b/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp @@ -330,6 +330,16 @@ template class BaseTranscript { */ void enable_manifest() { use_manifest = true; } + /** + * @brief Static hash method that forwards to TranscriptParams hash. + * @details This method allows hash to be called on the Transcript class directly, + * which is needed for verification key hashing. + * + * @param data Vector of field elements to hash + * @return Fr Hash result + */ + static Fr hash(const std::vector& data) { return TranscriptParams::hash(data); } + /** * @brief After all the prover messages have been sent, finalize the round by hashing all the data and then * create the number of requested challenges. diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp index 12ae4e808540..095cd9968ca4 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp @@ -86,10 +86,7 @@ template void OinkProver::execute_preamble_ro { PROFILE_THIS_NAME("OinkProver::execute_preamble_round"); fr vkey_hash = honk_vk->add_hash_to_transcript(domain_separator, *transcript); - // TODO(https://github.com/AztecProtocol/barretenberg/issues/1427): Add VK FS to solidity verifier. - if constexpr (!IsAnyOf) { - vinfo("vk hash in Oink prover: ", vkey_hash); - } + vinfo("vk hash in Oink prover: ", vkey_hash); for (size_t i = 0; i < proving_key->num_public_inputs(); ++i) { auto public_input_i = proving_key->public_inputs[i]; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/oink_verifier.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/oink_verifier.cpp index 6f0b1d3b9524..d6dd06cc241e 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/oink_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/oink_verifier.cpp @@ -46,11 +46,7 @@ template void OinkVerifier::verify() template void OinkVerifier::execute_preamble_round() { FF vkey_hash = verification_key->vk->add_hash_to_transcript(domain_separator, *transcript); - // TODO(https://github.com/AztecProtocol/barretenberg/issues/1427): Update solidity contract to generate vkey hash - // from transcript. - if constexpr (!IsAnyOf) { - vinfo("vk hash in Oink verifier: ", vkey_hash); - } + vinfo("vk hash in Oink verifier: ", vkey_hash); for (size_t i = 0; i < verification_key->vk->num_public_inputs; ++i) { auto public_input_i = diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_transcript.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_transcript.test.cpp index 9a670c375fe3..44821d0660fe 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_transcript.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_transcript.test.cpp @@ -63,15 +63,7 @@ template class UltraTranscriptTests : public ::testing::Test { size_t frs_per_evals = (Flavor::NUM_ALL_ENTITIES)*frs_per_Fr; size_t round = 0; - // TODO(https://github.com/AztecProtocol/barretenberg/issues/1427): Add VK FS to solidity verifier. - if constexpr (!IsAnyOf) { - manifest_expected.add_entry(round, "vk_hash", frs_per_Fr); - } else { - size_t frs_per_uint32 = bb::field_conversion::calc_num_bn254_frs(); - manifest_expected.add_entry(round, "vk_log_circuit_size", frs_per_uint32); - manifest_expected.add_entry(round, "vk_num_public_inputs", frs_per_uint32); - manifest_expected.add_entry(round, "vk_pub_inputs_offset", frs_per_uint32); - } + manifest_expected.add_entry(round, "vk_hash", frs_per_Fr); manifest_expected.add_entry(round, "public_input_0", frs_per_Fr); for (size_t i = 0; i < PAIRING_POINTS_SIZE; i++) { diff --git a/barretenberg/sol/scripts/copy_to_cpp.sh b/barretenberg/sol/scripts/copy_to_cpp.sh index 3caf5e380867..0e05c653b000 100755 --- a/barretenberg/sol/scripts/copy_to_cpp.sh +++ b/barretenberg/sol/scripts/copy_to_cpp.sh @@ -179,7 +179,7 @@ build_verifier() { # Add the final contract template if [ "$is_zk" = false ]; then cat >> "$output_file" << 'EOF' -contract HonkVerifier is BaseHonkVerifier(N, LOG_N, NUMBER_OF_PUBLIC_INPUTS) { +contract HonkVerifier is BaseHonkVerifier(N, LOG_N, VK_HASH, NUMBER_OF_PUBLIC_INPUTS) { function loadVerificationKey() internal pure override returns (Honk.VerificationKey memory) { return HonkVerificationKey.loadVerificationKey(); } @@ -187,7 +187,7 @@ contract HonkVerifier is BaseHonkVerifier(N, LOG_N, NUMBER_OF_PUBLIC_INPUTS) { EOF else cat >> "$output_file" << 'EOF' -contract HonkVerifier is BaseZKHonkVerifier(N, LOG_N, NUMBER_OF_PUBLIC_INPUTS) { +contract HonkVerifier is BaseZKHonkVerifier(N, LOG_N, VK_HASH, NUMBER_OF_PUBLIC_INPUTS) { function loadVerificationKey() internal pure override returns (Honk.VerificationKey memory) { return HonkVerificationKey.loadVerificationKey(); } diff --git a/barretenberg/sol/src/honk/BaseHonkVerifier.sol b/barretenberg/sol/src/honk/BaseHonkVerifier.sol index a1b643700388..240d78e94da3 100644 --- a/barretenberg/sol/src/honk/BaseHonkVerifier.sol +++ b/barretenberg/sol/src/honk/BaseHonkVerifier.sol @@ -33,11 +33,13 @@ abstract contract BaseHonkVerifier is IVerifier { uint256 immutable $N; uint256 immutable $LOG_N; + uint256 immutable $VK_HASH; uint256 immutable $NUM_PUBLIC_INPUTS; - constructor(uint256 _N, uint256 _logN, uint256 _numPublicInputs) { + constructor(uint256 _N, uint256 _logN, uint256 _vkHash, uint256 _numPublicInputs) { $N = _N; $LOG_N = _logN; + $VK_HASH = _vkHash; $NUM_PUBLIC_INPUTS = _numPublicInputs; } @@ -67,9 +69,7 @@ abstract contract BaseHonkVerifier is IVerifier { // Generate the fiat shamir challenges for the whole protocol // TODO(https://github.com/AztecProtocol/barretenberg/issues/1281): Add pubInputsOffset to VK or remove entirely. - Transcript memory t = TranscriptLib.generateTranscript( - p, publicInputs, vk.circuitSize, $NUM_PUBLIC_INPUTS, /*pubInputsOffset=*/ 1 - ); + Transcript memory t = TranscriptLib.generateTranscript(p, publicInputs, $VK_HASH, $NUM_PUBLIC_INPUTS); // Derive public input delta // TODO(https://github.com/AztecProtocol/barretenberg/issues/1281): Add pubInputsOffset to VK or remove entirely. diff --git a/barretenberg/sol/src/honk/BaseZKHonkVerifier.sol b/barretenberg/sol/src/honk/BaseZKHonkVerifier.sol index 01c4b25f1fe1..e0e98498efb2 100644 --- a/barretenberg/sol/src/honk/BaseZKHonkVerifier.sol +++ b/barretenberg/sol/src/honk/BaseZKHonkVerifier.sol @@ -33,11 +33,13 @@ abstract contract BaseZKHonkVerifier is IVerifier { uint256 immutable $N; uint256 immutable $LOG_N; + uint256 immutable $VK_HASH; uint256 immutable $NUM_PUBLIC_INPUTS; - constructor(uint256 _N, uint256 _logN, uint256 _numPublicInputs) { + constructor(uint256 _N, uint256 _logN, uint256 _vkHash, uint256 _numPublicInputs) { $N = _N; $LOG_N = _logN; + $VK_HASH = _vkHash; $NUM_PUBLIC_INPUTS = _numPublicInputs; } @@ -75,9 +77,7 @@ abstract contract BaseZKHonkVerifier is IVerifier { // Generate the fiat shamir challenges for the whole protocol // TODO(https://github.com/AztecProtocol/barretenberg/issues/1281): Add pubInputsOffset to VK or remove entirely. - ZKTranscript memory t = ZKTranscriptLib.generateTranscript( - p, publicInputs, vk.circuitSize, $NUM_PUBLIC_INPUTS, /*pubInputsOffset=*/ 1 - ); + ZKTranscript memory t = ZKTranscriptLib.generateTranscript(p, publicInputs, $VK_HASH, $NUM_PUBLIC_INPUTS); // Derive public input delta // TODO(https://github.com/AztecProtocol/barretenberg/issues/1281): Add pubInputsOffset to VK or remove entirely. diff --git a/barretenberg/sol/src/honk/Transcript.sol b/barretenberg/sol/src/honk/Transcript.sol index d2ae68337637..b2efd122bfa5 100644 --- a/barretenberg/sol/src/honk/Transcript.sol +++ b/barretenberg/sol/src/honk/Transcript.sol @@ -31,14 +31,12 @@ library TranscriptLib { function generateTranscript( Honk.Proof memory proof, bytes32[] calldata publicInputs, - uint256 circuitSize, - uint256 publicInputsSize, - uint256 pubInputsOffset + uint256 vkHash, + uint256 publicInputsSize ) internal pure returns (Transcript memory t) { Fr previousChallenge; - (t.relationParameters, previousChallenge) = generateRelationParametersChallenges( - proof, publicInputs, circuitSize, publicInputsSize, pubInputsOffset, previousChallenge - ); + (t.relationParameters, previousChallenge) = + generateRelationParametersChallenges(proof, publicInputs, vkHash, publicInputsSize, previousChallenge); (t.alphas, previousChallenge) = generateAlphaChallenges(previousChallenge, proof); @@ -68,13 +66,12 @@ library TranscriptLib { function generateRelationParametersChallenges( Honk.Proof memory proof, bytes32[] calldata publicInputs, - uint256 circuitSize, + uint256 vkHash, uint256 publicInputsSize, - uint256 pubInputsOffset, Fr previousChallenge ) internal pure returns (Honk.RelationParameters memory rp, Fr nextPreviousChallenge) { (rp.eta, rp.etaTwo, rp.etaThree, previousChallenge) = - generateEtaChallenge(proof, publicInputs, circuitSize, publicInputsSize, pubInputsOffset); + generateEtaChallenge(proof, publicInputs, vkHash, publicInputsSize); (rp.beta, rp.gamma, nextPreviousChallenge) = generateBetaAndGammaChallenges(previousChallenge, proof); } @@ -82,36 +79,33 @@ library TranscriptLib { function generateEtaChallenge( Honk.Proof memory proof, bytes32[] calldata publicInputs, - uint256 circuitSize, - uint256 publicInputsSize, - uint256 pubInputsOffset + uint256 vkHash, + uint256 publicInputsSize ) internal pure returns (Fr eta, Fr etaTwo, Fr etaThree, Fr previousChallenge) { - bytes32[] memory round0 = new bytes32[](3 + publicInputsSize + 12); - round0[0] = bytes32(circuitSize); - round0[1] = bytes32(publicInputsSize); - round0[2] = bytes32(pubInputsOffset); + bytes32[] memory round0 = new bytes32[](1 + publicInputsSize + 12); + round0[0] = bytes32(vkHash); for (uint256 i = 0; i < publicInputsSize - PAIRING_POINTS_SIZE; i++) { - round0[3 + i] = bytes32(publicInputs[i]); + round0[1 + i] = bytes32(publicInputs[i]); } for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) { - round0[3 + publicInputsSize - PAIRING_POINTS_SIZE + i] = FrLib.toBytes32(proof.pairingPointObject[i]); + round0[1 + publicInputsSize - PAIRING_POINTS_SIZE + i] = FrLib.toBytes32(proof.pairingPointObject[i]); } // Create the first challenge // Note: w4 is added to the challenge later on - round0[3 + publicInputsSize] = bytes32(proof.w1.x_0); - round0[3 + publicInputsSize + 1] = bytes32(proof.w1.x_1); - round0[3 + publicInputsSize + 2] = bytes32(proof.w1.y_0); - round0[3 + publicInputsSize + 3] = bytes32(proof.w1.y_1); - round0[3 + publicInputsSize + 4] = bytes32(proof.w2.x_0); - round0[3 + publicInputsSize + 5] = bytes32(proof.w2.x_1); - round0[3 + publicInputsSize + 6] = bytes32(proof.w2.y_0); - round0[3 + publicInputsSize + 7] = bytes32(proof.w2.y_1); - round0[3 + publicInputsSize + 8] = bytes32(proof.w3.x_0); - round0[3 + publicInputsSize + 9] = bytes32(proof.w3.x_1); - round0[3 + publicInputsSize + 10] = bytes32(proof.w3.y_0); - round0[3 + publicInputsSize + 11] = bytes32(proof.w3.y_1); + round0[1 + publicInputsSize] = bytes32(proof.w1.x_0); + round0[1 + publicInputsSize + 1] = bytes32(proof.w1.x_1); + round0[1 + publicInputsSize + 2] = bytes32(proof.w1.y_0); + round0[1 + publicInputsSize + 3] = bytes32(proof.w1.y_1); + round0[1 + publicInputsSize + 4] = bytes32(proof.w2.x_0); + round0[1 + publicInputsSize + 5] = bytes32(proof.w2.x_1); + round0[1 + publicInputsSize + 6] = bytes32(proof.w2.y_0); + round0[1 + publicInputsSize + 7] = bytes32(proof.w2.y_1); + round0[1 + publicInputsSize + 8] = bytes32(proof.w3.x_0); + round0[1 + publicInputsSize + 9] = bytes32(proof.w3.x_1); + round0[1 + publicInputsSize + 10] = bytes32(proof.w3.y_0); + round0[1 + publicInputsSize + 11] = bytes32(proof.w3.y_1); previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round0))); (eta, etaTwo) = splitChallenge(previousChallenge); diff --git a/barretenberg/sol/src/honk/ZKTranscript.sol b/barretenberg/sol/src/honk/ZKTranscript.sol index 3cb35deb8bee..e2de869b0b6f 100644 --- a/barretenberg/sol/src/honk/ZKTranscript.sol +++ b/barretenberg/sol/src/honk/ZKTranscript.sol @@ -33,14 +33,12 @@ library ZKTranscriptLib { function generateTranscript( Honk.ZKProof memory proof, bytes32[] calldata publicInputs, - uint256 circuitSize, - uint256 publicInputsSize, - uint256 pubInputsOffset + uint256 vkHash, + uint256 publicInputsSize ) external pure returns (ZKTranscript memory t) { Fr previousChallenge; - (t.relationParameters, previousChallenge) = generateRelationParametersChallenges( - proof, publicInputs, circuitSize, publicInputsSize, pubInputsOffset, previousChallenge - ); + (t.relationParameters, previousChallenge) = + generateRelationParametersChallenges(proof, publicInputs, vkHash, publicInputsSize, previousChallenge); (t.alphas, previousChallenge) = generateAlphaChallenges(previousChallenge, proof); @@ -69,13 +67,12 @@ library ZKTranscriptLib { function generateRelationParametersChallenges( Honk.ZKProof memory proof, bytes32[] calldata publicInputs, - uint256 circuitSize, + uint256 vkHash, uint256 publicInputsSize, - uint256 pubInputsOffset, Fr previousChallenge ) internal pure returns (Honk.RelationParameters memory rp, Fr nextPreviousChallenge) { (rp.eta, rp.etaTwo, rp.etaThree, previousChallenge) = - generateEtaChallenge(proof, publicInputs, circuitSize, publicInputsSize, pubInputsOffset); + generateEtaChallenge(proof, publicInputs, vkHash, publicInputsSize); (rp.beta, rp.gamma, nextPreviousChallenge) = generateBetaAndGammaChallenges(previousChallenge, proof); } @@ -83,35 +80,33 @@ library ZKTranscriptLib { function generateEtaChallenge( Honk.ZKProof memory proof, bytes32[] calldata publicInputs, - uint256 circuitSize, - uint256 publicInputsSize, - uint256 pubInputsOffset + uint256 vkHash, + uint256 publicInputsSize ) internal pure returns (Fr eta, Fr etaTwo, Fr etaThree, Fr previousChallenge) { - bytes32[] memory round0 = new bytes32[](3 + publicInputsSize + 12); - round0[0] = bytes32(circuitSize); - round0[1] = bytes32(publicInputsSize); - round0[2] = bytes32(pubInputsOffset); + bytes32[] memory round0 = new bytes32[](1 + publicInputsSize + 12); + round0[0] = bytes32(vkHash); + for (uint256 i = 0; i < publicInputsSize - PAIRING_POINTS_SIZE; i++) { - round0[3 + i] = bytes32(publicInputs[i]); + round0[1 + i] = bytes32(publicInputs[i]); } for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) { - round0[3 + publicInputsSize - PAIRING_POINTS_SIZE + i] = FrLib.toBytes32(proof.pairingPointObject[i]); + round0[1 + publicInputsSize - PAIRING_POINTS_SIZE + i] = FrLib.toBytes32(proof.pairingPointObject[i]); } // Create the first challenge // Note: w4 is added to the challenge later on - round0[3 + publicInputsSize] = bytes32(proof.w1.x_0); - round0[3 + publicInputsSize + 1] = bytes32(proof.w1.x_1); - round0[3 + publicInputsSize + 2] = bytes32(proof.w1.y_0); - round0[3 + publicInputsSize + 3] = bytes32(proof.w1.y_1); - round0[3 + publicInputsSize + 4] = bytes32(proof.w2.x_0); - round0[3 + publicInputsSize + 5] = bytes32(proof.w2.x_1); - round0[3 + publicInputsSize + 6] = bytes32(proof.w2.y_0); - round0[3 + publicInputsSize + 7] = bytes32(proof.w2.y_1); - round0[3 + publicInputsSize + 8] = bytes32(proof.w3.x_0); - round0[3 + publicInputsSize + 9] = bytes32(proof.w3.x_1); - round0[3 + publicInputsSize + 10] = bytes32(proof.w3.y_0); - round0[3 + publicInputsSize + 11] = bytes32(proof.w3.y_1); + round0[1 + publicInputsSize] = bytes32(proof.w1.x_0); + round0[1 + publicInputsSize + 1] = bytes32(proof.w1.x_1); + round0[1 + publicInputsSize + 2] = bytes32(proof.w1.y_0); + round0[1 + publicInputsSize + 3] = bytes32(proof.w1.y_1); + round0[1 + publicInputsSize + 4] = bytes32(proof.w2.x_0); + round0[1 + publicInputsSize + 5] = bytes32(proof.w2.x_1); + round0[1 + publicInputsSize + 6] = bytes32(proof.w2.y_0); + round0[1 + publicInputsSize + 7] = bytes32(proof.w2.y_1); + round0[1 + publicInputsSize + 8] = bytes32(proof.w3.x_0); + round0[1 + publicInputsSize + 9] = bytes32(proof.w3.x_1); + round0[1 + publicInputsSize + 10] = bytes32(proof.w3.y_0); + round0[1 + publicInputsSize + 11] = bytes32(proof.w3.y_1); previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(round0))); (eta, etaTwo) = splitChallenge(previousChallenge); diff --git a/barretenberg/sol/src/honk/instance/Add2Honk.sol b/barretenberg/sol/src/honk/instance/Add2Honk.sol index d70c26ce1b03..d9793a30e65f 100644 --- a/barretenberg/sol/src/honk/instance/Add2Honk.sol +++ b/barretenberg/sol/src/honk/instance/Add2Honk.sol @@ -3,13 +3,19 @@ pragma solidity >=0.8.21; import {IVerifier} from "../../interfaces/IVerifier.sol"; -import {Add2HonkVerificationKey as VK, N, LOG_N, NUMBER_OF_PUBLIC_INPUTS} from "../keys/Add2HonkVerificationKey.sol"; +import { + Add2HonkVerificationKey as VK, + N, + LOG_N, + NUMBER_OF_PUBLIC_INPUTS, + VK_HASH +} from "../keys/Add2HonkVerificationKey.sol"; import {Honk} from "../HonkTypes.sol"; import {BaseHonkVerifier as BASE} from "../BaseHonkVerifier.sol"; /// Smart contract verifier of honk proofs -contract Add2HonkVerifier is BASE(N, LOG_N, NUMBER_OF_PUBLIC_INPUTS) { +contract Add2HonkVerifier is BASE(N, LOG_N, VK_HASH, NUMBER_OF_PUBLIC_INPUTS) { function loadVerificationKey() internal pure override returns (Honk.VerificationKey memory) { return VK.loadVerificationKey(); } diff --git a/barretenberg/sol/src/honk/instance/Add2HonkZK.sol b/barretenberg/sol/src/honk/instance/Add2HonkZK.sol index fc5f14613ed0..adf852b9e113 100644 --- a/barretenberg/sol/src/honk/instance/Add2HonkZK.sol +++ b/barretenberg/sol/src/honk/instance/Add2HonkZK.sol @@ -3,13 +3,19 @@ pragma solidity >=0.8.21; import {IVerifier} from "../../interfaces/IVerifier.sol"; -import {Add2HonkVerificationKey as VK, N, LOG_N, NUMBER_OF_PUBLIC_INPUTS} from "../keys/Add2HonkVerificationKey.sol"; +import { + Add2HonkVerificationKey as VK, + N, + LOG_N, + NUMBER_OF_PUBLIC_INPUTS, + VK_HASH +} from "../keys/Add2HonkVerificationKey.sol"; import {Honk} from "../HonkTypes.sol"; import {BaseZKHonkVerifier as BASE} from "../BaseZKHonkVerifier.sol"; /// Smart contract verifier of honk proofs -contract Add2HonkZKVerifier is BASE(N, LOG_N, NUMBER_OF_PUBLIC_INPUTS) { +contract Add2HonkZKVerifier is BASE(N, LOG_N, VK_HASH, NUMBER_OF_PUBLIC_INPUTS) { function loadVerificationKey() internal pure override returns (Honk.VerificationKey memory) { return VK.loadVerificationKey(); } diff --git a/barretenberg/sol/src/honk/instance/BlakeHonk.sol b/barretenberg/sol/src/honk/instance/BlakeHonk.sol index fd42b9e094e7..564056c61418 100644 --- a/barretenberg/sol/src/honk/instance/BlakeHonk.sol +++ b/barretenberg/sol/src/honk/instance/BlakeHonk.sol @@ -3,14 +3,20 @@ pragma solidity >=0.8.21; import {IVerifier} from "../../interfaces/IVerifier.sol"; -import {BlakeHonkVerificationKey as VK, N, LOG_N, NUMBER_OF_PUBLIC_INPUTS} from "../keys/BlakeHonkVerificationKey.sol"; +import { + BlakeHonkVerificationKey as VK, + N, + LOG_N, + NUMBER_OF_PUBLIC_INPUTS, + VK_HASH +} from "../keys/BlakeHonkVerificationKey.sol"; import {Honk} from "../HonkTypes.sol"; import {BaseHonkVerifier as BASE} from "../BaseHonkVerifier.sol"; /// Smart contract verifier of honk proofs -contract BlakeHonkVerifier is BASE(N, LOG_N, NUMBER_OF_PUBLIC_INPUTS) { +contract BlakeHonkVerifier is BASE(N, LOG_N, VK_HASH, NUMBER_OF_PUBLIC_INPUTS) { function loadVerificationKey() internal pure override returns (Honk.VerificationKey memory) { return VK.loadVerificationKey(); } diff --git a/barretenberg/sol/src/honk/instance/BlakeHonkZK.sol b/barretenberg/sol/src/honk/instance/BlakeHonkZK.sol index 6d6a61172da0..e9a7241d3e61 100644 --- a/barretenberg/sol/src/honk/instance/BlakeHonkZK.sol +++ b/barretenberg/sol/src/honk/instance/BlakeHonkZK.sol @@ -3,14 +3,20 @@ pragma solidity >=0.8.21; import {IVerifier} from "../../interfaces/IVerifier.sol"; -import {BlakeHonkVerificationKey as VK, N, LOG_N, NUMBER_OF_PUBLIC_INPUTS} from "../keys/BlakeHonkVerificationKey.sol"; +import { + BlakeHonkVerificationKey as VK, + N, + LOG_N, + NUMBER_OF_PUBLIC_INPUTS, + VK_HASH +} from "../keys/BlakeHonkVerificationKey.sol"; import {Honk} from "../HonkTypes.sol"; import {BaseZKHonkVerifier as BASE} from "../BaseZKHonkVerifier.sol"; /// Smart contract verifier of honk proofs -contract BlakeHonkZKVerifier is BASE(N, LOG_N, NUMBER_OF_PUBLIC_INPUTS) { +contract BlakeHonkZKVerifier is BASE(N, LOG_N, VK_HASH, NUMBER_OF_PUBLIC_INPUTS) { function loadVerificationKey() internal pure override returns (Honk.VerificationKey memory) { return VK.loadVerificationKey(); } diff --git a/barretenberg/sol/src/honk/instance/EcdsaHonk.sol b/barretenberg/sol/src/honk/instance/EcdsaHonk.sol index f7d599ff01e9..833b7a48862f 100644 --- a/barretenberg/sol/src/honk/instance/EcdsaHonk.sol +++ b/barretenberg/sol/src/honk/instance/EcdsaHonk.sol @@ -3,14 +3,20 @@ pragma solidity >=0.8.21; import {IVerifier} from "../../interfaces/IVerifier.sol"; -import {EcdsaHonkVerificationKey as VK, N, LOG_N, NUMBER_OF_PUBLIC_INPUTS} from "../keys/EcdsaHonkVerificationKey.sol"; +import { + EcdsaHonkVerificationKey as VK, + N, + LOG_N, + NUMBER_OF_PUBLIC_INPUTS, + VK_HASH +} from "../keys/EcdsaHonkVerificationKey.sol"; import {Honk} from "../HonkTypes.sol"; import {BaseHonkVerifier as BASE} from "../BaseHonkVerifier.sol"; /// Smart contract verifier of honk proofs -contract EcdsaHonkVerifier is BASE(N, LOG_N, NUMBER_OF_PUBLIC_INPUTS) { +contract EcdsaHonkVerifier is BASE(N, LOG_N, VK_HASH, NUMBER_OF_PUBLIC_INPUTS) { function loadVerificationKey() internal pure override returns (Honk.VerificationKey memory) { return VK.loadVerificationKey(); } diff --git a/barretenberg/sol/src/honk/instance/EcdsaHonkZK.sol b/barretenberg/sol/src/honk/instance/EcdsaHonkZK.sol index d3940dff7b11..0eb33127fa3d 100644 --- a/barretenberg/sol/src/honk/instance/EcdsaHonkZK.sol +++ b/barretenberg/sol/src/honk/instance/EcdsaHonkZK.sol @@ -3,14 +3,20 @@ pragma solidity >=0.8.21; import {IVerifier} from "../../interfaces/IVerifier.sol"; -import {EcdsaHonkVerificationKey as VK, N, LOG_N, NUMBER_OF_PUBLIC_INPUTS} from "../keys/EcdsaHonkVerificationKey.sol"; +import { + EcdsaHonkVerificationKey as VK, + N, + LOG_N, + NUMBER_OF_PUBLIC_INPUTS, + VK_HASH +} from "../keys/EcdsaHonkVerificationKey.sol"; import {Honk} from "../HonkTypes.sol"; import {BaseZKHonkVerifier as BASE} from "../BaseZKHonkVerifier.sol"; /// Smart contract verifier of honk proofs -contract EcdsaHonkZKVerifier is BASE(N, LOG_N, NUMBER_OF_PUBLIC_INPUTS) { +contract EcdsaHonkZKVerifier is BASE(N, LOG_N, VK_HASH, NUMBER_OF_PUBLIC_INPUTS) { function loadVerificationKey() internal pure override returns (Honk.VerificationKey memory) { return VK.loadVerificationKey(); } diff --git a/barretenberg/sol/src/honk/instance/RecursiveHonk.sol b/barretenberg/sol/src/honk/instance/RecursiveHonk.sol index e7436c6fc964..3c65f3f13f8b 100644 --- a/barretenberg/sol/src/honk/instance/RecursiveHonk.sol +++ b/barretenberg/sol/src/honk/instance/RecursiveHonk.sol @@ -7,14 +7,15 @@ import { RecursiveHonkVerificationKey as VK, N, LOG_N, - NUMBER_OF_PUBLIC_INPUTS + NUMBER_OF_PUBLIC_INPUTS, + VK_HASH } from "../keys/RecursiveHonkVerificationKey.sol"; import {Honk} from "../HonkTypes.sol"; import {BaseHonkVerifier as BASE} from "../BaseHonkVerifier.sol"; /// Smart contract verifier of honk proofs -contract RecursiveHonkVerifier is BASE(N, LOG_N, NUMBER_OF_PUBLIC_INPUTS) { +contract RecursiveHonkVerifier is BASE(N, LOG_N, VK_HASH, NUMBER_OF_PUBLIC_INPUTS) { function loadVerificationKey() internal pure override returns (Honk.VerificationKey memory) { return VK.loadVerificationKey(); } diff --git a/barretenberg/sol/src/honk/instance/RecursiveHonkZK.sol b/barretenberg/sol/src/honk/instance/RecursiveHonkZK.sol index 62ac69172ba4..72232e4e04d5 100644 --- a/barretenberg/sol/src/honk/instance/RecursiveHonkZK.sol +++ b/barretenberg/sol/src/honk/instance/RecursiveHonkZK.sol @@ -7,14 +7,15 @@ import { RecursiveHonkVerificationKey as VK, N, LOG_N, - NUMBER_OF_PUBLIC_INPUTS + NUMBER_OF_PUBLIC_INPUTS, + VK_HASH } from "../keys/RecursiveHonkVerificationKey.sol"; import {Honk} from "../HonkTypes.sol"; import {BaseZKHonkVerifier as BASE} from "../BaseZKHonkVerifier.sol"; /// Smart contract verifier of honk proofs -contract RecursiveHonkZKVerifier is BASE(N, LOG_N, NUMBER_OF_PUBLIC_INPUTS) { +contract RecursiveHonkZKVerifier is BASE(N, LOG_N, VK_HASH, NUMBER_OF_PUBLIC_INPUTS) { function loadVerificationKey() internal pure override returns (Honk.VerificationKey memory) { return VK.loadVerificationKey(); }