diff --git a/aztec-nargo/compile_then_postprocess.sh b/aztec-nargo/compile_then_postprocess.sh index 03deed4d4cf7..2ccca323078c 100755 --- a/aztec-nargo/compile_then_postprocess.sh +++ b/aztec-nargo/compile_then_postprocess.sh @@ -41,7 +41,7 @@ for artifact in $artifacts_to_process; do echo "Generating verification key for function $fn_name" # BB outputs the verification key to stdout as raw bytes, however, we need to base64 encode it before storing it in the artifact - verification_key=$($BB write_vk_mega_honk -h -b ${fn_artifact_path} -o - | base64) + verification_key=$($BB write_vk_for_ivc -h -b ${fn_artifact_path} -o - | base64) rm $fn_artifact_path jq ".functions[$fn_index].verification_key = \"$verification_key\"" $artifact > $artifact.tmp mv $artifact.tmp $artifact diff --git a/barretenberg/cpp/src/barretenberg/constants.hpp b/barretenberg/cpp/src/barretenberg/constants.hpp index 7ff2b6b002c5..364600b2ef8d 100644 --- a/barretenberg/cpp/src/barretenberg/constants.hpp +++ b/barretenberg/cpp/src/barretenberg/constants.hpp @@ -13,7 +13,7 @@ static constexpr uint32_t CONST_PG_LOG_N = 20; static constexpr uint32_t CONST_ECCVM_LOG_N = 15; -static constexpr uint32_t MAX_LOOKUP_TABLES_SIZE = 70000; +static constexpr uint32_t MAX_LOOKUP_TABLES_SIZE = 75000; static constexpr uint32_t MAX_DATABUS_SIZE = 10000; } // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/composer_lib.hpp b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/composer_lib.hpp index 1216623ee32a..5565d5197ee9 100644 --- a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/composer_lib.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/composer_lib.hpp @@ -23,6 +23,7 @@ void construct_lookup_table_polynomials(const RefArray tables_size + additional_offset); size_t offset = dyadic_circuit_size - tables_size - additional_offset; diff --git a/barretenberg/cpp/src/barretenberg/polynomials/shared_shifted_virtual_zeroes_array.hpp b/barretenberg/cpp/src/barretenberg/polynomials/shared_shifted_virtual_zeroes_array.hpp index 191080edbe8a..c9999fbad1bc 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/shared_shifted_virtual_zeroes_array.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/shared_shifted_virtual_zeroes_array.hpp @@ -85,7 +85,10 @@ template struct SharedShiftedVirtualZeroesArray { T& operator[](size_t index) { - ASSERT(index >= start_ && index < end_); + if (index < start_ || index >= end_) { + vinfo("index = ", index, ", start_ = ", start_, ", end_ = ", end_); + ASSERT(false); + } return data()[index - start_]; } // get() is more useful, but for completeness with the non-const operator[] diff --git a/noir-projects/Earthfile b/noir-projects/Earthfile index 0a876ac39f7f..42cfb3d89ad0 100644 --- a/noir-projects/Earthfile +++ b/noir-projects/Earthfile @@ -19,8 +19,7 @@ source: COPY package.json yarn.lock . RUN yarn - COPY mega_honk_circuits.json . - COPY ivc_integration_circuits.json . + COPY client_ivc_circuits.json . COPY --dir aztec-nr noir-contracts noir-protocol-circuits mock-protocol-circuits scripts . build-contracts: diff --git a/noir-projects/client_ivc_circuits.json b/noir-projects/client_ivc_circuits.json new file mode 100644 index 000000000000..98b0104f17e7 --- /dev/null +++ b/noir-projects/client_ivc_circuits.json @@ -0,0 +1,8 @@ +[ + "private_kernel_init", + "private_kernel_inner", + "private_kernel_reset.*", + "private_kernel_tail.*", + "app_creator", + "app_reader" +] \ No newline at end of file diff --git a/noir-projects/gates_report.sh b/noir-projects/gates_report.sh index eaeb52a0c132..d1b0d40aa058 100755 --- a/noir-projects/gates_report.sh +++ b/noir-projects/gates_report.sh @@ -5,7 +5,7 @@ set -eu # The script needs some slight updating as `nargo info` expects a complete JSON object, while this script expects a single object field # representing a list of circuit reports for a program. # The ACIR tests in barretenberg also expect every target bytecode to have the name `acir.gz` while this script expects the same name of the package -MEGA_HONK_CIRCUIT_PATTERNS=$(jq -r '.[]' mega_honk_circuits.json) +MEGA_HONK_CIRCUIT_PATTERNS=$(jq -r '.[]' client_ivc_circuits.json) cd noir-protocol-circuits PROTOCOL_CIRCUITS_DIR=$PWD @@ -31,13 +31,13 @@ for pathname in "$PROTOCOL_CIRCUITS_DIR/target"/*.json; do fi done - # If it's mega honk, we need to use the gates_mega_honk command + # If it's mega honk, we need to use the gates_mega_honk command if [ "$IS_MEGA_HONK_CIRCUIT" = "true" ]; then GATES_INFO=$($BB_BIN gates_mega_honk -h -b "$pathname") else GATES_INFO=$($BB_BIN gates -h -b "$pathname") fi - + MAIN_FUNCTION_INFO=$(echo $GATES_INFO | jq -r '.functions[0] | .name = "main"') echo "{\"package_name\": \"$ARTIFACT_NAME\", \"functions\": [$MAIN_FUNCTION_INFO]" >> gates_report.json diff --git a/noir-projects/ivc_integration_circuits.json b/noir-projects/ivc_integration_circuits.json deleted file mode 100644 index 01971872d1ff..000000000000 --- a/noir-projects/ivc_integration_circuits.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - "mock_private_kernel_init", - "mock_private_kernel_inner", - "mock_private_kernel_reset.*", - "mock_private_kernel_tail.*", - "app_creator", - "app_reader" -] \ No newline at end of file diff --git a/noir-projects/mega_honk_circuits.json b/noir-projects/mega_honk_circuits.json deleted file mode 100644 index 1db696b11e6e..000000000000 --- a/noir-projects/mega_honk_circuits.json +++ /dev/null @@ -1,6 +0,0 @@ -[ - "^private_kernel_init", - "^private_kernel_inner", - "^private_kernel_reset.*", - "^private_kernel_tail.*" -] \ No newline at end of file diff --git a/noir-projects/noir-contracts/scripts/postprocess_contract.js b/noir-projects/noir-contracts/scripts/postprocess_contract.js index b423bf2a50f5..012197d68c4a 100644 --- a/noir-projects/noir-contracts/scripts/postprocess_contract.js +++ b/noir-projects/noir-contracts/scripts/postprocess_contract.js @@ -38,7 +38,7 @@ async function generateVkForFunction(functionArtifact, outputFolder) { ); try { - const writeVkCommand = `${BB_BIN_PATH} write_vk_mega_honk -h -b "${functionArtifactPath}" -o "${outputVkPath}" `; + const writeVkCommand = `${BB_BIN_PATH} write_vk_for_ivc -h -b "${functionArtifactPath}" -o "${outputVkPath}" `; console.log("WRITE VK CMD: ", writeVkCommand); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr index aee9521cd152..94112c25ee2d 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr @@ -49,6 +49,10 @@ impl PrivateKernelInitCircuitPrivateInputs { } pub fn execute(self) -> PrivateKernelCircuitPublicInputs { + if !std::runtime::is_unconstrained() { + self.private_call.verify(true); + } + // Generate output. let output = unsafe { self.generate_output() }; diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr index 4ac72fc4d6bd..c372c62e1fd5 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr @@ -47,6 +47,11 @@ impl PrivateKernelInnerCircuitPrivateInputs { } pub fn execute(self) -> PrivateKernelCircuitPublicInputs { + if !std::runtime::is_unconstrained() { + self.previous_kernel.verify(); + self.private_call.verify(false); + } + // Generate output. let output = unsafe { self.generate_output() }; diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr index 154c12763eef..2adb56037601 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr @@ -65,6 +65,10 @@ impl PrivateKernelCircuitPublicInputs { + if !std::runtime::is_unconstrained() { + self.previous_kernel.verify(); + } + let previous_public_inputs = self.previous_kernel.public_inputs; let validation_request_processor = PrivateValidationRequestProcessor { validation_requests: previous_public_inputs.validation_requests, diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr index 78ab6f77609d..27276bed9597 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr @@ -33,6 +33,9 @@ impl PrivateKernelTailCircuitPrivateInputs { } pub fn execute(self) -> KernelCircuitPublicInputs { + if !std::runtime::is_unconstrained() { + self.previous_kernel.verify(); + } // Generate output. let output = unsafe { self.generate_output() }; diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr index 6bc437e46016..2a18fbfed3e1 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr @@ -34,6 +34,9 @@ impl PrivateKernelTailToPublicCircuitPrivateInputs { } pub fn execute(self) -> PrivateToPublicKernelCircuitPublicInputs { + if !std::runtime::is_unconstrained() { + self.previous_kernel.verify(); + } // Generate output. let output = unsafe { self.generate_output() }; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel/private_call_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel/private_call_data.nr index be9751aad925..0d887f71f423 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel/private_call_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel/private_call_data.nr @@ -1,7 +1,9 @@ use crate::{ abis::private_circuit_public_inputs::PrivateCircuitPublicInputs, address::SaltedInitializationHash, - constants::{FUNCTION_TREE_HEIGHT, PROTOCOL_CONTRACT_TREE_HEIGHT}, + constants::{ + FUNCTION_TREE_HEIGHT, PROOF_TYPE_OINK, PROOF_TYPE_PG, PROTOCOL_CONTRACT_TREE_HEIGHT, + }, merkle_tree::membership::MembershipWitness, proof::verification_key::ClientIVCVerificationKey, public_keys::PublicKeys, @@ -22,6 +24,18 @@ pub struct PrivateCallData { pub acir_hash: Field, } +impl PrivateCallData { + fn verify(self, is_first_app: bool) { + let proof_type = if is_first_app { + PROOF_TYPE_OINK + } else { + PROOF_TYPE_PG + }; + // Client IVC public inputs are linked in the backend via the databus + std::verify_proof_with_type(self.vk.key, [], [], 0, proof_type); + } +} + pub struct PrivateCallDataWithoutPublicInputs { pub vk: ClientIVCVerificationKey, diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel_data.nr index 63540dcbb372..5737775889ef 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel_data.nr @@ -1,8 +1,8 @@ use crate::{ abis::kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, - constants::{PRIVATE_KERNEL_RESET_INDEX, VK_TREE_HEIGHT}, + constants::{PRIVATE_KERNEL_RESET_INDEX, PROOF_TYPE_PG, VK_TREE_HEIGHT}, merkle_tree::membership::assert_check_membership, - proof::verification_key::ClientIVCVerificationKey, + proof::{traits::Verifiable, verification_key::ClientIVCVerificationKey}, utils::arrays::find_index_hint, }; @@ -38,6 +38,13 @@ impl PrivateKernelData { } } +impl Verifiable for PrivateKernelData { + fn verify(self) { + // Client IVC public inputs are linked in the backend via the databus + std::verify_proof_with_type(self.vk.key, [], [], 0, PROOF_TYPE_PG); + } +} + pub struct PrivateKernelDataWithoutPublicInputs { vk: ClientIVCVerificationKey, vk_index: u32, diff --git a/noir-projects/noir-protocol-circuits/scripts/flamegraph.sh b/noir-projects/noir-protocol-circuits/scripts/flamegraph.sh index 4f0868e573af..b8307d845ee5 100755 --- a/noir-projects/noir-protocol-circuits/scripts/flamegraph.sh +++ b/noir-projects/noir-protocol-circuits/scripts/flamegraph.sh @@ -123,7 +123,7 @@ fi DEST="$SCRIPT_DIR/../dest" mkdir -p $DEST -MEGA_HONK_CIRCUIT_PATTERNS=$(jq -r '.[]' "$SCRIPT_DIR/../../mega_honk_circuits.json") +MEGA_HONK_CIRCUIT_PATTERNS=$(jq -r '.[]' "$SCRIPT_DIR/../../client_ivc_circuits.json") # Process each CIRCUIT_NAME. for CIRCUIT_NAME in "${CIRCUIT_NAMES[@]}"; do diff --git a/noir-projects/scripts/generate_vk_json.js b/noir-projects/scripts/generate_vk_json.js index a2942e69cded..3bbe390ff9dc 100644 --- a/noir-projects/scripts/generate_vk_json.js +++ b/noir-projects/scripts/generate_vk_json.js @@ -3,8 +3,7 @@ const fs = require("fs/promises"); const child_process = require("child_process"); const crypto = require("crypto"); -const megaHonkPatterns = require("../mega_honk_circuits.json"); -const ivcIntegrationPatterns = require("../ivc_integration_circuits.json"); +const clientIvcPatterns = require("../client_ivc_circuits.json"); const { readVKFromS3, writeVKToS3, @@ -33,19 +32,13 @@ async function getBytecodeHash(artifactPath) { return crypto.createHash("md5").update(bytecode).digest("hex"); } -async function getArtifactHash( - artifactPath, - isMegaHonk, - isIvcIntegration, - isRecursive -) { +async function getArtifactHash(artifactPath, isClientIvc, isRecursive) { const bytecodeHash = await getBytecodeHash(artifactPath); const barretenbergHash = await getBarretenbergHash(); return generateArtifactHash( barretenbergHash, bytecodeHash, - isMegaHonk, - isIvcIntegration, + isClientIvc, isRecursive ); } @@ -68,26 +61,19 @@ async function hasArtifactHashChanged(artifactHash, vkDataPath) { return true; } -function isMegaHonkCircuit(artifactName) { - return megaHonkPatterns.some((pattern) => - artifactName.match(new RegExp(pattern)) - ); -} -function isIvcIntegrationCircuit(artifactName) { - return ivcIntegrationPatterns.some((pattern) => +function isClientIvcCircuit(artifactName) { + return clientIvcPatterns.some((pattern) => artifactName.match(new RegExp(pattern)) ); } async function processArtifact(artifactPath, artifactName, outputFolder) { - const isMegaHonk = isMegaHonkCircuit(artifactName); - const isIvcIntegration = isIvcIntegrationCircuit(artifactName); + const isClientIvc = isClientIvcCircuit(artifactName); const isRecursive = true; const artifactHash = await getArtifactHash( artifactPath, - isMegaHonk, - isIvcIntegration, + isClientIvc, isRecursive ); @@ -106,8 +92,7 @@ async function processArtifact(artifactPath, artifactName, outputFolder) { outputFolder, artifactPath, artifactHash, - isMegaHonk, - isIvcIntegration, + isClientIvc, isRecursive ); await writeVKToS3(artifactName, artifactHash, JSON.stringify(vkData)); @@ -123,14 +108,11 @@ async function generateVKData( outputFolder, artifactPath, artifactHash, - isMegaHonk, - isIvcIntegration, + isClientIvc, isRecursive ) { - if (isMegaHonk) { - console.log("Generating new mega honk vk for", artifactName); - } else if (isIvcIntegration) { - console.log("Generating new IVC vk for", artifactName); + if (isClientIvc) { + console.log("Generating new client ivc vk for", artifactName); } else { console.log("Generating new vk for", artifactName); } @@ -142,8 +124,7 @@ async function generateVKData( const jsonVkPath = vkJsonFileNameForArtifactName(outputFolder, artifactName); function getVkCommand() { - if (isMegaHonk) return "write_vk_mega_honk"; - if (isIvcIntegration) return "write_vk_for_ivc"; + if (isClientIvc) return "write_vk_for_ivc"; return "write_vk_ultra_honk"; } @@ -154,9 +135,7 @@ async function generateVKData( console.log("WRITE VK CMD: ", writeVkCommand); const vkAsFieldsCommand = `${BB_BIN_PATH} ${ - isMegaHonk || isIvcIntegration - ? "vk_as_fields_mega_honk" - : "vk_as_fields_ultra_honk" + isClientIvc ? "vk_as_fields_mega_honk" : "vk_as_fields_ultra_honk" } -k "${binaryVkPath}" -o "${jsonVkPath}"`; await new Promise((resolve, reject) => { diff --git a/noir-projects/scripts/verification_keys.js b/noir-projects/scripts/verification_keys.js index 90fd90cb991b..0ec6d9258ec0 100644 --- a/noir-projects/scripts/verification_keys.js +++ b/noir-projects/scripts/verification_keys.js @@ -67,11 +67,11 @@ function generateS3Client() { function generateArtifactHash( barretenbergHash, bytecodeHash, - isMegaHonk, + isClientIvc, isRecursive ) { return `${barretenbergHash}-${bytecodeHash}-${ - isMegaHonk ? "mega-honk" : "ultra-honk" + isClientIvc ? "client-ivc" : "ultra-honk" }-${isRecursive}`; } diff --git a/yarn-project/bb-prover/src/prover/bb_private_kernel_prover.ts b/yarn-project/bb-prover/src/prover/bb_private_kernel_prover.ts index 53f18d20c2e0..614329564cd3 100644 --- a/yarn-project/bb-prover/src/prover/bb_private_kernel_prover.ts +++ b/yarn-project/bb-prover/src/prover/bb_private_kernel_prover.ts @@ -105,6 +105,7 @@ export class BBNativePrivateKernelProver implements PrivateKernelProver { path.join(directory, 'acir.msgpack'), path.join(directory, 'witnesses.msgpack'), this.log.info, + true, ); if (provingResult.status === BB_RESULT.FAILURE) {