diff --git a/barretenberg/acir_tests/sol-test/src/index.js b/barretenberg/acir_tests/sol-test/src/index.js index 465b309042a5..7800eeabe0bc 100644 --- a/barretenberg/acir_tests/sol-test/src/index.js +++ b/barretenberg/acir_tests/sol-test/src/index.js @@ -9,6 +9,7 @@ const NUMBER_OF_FIELDS_IN_PLONK_PROOF = 93; const NUMBER_OF_FIELDS_IN_HONK_PROOF = 443; const NUMBER_OF_FIELDS_IN_HONK_ZK_PROOF = 494; +const WRONG_PROOF_LENGTH = "0xed74ac0a"; const WRONG_PUBLIC_INPUTS_LENGTH = "0xfa066593"; const SUMCHECK_FAILED = "0x9fc3a218"; const SHPLEMINI_FAILED = "0xa5d82e8a"; @@ -60,7 +61,6 @@ const testingHonk = getEnvVarCanBeUndefined("TESTING_HONK"); const hasZK = getEnvVarCanBeUndefined("HAS_ZK"); const verifierContract = hasZK ? "ZKVerifier.sol" : "Verifier.sol"; -console.log(verifierContract); export const compilationInput = { language: "Solidity", sources: { @@ -260,6 +260,10 @@ try { if (testingHonk) { var errorType = e.data; switch (errorType) { + case WRONG_PROOF_LENGTH: + throw new Error( + "Proof length wrong. Check the constant and the proof surgery." + ); case WRONG_PUBLIC_INPUTS_LENGTH: throw new Error("Number of inputs in the proof is wrong"); case SUMCHECK_FAILED: 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 5cc27bc8868f..c18cf1f311a9 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp @@ -1430,13 +1430,22 @@ abstract contract BaseHonkVerifier is IVerifier { numPublicInputs = _numPublicInputs; } + error ProofLengthWrong(); error PublicInputsLengthWrong(); error SumcheckFailed(); error ShpleminiFailed(); + // Number of field elements in a ultra honk zero knowledge proof + uint256 constant PROOF_SIZE = 443; + function loadVerificationKey() internal pure virtual returns (Honk.VerificationKey memory); function verify(bytes calldata proof, bytes32[] calldata publicInputs) public view override returns (bool) { + // Check the received proof is the expected size where each field element is 32 bytes + if (proof.length != PROOF_SIZE * 32) { + revert ProofLengthWrong(); + } + Honk.VerificationKey memory vk = loadVerificationKey(); Honk.Proof memory p = TranscriptLib.loadProof(proof); 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 92a4cd944e08..4e5eef6c2c63 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 @@ -1489,13 +1489,21 @@ interface IVerifier { // Errors + error ProofLengthWrong(); error PublicInputsLengthWrong(); error SumcheckFailed(); error ShpleminiFailed(); error GeminiChallengeInSubgroup(); error ConsistencyCheckFailed(); + uint256 constant PROOF_SIZE = 494; + function verify(bytes calldata proof, bytes32[] calldata publicInputs) public view override returns (bool verified) { + // Check the received proof is the expected size where each field element is 32 bytes + if (proof.length != PROOF_SIZE * 32) { + revert ProofLengthWrong(); + } + Honk.VerificationKey memory vk = loadVerificationKey(); Honk.ZKProof memory p = ZKTranscriptLib.loadProof(proof); diff --git a/barretenberg/sol/src/honk/BaseHonkVerifier.sol b/barretenberg/sol/src/honk/BaseHonkVerifier.sol index fc20594bdddc..d6ad628b1dea 100644 --- a/barretenberg/sol/src/honk/BaseHonkVerifier.sol +++ b/barretenberg/sol/src/honk/BaseHonkVerifier.sol @@ -39,13 +39,22 @@ abstract contract BaseHonkVerifier is IVerifier { } // Errors + error ProofLengthWrong(); error PublicInputsLengthWrong(); error SumcheckFailed(); error ShpleminiFailed(); + // Number of field elements in a ultra honk proof + uint256 constant PROOF_SIZE = 443; + function loadVerificationKey() internal pure virtual returns (Honk.VerificationKey memory); function verify(bytes calldata proof, bytes32[] calldata publicInputs) public view override returns (bool) { + // Check the received proof is the expected size where each field element is 32 bytes + if (proof.length != PROOF_SIZE * 32) { + revert ProofLengthWrong(); + } + Honk.VerificationKey memory vk = loadVerificationKey(); Honk.Proof memory p = TranscriptLib.loadProof(proof); if (publicInputs.length != vk.publicInputsSize) { diff --git a/barretenberg/sol/src/honk/BaseZKHonkVerifier.sol b/barretenberg/sol/src/honk/BaseZKHonkVerifier.sol index fee12422171c..b93f67117414 100644 --- a/barretenberg/sol/src/honk/BaseZKHonkVerifier.sol +++ b/barretenberg/sol/src/honk/BaseZKHonkVerifier.sol @@ -41,12 +41,16 @@ abstract contract BaseZKHonkVerifier is IVerifier { } // Errors + error ProofLengthWrong(); error PublicInputsLengthWrong(); error SumcheckFailed(); error ShpleminiFailed(); error GeminiChallengeInSubgroup(); error ConsistencyCheckFailed(); + // Number of field elements in a ultra honk zero knowledge proof + uint256 constant PROOF_SIZE = 494; + function loadVerificationKey() internal pure virtual returns (Honk.VerificationKey memory); function verify(bytes calldata proof, bytes32[] calldata publicInputs) @@ -55,6 +59,11 @@ abstract contract BaseZKHonkVerifier is IVerifier { override returns (bool verified) { + // Check the received proof is the expected size where each field element is 32 bytes + if (proof.length != PROOF_SIZE * 32) { + revert ProofLengthWrong(); + } + Honk.VerificationKey memory vk = loadVerificationKey(); Honk.ZKProof memory p = ZKTranscriptLib.loadProof(proof);