From 976ed253278e53b56eac884b1234acdcb404db5f Mon Sep 17 00:00:00 2001 From: sirasistant Date: Tue, 5 Nov 2024 13:01:46 +0000 Subject: [PATCH 01/17] feat: write verification_key in artifacts --- noir-projects/noir-contracts/bootstrap.sh | 17 +- .../scripts/include_verification_keys.js | 101 +++++++++++ noir-projects/scripts/generate_vk_json.js | 165 ++---------------- noir-projects/scripts/verification_keys.js | 104 +++++++++++ 4 files changed, 226 insertions(+), 161 deletions(-) create mode 100644 noir-projects/noir-contracts/scripts/include_verification_keys.js create mode 100644 noir-projects/scripts/verification_keys.js diff --git a/noir-projects/noir-contracts/bootstrap.sh b/noir-projects/noir-contracts/bootstrap.sh index b739b0eb429..79e93bd2cfd 100755 --- a/noir-projects/noir-contracts/bootstrap.sh +++ b/noir-projects/noir-contracts/bootstrap.sh @@ -19,20 +19,15 @@ echo "Compiling contracts..." NARGO=${NARGO:-../../noir/noir-repo/target/release/nargo} $NARGO compile --silence-warnings --inliner-aggressiveness 0 -echo "Generating protocol contract vks..." +echo "Transpiling contracts..." +scripts/transpile.sh + +echo "Generating contract vks..." BB_HASH=${BB_HASH:-$(cd ../../ && git ls-tree -r HEAD | grep 'barretenberg/cpp' | awk '{print $3}' | git hash-object --stdin)} echo Using BB hash $BB_HASH vkDir="./target/keys" mkdir -p $vkDir -protocol_contracts=$(jq -r '.[]' "./protocol_contracts.json") -for contract in $protocol_contracts; do - artifactPath="./target/$contract.json" - fnNames=$(jq -r '.functions[] | select(.custom_attributes | index("private")) | .name' "$artifactPath") - for fnName in $fnNames; do - BB_HASH=$BB_HASH node ../scripts/generate_vk_json.js "$artifactPath" "$vkDir" "$fnName" - done +for artifactPath in "./target"/*.json; do + BB_HASH=$BB_HASH node ./scripts/include_verification_keys.js "$artifactPath" "$vkDir" done - -echo "Transpiling contracts..." -scripts/transpile.sh \ No newline at end of file diff --git a/noir-projects/noir-contracts/scripts/include_verification_keys.js b/noir-projects/noir-contracts/scripts/include_verification_keys.js new file mode 100644 index 00000000000..d3c02dc0748 --- /dev/null +++ b/noir-projects/noir-contracts/scripts/include_verification_keys.js @@ -0,0 +1,101 @@ +const fs = require("fs/promises"); +const path = require("path"); +const { + BB_BIN_PATH, + readVKFromS3, + writeVKToS3, + generateArtifactHash, + getBarretenbergHash, +} = require("../../scripts/verification_keys"); +const child_process = require("child_process"); +const crypto = require("crypto"); + +function getFunctionArtifactPath(outputFolder, functionName) { + return path.join(outputFolder, `${functionName}.tmp.json`); +} + +function getFunctionVkPath(outputFolder, functionName) { + return path.join(outputFolder, `${functionName}.vk.tmp.bin`); +} + +async function getBytecodeHash({ bytecode }) { + if (!bytecode) { + throw new Error("No bytecode found in function artifact"); + } + return crypto.createHash("md5").update(bytecode).digest("hex"); +} + +async function generateVkForFunction(functionArtifact, outputFolder) { + const functionArtifactPath = getFunctionArtifactPath( + outputFolder, + functionArtifact.name + ); + const outputVkPath = getFunctionVkPath(outputFolder, functionArtifact.name); + + await fs.writeFile( + functionArtifactPath, + JSON.stringify(functionArtifact, null, 2) + ); + + try { + const writeVkCommand = `${BB_BIN_PATH} write_vk_mega_honk -h -b "${functionArtifactPath}" -o "${outputVkPath}" `; + + console.log("WRITE VK CMD: ", writeVkCommand); + + await new Promise((resolve, reject) => { + child_process.exec(`${writeVkCommand}`, (err) => { + if (err) { + reject(err); + } else { + resolve(); + } + }); + }); + const binaryVk = await fs.readFile(outputVkPath); + await fs.unlink(outputVkPath); + + return binaryVk; + } finally { + await fs.unlink(functionArtifactPath); + } +} + +async function main() { + let [artifactPath, tempFolder] = process.argv.slice(2); + const artifact = JSON.parse(await fs.readFile(artifactPath, "utf8")); + const barretenbergHash = await getBarretenbergHash(); + for (const functionArtifact of artifact.functions.filter((functionArtifact) => + functionArtifact.custom_attributes.includes("private") + )) { + const artifactName = `${artifact.name}-${functionArtifact.name}`; + const artifactHash = generateArtifactHash( + barretenbergHash, + await getBytecodeHash(functionArtifact), + true, + true + ); + if ( + functionArtifact.verification_key && + functionArtifact.artifact_hash === artifactHash + ) { + console.log("Reusing on disk VK for", artifactName); + } else { + let vk = await readVKFromS3(artifactName, artifactHash, false); + if (!vk) { + vk = await generateVkForFunction(functionArtifact, tempFolder); + await writeVKToS3(artifactName, artifactHash, vk); + } else { + console.log("Using VK from remote cache for", artifactName); + } + functionArtifact.verification_key = vk.toString("base64"); + functionArtifact.artifact_hash = artifactHash; + } + } + + await fs.writeFile(artifactPath, JSON.stringify(artifact, null, 2)); +} + +main().catch((err) => { + console.error(err); + process.exit(1); +}); diff --git a/noir-projects/scripts/generate_vk_json.js b/noir-projects/scripts/generate_vk_json.js index 47aebef30d7..c891d1f7ca4 100644 --- a/noir-projects/scripts/generate_vk_json.js +++ b/noir-projects/scripts/generate_vk_json.js @@ -1,20 +1,16 @@ const path = require("path"); const fs = require("fs/promises"); -const fs_stream = require("fs"); const child_process = require("child_process"); - -const { fromIni } = require("@aws-sdk/credential-providers"); -const { S3 } = require("@aws-sdk/client-s3"); - const crypto = require("crypto"); const megaHonkPatterns = require("../mega_honk_circuits.json"); - -const BB_BIN_PATH = - process.env.BB_BIN || - path.join(__dirname, "../../barretenberg/cpp/build/bin/bb"); -const BUCKET_NAME = "aztec-ci-artifacts"; -const PREFIX = "protocol"; +const { + readVKFromS3, + writeVKToS3, + getBarretenbergHash, + generateArtifactHash, + BB_BIN_PATH, +} = require("./verification_keys"); function vkBinaryFileNameForArtifactName(outputFolder, artifactName) { return path.join(outputFolder, `${artifactName}.vk`); @@ -28,32 +24,6 @@ function vkDataFileNameForArtifactName(outputFolder, artifactName) { return path.join(outputFolder, `${artifactName}.vk.data.json`); } -function getFunctionArtifactPath(outputFolder, functionName) { - return path.join(outputFolder, `${functionName}.tmp.json`); -} - -async function createFunctionArtifact( - contractArtifactPath, - functionName, - outputFolder -) { - const contractArtifact = JSON.parse(await fs.readFile(contractArtifactPath)); - const artifact = contractArtifact.functions.find( - (fn) => fn.name === functionName - ); - if (!artifact) { - throw new Error(`Cannot find artifact for function: ${functionName}.`); - } - - const artifactPath = getFunctionArtifactPath(outputFolder, functionName); - await fs.writeFile(artifactPath, JSON.stringify(artifact, null, 2)); - return artifactPath; -} - -async function removeFunctionArtifact(artifactPath) { - await fs.unlink(artifactPath); -} - async function getBytecodeHash(artifactPath) { const { bytecode } = JSON.parse(await fs.readFile(artifactPath)); if (!bytecode) { @@ -62,37 +32,6 @@ async function getBytecodeHash(artifactPath) { return crypto.createHash("md5").update(bytecode).digest("hex"); } -function getBarretenbergHash() { - if (process.env.BB_HASH) { - return Promise.resolve(process.env.BB_HASH); - } - return new Promise((res, rej) => { - const hash = crypto.createHash("md5"); - - const rStream = fs_stream.createReadStream(BB_BIN_PATH); - rStream.on("data", (data) => { - hash.update(data); - }); - rStream.on("end", () => { - res(hash.digest("hex")); - }); - rStream.on("error", (err) => { - rej(err); - }); - }); -} - -function generateArtifactHash( - barretenbergHash, - bytecodeHash, - isMegaHonk, - isRecursive -) { - return `${barretenbergHash}-${bytecodeHash}-${ - isMegaHonk ? "mega-honk" : "ultra-honk" - }-${isRecursive}`; -} - async function getArtifactHash(artifactPath, isMegaHonk, isRecursive) { const bytecodeHash = await getBytecodeHash(artifactPath); const barretenbergHash = await getBarretenbergHash(); @@ -128,12 +67,7 @@ function isMegaHonkCircuit(artifactName) { ); } -async function processArtifact( - artifactPath, - artifactName, - outputFolder, - syncWithS3 -) { +async function processArtifact(artifactPath, artifactName, outputFolder) { const isMegaHonk = isMegaHonkCircuit(artifactName); const isRecursive = true; @@ -151,9 +85,7 @@ async function processArtifact( return; } - let vkData = syncWithS3 - ? await readVKFromS3(artifactName, artifactHash) - : undefined; + let vkData = await readVKFromS3(artifactName, artifactHash); if (!vkData) { vkData = await generateVKData( artifactName, @@ -163,9 +95,7 @@ async function processArtifact( isMegaHonk, isRecursive ); - if (syncWithS3) { - await writeVKToS3(artifactName, artifactHash, JSON.stringify(vkData)); - } + await writeVKToS3(artifactName, artifactHash, JSON.stringify(vkData)); } else { console.log("Using VK from remote cache for", artifactName); } @@ -230,84 +160,19 @@ async function generateVKData( } async function main() { - let [artifactPath, outputFolder, functionName] = process.argv.slice(2); + let [artifactPath, outputFolder] = process.argv.slice(2); if (!artifactPath || !outputFolder) { console.log( - "Usage: node generate_vk_json.js [functionName]" + "Usage: node generate_vk_json.js " ); return; } - const sourceArtifactPath = !functionName - ? artifactPath - : await createFunctionArtifact(artifactPath, functionName, outputFolder); - - const artifactName = [ - path.basename(artifactPath, ".json"), - functionName ? `-${functionName}` : "", - ].join(""); - - const syncWithS3 = true; - await processArtifact( - sourceArtifactPath, - artifactName, - outputFolder, - syncWithS3 + artifactPath, + path.basename(artifactPath, ".json"), + outputFolder ); - - if (sourceArtifactPath !== artifactPath) { - await removeFunctionArtifact(sourceArtifactPath); - } -} - -function generateS3Client() { - return new S3({ - credentials: fromIni({ - profile: "default", - }), - region: "us-east-2", - }); -} - -async function writeVKToS3(artifactName, artifactHash, body) { - if (process.env.DISABLE_VK_S3_CACHE) { - return; - } - try { - const s3 = generateS3Client(); - await s3.putObject({ - Bucket: BUCKET_NAME, - Key: `${PREFIX}/${artifactName}-${artifactHash}.json`, - Body: body, - }); - } catch (err) { - console.warn("Could not write to S3 VK remote cache", err.message); - } -} - -async function readVKFromS3(artifactName, artifactHash) { - if (process.env.DISABLE_VK_S3_CACHE) { - return; - } - const key = `${PREFIX}/${artifactName}-${artifactHash}.json`; - - try { - const s3 = generateS3Client(); - const { Body: response } = await s3.getObject({ - Bucket: BUCKET_NAME, - Key: key, - }); - - const result = JSON.parse(await response.transformToString()); - return result; - } catch (err) { - console.warn( - `Could not read VK from remote cache at s3://${BUCKET_NAME}/${key}`, - err.message - ); - return undefined; - } } main().catch((err) => { diff --git a/noir-projects/scripts/verification_keys.js b/noir-projects/scripts/verification_keys.js new file mode 100644 index 00000000000..90fd90cb991 --- /dev/null +++ b/noir-projects/scripts/verification_keys.js @@ -0,0 +1,104 @@ +const { fromIni } = require("@aws-sdk/credential-providers"); +const { S3 } = require("@aws-sdk/client-s3"); +const fs_stream = require("fs"); +const path = require("path"); + +const BB_BIN_PATH = + process.env.BB_BIN || + path.join(__dirname, "../../barretenberg/cpp/build/bin/bb"); +const BUCKET_NAME = "aztec-ci-artifacts"; +const PREFIX = "protocol"; + +async function writeVKToS3(artifactName, artifactHash, body) { + if (process.env.DISABLE_VK_S3_CACHE) { + return; + } + try { + const s3 = generateS3Client(); + await s3.putObject({ + Bucket: BUCKET_NAME, + Key: `${PREFIX}/${artifactName}-${artifactHash}.json`, + Body: body, + }); + } catch (err) { + console.warn("Could not write to S3 VK remote cache", err.message); + } +} + +async function readVKFromS3(artifactName, artifactHash, json = true) { + if (process.env.DISABLE_VK_S3_CACHE) { + return; + } + const key = `${PREFIX}/${artifactName}-${artifactHash}.json`; + + try { + const s3 = generateS3Client(); + const { Body: response } = await s3.getObject({ + Bucket: BUCKET_NAME, + Key: key, + }); + + if (json) { + const result = JSON.parse(await response.transformToString()); + return result; + } else { + return Buffer.from(await response.transformToByteArray()); + } + } catch (err) { + if (err.name !== "NoSuchKey") { + console.warn( + `Could not read VK from remote cache at s3://${BUCKET_NAME}/${key}`, + err.message + ); + } + return undefined; + } +} + +function generateS3Client() { + return new S3({ + credentials: fromIni({ + profile: "default", + }), + region: "us-east-2", + }); +} + +function generateArtifactHash( + barretenbergHash, + bytecodeHash, + isMegaHonk, + isRecursive +) { + return `${barretenbergHash}-${bytecodeHash}-${ + isMegaHonk ? "mega-honk" : "ultra-honk" + }-${isRecursive}`; +} + +function getBarretenbergHash() { + if (process.env.BB_HASH) { + return Promise.resolve(process.env.BB_HASH); + } + return new Promise((res, rej) => { + const hash = crypto.createHash("md5"); + + const rStream = fs_stream.createReadStream(BB_BIN_PATH); + rStream.on("data", (data) => { + hash.update(data); + }); + rStream.on("end", () => { + res(hash.digest("hex")); + }); + rStream.on("error", (err) => { + rej(err); + }); + }); +} + +module.exports = { + BB_BIN_PATH, + writeVKToS3, + readVKFromS3, + generateArtifactHash, + getBarretenbergHash, +}; From a6983bd43b49cdfe213abcf149fa90958b55485f Mon Sep 17 00:00:00 2001 From: sirasistant Date: Tue, 5 Nov 2024 14:30:28 +0000 Subject: [PATCH 02/17] wip real vks --- .../barretenberg/dsl/acir_proofs/c_bind.cpp | 9 +++++++ .../barretenberg/dsl/acir_proofs/c_bind.hpp | 4 +++- barretenberg/exports.json | 16 +++++++++++++ barretenberg/ts/src/barretenberg_api/index.ts | 24 +++++++++++++++++++ .../validate_contract_address.nr | 9 +++---- .../crates/types/src/address/aztec_address.nr | 4 ++-- .../crates/types/src/hash.nr | 10 -------- .../verification_key/verification_key_data.ts | 4 ++-- .../src/contract/contract_class.ts | 13 ++++++---- yarn-project/circuits.js/src/hash/hash.ts | 22 ++++------------- yarn-project/foundation/src/abi/abi.ts | 2 +- yarn-project/foundation/src/crypto/index.ts | 1 + .../foundation/src/crypto/keys/index.ts | 9 +++++++ .../noir-protocol-circuits-types/src/index.ts | 1 - .../src/scripts/generate_vk_hashes.ts | 5 ++-- .../src/utils/vk_json.ts | 5 ---- .../src/protocol_contract_data.ts | 14 +++++------ .../src/scripts/generate_data.ts | 17 ------------- .../pxe/src/kernel_prover/kernel_prover.ts | 10 +++++--- .../types/src/abi/contract_artifact.ts | 3 +-- 20 files changed, 100 insertions(+), 82 deletions(-) create mode 100644 yarn-project/foundation/src/crypto/keys/index.ts diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp index 16553a32d4a..b9c1253eaf5 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp @@ -275,6 +275,15 @@ WASM_EXPORT void acir_vk_as_fields_ultra_honk(uint8_t const* vk_buf, fr::vec_out { using VerificationKey = UltraFlavor::VerificationKey; + auto verification_key = std::make_shared(from_buffer(vk_buf)); + std::vector vkey_as_fields = verification_key->to_field_elements(); + *out_vkey = to_heap_buffer(vkey_as_fields); +} + +WASM_EXPORT void acir_vk_as_fields_mega_honk(uint8_t const* vk_buf, fr::vec_out_buf out_vkey) +{ + using VerificationKey = MegaFlavor::VerificationKey; + auto verification_key = std::make_shared(from_buffer(vk_buf)); std::vector vkey_as_fields = verification_key->to_field_elements(); *out_vkey = to_heap_buffer(vkey_as_fields); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp index 2ed4613b666..9efd50e4721 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp @@ -93,4 +93,6 @@ WASM_EXPORT void acir_write_vk_ultra_honk(uint8_t const* acir_vec, bool const* r WASM_EXPORT void acir_proof_as_fields_ultra_honk(uint8_t const* proof_buf, fr::vec_out_buf out); -WASM_EXPORT void acir_vk_as_fields_ultra_honk(uint8_t const* vk_buf, fr::vec_out_buf out_vkey); \ No newline at end of file +WASM_EXPORT void acir_vk_as_fields_ultra_honk(uint8_t const* vk_buf, fr::vec_out_buf out_vkey); + +WASM_EXPORT void acir_vk_as_fields_mega_honk(uint8_t const* vk_buf, fr::vec_out_buf out_vkey); \ No newline at end of file diff --git a/barretenberg/exports.json b/barretenberg/exports.json index 67c4854c607..83b2a64ec71 100644 --- a/barretenberg/exports.json +++ b/barretenberg/exports.json @@ -917,5 +917,21 @@ } ], "isAsync": false + }, + { + "functionName": "acir_vk_as_fields_mega_honk", + "inArgs": [ + { + "name": "vk_buf", + "type": "const uint8_t *" + } + ], + "outArgs": [ + { + "name": "out_vkey", + "type": "fr::vec_out_buf" + } + ], + "isAsync": false } ] \ No newline at end of file diff --git a/barretenberg/ts/src/barretenberg_api/index.ts b/barretenberg/ts/src/barretenberg_api/index.ts index 06290eda204..a6ead4041b4 100644 --- a/barretenberg/ts/src/barretenberg_api/index.ts +++ b/barretenberg/ts/src/barretenberg_api/index.ts @@ -604,6 +604,18 @@ export class BarretenbergApi { const out = result.map((r, i) => outTypes[i].fromBuffer(r)); return out[0]; } + + async acirVkAsFieldsMegaHonk(vkBuf: Uint8Array): Promise { + const inArgs = [vkBuf].map(serializeBufferable); + const outTypes: OutputType[] = [VectorDeserializer(Fr)]; + const result = await this.wasm.callWasmExport( + 'acir_vk_as_fields_mega_honk', + inArgs, + outTypes.map(t => t.SIZE_IN_BYTES), + ); + const out = result.map((r, i) => outTypes[i].fromBuffer(r)); + return out[0]; + } } export class BarretenbergApiSync { constructor(protected wasm: BarretenbergWasm) {} @@ -1181,4 +1193,16 @@ export class BarretenbergApiSync { const out = result.map((r, i) => outTypes[i].fromBuffer(r)); return out[0]; } + + acirVkAsFieldsMegaHonk(vkBuf: Uint8Array): Fr[] { + const inArgs = [vkBuf].map(serializeBufferable); + const outTypes: OutputType[] = [VectorDeserializer(Fr)]; + const result = this.wasm.callWasmExport( + 'acir_vk_as_fields_mega_honk', + inArgs, + outTypes.map(t => t.SIZE_IN_BYTES), + ); + const out = result.map((r, i) => outTypes[i].fromBuffer(r)); + return out[0]; + } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/validate_contract_address.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/validate_contract_address.nr index b4b4e20086e..f611e6fceeb 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/validate_contract_address.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/validate_contract_address.nr @@ -1,7 +1,6 @@ use dep::types::{ abis::private_kernel::private_call_data::PrivateCallData, address::AztecAddress, - constants::MAX_PROTOCOL_CONTRACTS, hash::stdlib_recursion_verification_key_compress_native_vk, - merkle_tree::root::root_from_sibling_path, + constants::MAX_PROTOCOL_CONTRACTS, merkle_tree::root::root_from_sibling_path, }; pub fn validate_contract_address( @@ -11,13 +10,11 @@ pub fn validate_contract_address( let contract_address = private_call_data.public_inputs.call_context.contract_address; assert(!contract_address.is_zero(), "contract address cannot be zero"); - // TODO(https://github.com/AztecProtocol/aztec-packages/issues/3062): Why is this using a hash function from the stdlib::recursion namespace - let private_call_vk_hash = - stdlib_recursion_verification_key_compress_native_vk(private_call_data.vk); + private_call_data.vk.check_hash(); let computed_address = AztecAddress::compute_from_private_function( private_call_data.public_inputs.call_context.function_selector, - private_call_vk_hash, + private_call_data.vk.hash, private_call_data.function_leaf_membership_witness, private_call_data.contract_class_artifact_hash, private_call_data.contract_class_public_bytecode_commitment, diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr b/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr index 72f0c2485df..3dbaa0521a2 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr @@ -115,7 +115,7 @@ impl AztecAddress { pub fn compute_from_private_function( function_selector: FunctionSelector, - functino_vk_hash: Field, + function_vk_hash: Field, function_leaf_membership_witness: MembershipWitness, contract_class_artifact_hash: Field, contract_class_public_bytecode_commitment: Field, @@ -124,7 +124,7 @@ impl AztecAddress { ) -> Self { let private_functions_root = private_functions_root_from_siblings( function_selector, - functino_vk_hash, + function_vk_hash, function_leaf_membership_witness.leaf_index, function_leaf_membership_witness.sibling_path, ); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr b/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr index 5de0d2cf0f3..80ccd3129dd 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr @@ -129,16 +129,6 @@ pub fn merkle_hash(left: Field, right: Field) -> Field { poseidon2_hash([left, right]) } -pub fn stdlib_recursion_verification_key_compress_native_vk( - _vk: VerificationKey, -) -> Field { - // Original cpp code - // stdlib::recursion::verification_key::compress_native(private_call.vk, GeneratorIndex::VK); - // The above cpp method is only ever called on verification key, so it has been special cased here - let _hash_index = GENERATOR_INDEX__VK; - 0 -} - pub fn compute_l2_to_l1_hash( contract_address: AztecAddress, recipient: EthAddress, diff --git a/yarn-project/bb-prover/src/verification_key/verification_key_data.ts b/yarn-project/bb-prover/src/verification_key/verification_key_data.ts index fe4c55a31cf..14f5eb28c59 100644 --- a/yarn-project/bb-prover/src/verification_key/verification_key_data.ts +++ b/yarn-project/bb-prover/src/verification_key/verification_key_data.ts @@ -4,7 +4,7 @@ import { VerificationKeyAsFields, VerificationKeyData, } from '@aztec/circuits.js'; -import { hashVk } from '@aztec/noir-protocol-circuits-types'; +import { hashVK } from '@aztec/circuits.js/hash'; import { strict as assert } from 'assert'; import * as fs from 'fs/promises'; @@ -25,7 +25,7 @@ export async function extractVkData(vkDirectoryPath: string): Promise [e.y.toBuffer(), e.x.toBuffer()]) - .flat(), - // Montgomery form of fr::one()? Not sure. But if so, why? - Buffer.from('1418144d5b080fcac24cdb7649bdadf246a6cb2426e324bedb94fb05118f023a', 'hex'), - ]); - return pedersenHashBuffer(toHash); +export function hashVK(keyAsFields: Fr[]): Fr { + return poseidon2Hash(keyAsFields); } /** diff --git a/yarn-project/foundation/src/abi/abi.ts b/yarn-project/foundation/src/abi/abi.ts index a1d9c6aaab8..a762d4204f2 100644 --- a/yarn-project/foundation/src/abi/abi.ts +++ b/yarn-project/foundation/src/abi/abi.ts @@ -222,7 +222,7 @@ export interface FunctionAbi { export interface FunctionArtifact extends FunctionAbi { /** The ACIR bytecode of the function. */ bytecode: Buffer; - /** The verification key of the function. */ + /** The verification key of the function, base64 encoded, if it's a private fn. */ verificationKey?: string; /** Maps opcodes to source code pointers */ debugSymbols: string; diff --git a/yarn-project/foundation/src/crypto/index.ts b/yarn-project/foundation/src/crypto/index.ts index 4a93708f498..9385f359563 100644 --- a/yarn-project/foundation/src/crypto/index.ts +++ b/yarn-project/foundation/src/crypto/index.ts @@ -7,6 +7,7 @@ export * from './sha512/index.js'; export * from './pedersen/index.js'; export * from './poseidon/index.js'; export * from './secp256k1-signer/index.js'; +export * from './keys/index.js'; /** * Init the bb singleton. This constructs (if not already) the barretenberg sync api within bb.js itself. diff --git a/yarn-project/foundation/src/crypto/keys/index.ts b/yarn-project/foundation/src/crypto/keys/index.ts new file mode 100644 index 00000000000..7b2066717a2 --- /dev/null +++ b/yarn-project/foundation/src/crypto/keys/index.ts @@ -0,0 +1,9 @@ +import { BarretenbergSync, RawBuffer } from '@aztec/bb.js'; + +import { Fr } from '../../fields/fields.js'; + +export function vkAsFieldsMegaHonk(input: Buffer): Fr[] { + return BarretenbergSync.getSingleton() + .acirVkAsFieldsMegaHonk(new RawBuffer(input)) + .map(bbFr => Fr.fromBuffer(Buffer.from(bbFr.toBuffer()))); // TODO(#4189): remove this conversion +} diff --git a/yarn-project/noir-protocol-circuits-types/src/index.ts b/yarn-project/noir-protocol-circuits-types/src/index.ts index d592b373f22..bfda8a89930 100644 --- a/yarn-project/noir-protocol-circuits-types/src/index.ts +++ b/yarn-project/noir-protocol-circuits-types/src/index.ts @@ -108,7 +108,6 @@ export * from './artifacts.js'; export { maxPrivateKernelResetDimensions, privateKernelResetDimensionsConfig } from './private_kernel_reset_data.js'; export * from './utils/private_kernel_reset.js'; export * from './vks.js'; -export { hashVk } from './utils/vk_json.js'; /* eslint-disable camelcase */ diff --git a/yarn-project/noir-protocol-circuits-types/src/scripts/generate_vk_hashes.ts b/yarn-project/noir-protocol-circuits-types/src/scripts/generate_vk_hashes.ts index d8bc6e0ac96..a0a2573e9e0 100644 --- a/yarn-project/noir-protocol-circuits-types/src/scripts/generate_vk_hashes.ts +++ b/yarn-project/noir-protocol-circuits-types/src/scripts/generate_vk_hashes.ts @@ -1,12 +1,11 @@ import { Fr, VerificationKeyData } from '@aztec/circuits.js'; +import { hashVK } from '@aztec/circuits.js/hash'; import { createConsoleLogger } from '@aztec/foundation/log'; import { fileURLToPath } from '@aztec/foundation/url'; import fs from 'fs/promises'; import { join } from 'path'; -import { hashVk } from '../utils/vk_json.js'; - const log = createConsoleLogger('aztec:autogenerate'); function resolveRelativePath(relativePath: string) { @@ -34,7 +33,7 @@ const main = async () => { if (!content.vkHash) { const { keyAsFields } = content; - content.vkHash = hashVk(keyAsFields.map((str: string) => Fr.fromString(str))).toString(); + content.vkHash = hashVK(keyAsFields.map((str: string) => Fr.fromString(str))).toString(); await fs.writeFile(keyPath, JSON.stringify(content, null, 2)); } } diff --git a/yarn-project/noir-protocol-circuits-types/src/utils/vk_json.ts b/yarn-project/noir-protocol-circuits-types/src/utils/vk_json.ts index 6176bcbb68f..2640a9e5cbb 100644 --- a/yarn-project/noir-protocol-circuits-types/src/utils/vk_json.ts +++ b/yarn-project/noir-protocol-circuits-types/src/utils/vk_json.ts @@ -1,5 +1,4 @@ import { Fr, VerificationKeyAsFields, VerificationKeyData } from '@aztec/circuits.js'; -import { poseidon2Hash } from '@aztec/foundation/crypto'; interface VkJson { keyAsBytes: string; @@ -17,7 +16,3 @@ export function keyJsonToVKData(json: VkJson): VerificationKeyData { Buffer.from(keyAsBytes, 'hex'), ); } - -export function hashVk(keyAsFields: Fr[]): Fr { - return poseidon2Hash(keyAsFields); -} diff --git a/yarn-project/protocol-contracts/src/protocol_contract_data.ts b/yarn-project/protocol-contracts/src/protocol_contract_data.ts index db770ce0da4..16ca54a6eb4 100644 --- a/yarn-project/protocol-contracts/src/protocol_contract_data.ts +++ b/yarn-project/protocol-contracts/src/protocol_contract_data.ts @@ -50,14 +50,14 @@ export const ProtocolContractAddress: Record }; export const ProtocolContractLeaf = { - AuthRegistry: Fr.fromString('0x04d70cb3d8222ae04cfa59e8bfed4f804832aaaef4f485d1debb004d1b9d6362'), - ContractInstanceDeployer: Fr.fromString('0x04a661c9d4d295fc485a7e0f3de40c09b35366343bce8ad229106a8ef4076fe5'), - ContractClassRegisterer: Fr.fromString('0x147ba3294403576dbad10f86d3ffd4eb83fb230ffbcd5c8b153dd02942d0611f'), - MultiCallEntrypoint: Fr.fromString('0x154b701b41d6cf6da7204fef36b2ee9578b449d21b3792a9287bf45eba48fd26'), - FeeJuice: Fr.fromString('0x1067e9dc15d3046b6d21aaa8eafcfec88216217242cee3f9d722165ffc03c767'), - Router: Fr.fromString('0x16ab75e4efc0964c0ee3d715ac645d7972b722bfe60eea730a60b527c0681973'), + AuthRegistry: Fr.fromString('0x264d5813e33795397db05b027f17c6d16f38289f7e8c7ce3ed27a8428c5ffc47'), + ContractInstanceDeployer: Fr.fromString('0x0a2d2bebf9ed365ecf2fe61b1da069c93d3c0cc252a3ebd29a7e04c83bc88f52'), + ContractClassRegisterer: Fr.fromString('0x1f6709a774da0656ece30dcb29f604f13ea39e5bebba158ad4ee3ca55d32ee7d'), + MultiCallEntrypoint: Fr.fromString('0x1bf3e24391488ef068ffca602ba37aca41533a2e3c73fbea247340f31be05fd7'), + FeeJuice: Fr.fromString('0x1002548e0fa75e8aad3f6ed92a8e0f3dd99273139341b7c2fe2915ef7f32b571'), + Router: Fr.fromString('0x0713c42228cc09b0b0a0aaa010cb49d8ba1d9404c299e472693306127b17fac7'), }; export const protocolContractTreeRoot = Fr.fromString( - '0x2673f1d0618d2c98ccb3a11282073002f73335c4791eac16f67bf522e24151d1', + '0x2b9ff3b378c200af8b4bda92b6d0c5aebd3fe7d8b3d1265a412b9548e98559c7', ); diff --git a/yarn-project/protocol-contracts/src/scripts/generate_data.ts b/yarn-project/protocol-contracts/src/scripts/generate_data.ts index d42345c68e9..0d226bcc99f 100644 --- a/yarn-project/protocol-contracts/src/scripts/generate_data.ts +++ b/yarn-project/protocol-contracts/src/scripts/generate_data.ts @@ -50,10 +50,6 @@ async function clearDestDir() { await fs.mkdir(destArtifactsDir, { recursive: true }); } -function getPrivateFunctionNames(artifact: NoirCompiledContract) { - return artifact.functions.filter(fn => fn.custom_attributes.includes('private')).map(fn => fn.name); -} - async function copyArtifact(srcName: string, destName: string) { const src = path.join(srcPath, `${srcName}.json`); const artifact = JSON.parse(await fs.readFile(src, 'utf8')) as NoirCompiledContract; @@ -62,17 +58,6 @@ async function copyArtifact(srcName: string, destName: string) { return artifact; } -async function copyVks(srcName: string, destName: string, fnNames: string[]) { - const deskVksDir = path.join(destArtifactsDir, 'keys', destName); - await fs.mkdir(deskVksDir, { recursive: true }); - - for (const fnName of fnNames) { - const src = path.join(srcPath, 'keys', `${srcName}-${fnName}.vk.data.json`); - const dest = path.join(deskVksDir, `${fnName}.vk.data.json`); - await fs.copyFile(src, dest); - } -} - function computeContractLeaf(artifact: NoirCompiledContract) { const instance = getContractInstanceFromDeployParams(loadContractArtifact(artifact), { salt }); return instance.address; @@ -191,8 +176,6 @@ async function main() { const srcName = srcNames[i]; const destName = destNames[i]; const artifact = await copyArtifact(srcName, destName); - const fnNames = getPrivateFunctionNames(artifact); - await copyVks(srcName, destName, fnNames); await generateDeclarationFile(destName); leaves.push(computeContractLeaf(artifact)); } diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts index d4ce8006693..0a949026414 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts @@ -23,7 +23,9 @@ import { VK_TREE_HEIGHT, VerificationKeyAsFields, } from '@aztec/circuits.js'; +import { hashVK } from '@aztec/circuits.js/hash'; import { makeTuple } from '@aztec/foundation/array'; +import { vkAsFieldsMegaHonk } from '@aztec/foundation/crypto'; import { createDebugLogger } from '@aztec/foundation/log'; import { assertLength } from '@aztec/foundation/serialize'; import { pushTestData } from '@aztec/foundation/testing'; @@ -143,8 +145,7 @@ export class KernelProver { await addGateCount(functionName as string, currentExecution.acir); } - const appVk = await this.proofCreator.computeAppCircuitVerificationKey(currentExecution.acir, functionName); - const privateCallData = await this.createPrivateCallData(currentExecution, appVk.verificationKey); + const privateCallData = await this.createPrivateCallData(currentExecution); if (firstIteration) { const proofInput = new PrivateKernelInitCircuitPrivateInputs( @@ -241,9 +242,12 @@ export class KernelProver { return tailOutput; } - private async createPrivateCallData({ publicInputs }: PrivateExecutionResult, vk: VerificationKeyAsFields) { + private async createPrivateCallData({ publicInputs, vk: vkAsBuffer }: PrivateExecutionResult) { const { contractAddress, functionSelector } = publicInputs.callContext; + const vkAsFields = vkAsFieldsMegaHonk(vkAsBuffer); + const vk = new VerificationKeyAsFields(vkAsFields, hashVK(vkAsFields)); + const functionLeafMembershipWitness = await this.oracle.getFunctionMembershipWitness( contractAddress, functionSelector, diff --git a/yarn-project/types/src/abi/contract_artifact.ts b/yarn-project/types/src/abi/contract_artifact.ts index 73896129f2f..e718b6237af 100644 --- a/yarn-project/types/src/abi/contract_artifact.ts +++ b/yarn-project/types/src/abi/contract_artifact.ts @@ -23,7 +23,6 @@ import { AZTEC_VIEW_ATTRIBUTE, type NoirCompiledContract, } from '../noir/index.js'; -import { mockVerificationKey } from './mocked_keys.js'; /** * Serializes a contract artifact to a buffer for storage. @@ -180,7 +179,7 @@ function generateFunctionArtifact(fn: NoirCompiledContractFunction, contract: No parameters, returnTypes, bytecode: Buffer.from(fn.bytecode, 'base64'), - verificationKey: mockVerificationKey, + verificationKey: fn.verification_key, debugSymbols: fn.debug_symbols, errorTypes: fn.abi.error_types, }; From ec25cf2982f492e3a1ea07aba13dc15f8abf29a1 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Tue, 5 Nov 2024 14:56:47 +0000 Subject: [PATCH 03/17] fix --- .../validate_contract_address.nr | 5 +++++ .../aztec.js/src/deployment/broadcast_function.ts | 2 +- .../circuits.js/src/contract/contract_class.ts | 13 +++++++------ .../private_function_membership_proof.test.ts | 2 +- .../simulator/src/client/private_execution.ts | 2 +- 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/validate_contract_address.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/validate_contract_address.nr index f611e6fceeb..c9bbdaaece0 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/validate_contract_address.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/validate_contract_address.nr @@ -2,6 +2,7 @@ use dep::types::{ abis::private_kernel::private_call_data::PrivateCallData, address::AztecAddress, constants::MAX_PROTOCOL_CONTRACTS, merkle_tree::root::root_from_sibling_path, }; +use types::debug_log::debug_log_format; pub fn validate_contract_address( private_call_data: PrivateCallData, @@ -23,6 +24,10 @@ pub fn validate_contract_address( ); let protocol_contract_index = contract_address.to_field(); + debug_log_format( + "protocol_contract_index:{0} with computed_address: {1}", + [protocol_contract_index, computed_address.to_field()], + ); let computed_protocol_contract_tree_root = if (MAX_PROTOCOL_CONTRACTS as Field).lt( protocol_contract_index, ) { diff --git a/yarn-project/aztec.js/src/deployment/broadcast_function.ts b/yarn-project/aztec.js/src/deployment/broadcast_function.ts index 6dcf5b6ec0a..599d2d4b63c 100644 --- a/yarn-project/aztec.js/src/deployment/broadcast_function.ts +++ b/yarn-project/aztec.js/src/deployment/broadcast_function.ts @@ -44,7 +44,7 @@ export async function broadcastPrivateFunction( privateFunctionTreeLeafIndex, } = createPrivateFunctionMembershipProof(selector, artifact); - const vkHash = computeVerificationKeyHash(privateFunctionArtifact.verificationKey!); + const vkHash = computeVerificationKeyHash(privateFunctionArtifact); const bytecode = bufferAsFields( privateFunctionArtifact.bytecode, MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS, diff --git a/yarn-project/circuits.js/src/contract/contract_class.ts b/yarn-project/circuits.js/src/contract/contract_class.ts index 1db6269dbc4..74915757622 100644 --- a/yarn-project/circuits.js/src/contract/contract_class.ts +++ b/yarn-project/circuits.js/src/contract/contract_class.ts @@ -65,15 +65,16 @@ export function getContractClassPrivateFunctionFromArtifact( } return { selector: FunctionSelector.fromNameAndParameters(f.name, f.parameters), - vkHash: computeVerificationKeyHash(f.verificationKey!), + vkHash: computeVerificationKeyHash(f), }; } /** - * Calculates the hash of a verification key. + * For a given private function, computes the hash of its vk. */ -export function computeVerificationKeyHash(verificationKeyInBase64: string) { - const vkBuffer = Buffer.from(verificationKeyInBase64, 'base64'); - const vkAsFields = vkAsFieldsMegaHonk(vkBuffer); - return hashVK(vkAsFields); +export function computeVerificationKeyHash(f: FunctionArtifact) { + if (!f.verificationKey) { + throw new Error('Private function must have a verification key'); + } + return hashVK(vkAsFieldsMegaHonk(Buffer.from(f.verificationKey, 'base64'))); } diff --git a/yarn-project/circuits.js/src/contract/private_function_membership_proof.test.ts b/yarn-project/circuits.js/src/contract/private_function_membership_proof.test.ts index c63a517957d..2135967d9d4 100644 --- a/yarn-project/circuits.js/src/contract/private_function_membership_proof.test.ts +++ b/yarn-project/circuits.js/src/contract/private_function_membership_proof.test.ts @@ -21,7 +21,7 @@ describe('private_function_membership_proof', () => { artifact = getBenchmarkContractArtifact(); contractClass = getContractClassFromArtifact(artifact); privateFunction = artifact.functions.findLast(fn => fn.functionType === FunctionType.PRIVATE)!; - vkHash = computeVerificationKeyHash(privateFunction.verificationKey!); + vkHash = computeVerificationKeyHash(privateFunction); selector = FunctionSelector.fromNameAndParameters(privateFunction); }); diff --git a/yarn-project/simulator/src/client/private_execution.ts b/yarn-project/simulator/src/client/private_execution.ts index d27db358c56..73fc9742ed5 100644 --- a/yarn-project/simulator/src/client/private_execution.ts +++ b/yarn-project/simulator/src/client/private_execution.ts @@ -76,7 +76,7 @@ export async function executePrivateFunction( return new PrivateExecutionResult( acir, - Buffer.from(artifact.verificationKey!, 'hex'), + Buffer.from(artifact.verificationKey!, 'base64'), partialWitness, publicInputs, noteHashLeafIndexMap, From 09d96401a111afae302b5aa99b2a01be19138382 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Tue, 5 Nov 2024 16:00:45 +0000 Subject: [PATCH 04/17] fix noir tests --- .../crates/types/src/tests/fixture_builder.nr | 22 +++++++++++++------ .../src/tests/fixtures/contract_functions.nr | 8 ++++--- .../src/contract/contract_class.ts | 5 +---- .../src/protocol_contract_data.ts | 8 +++---- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr index f48dff6111c..9b90fff5998 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr @@ -41,10 +41,10 @@ use crate::{ }, address::{AztecAddress, EthAddress, SaltedInitializationHash}, constants::{ - FUNCTION_TREE_HEIGHT, MAX_ENCRYPTED_LOGS_PER_TX, MAX_FIELD_VALUE, - MAX_KEY_VALIDATION_REQUESTS_PER_TX, MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX, - MAX_L2_TO_L1_MSGS_PER_TX, MAX_NOTE_ENCRYPTED_LOGS_PER_TX, - MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NOTE_HASHES_PER_TX, + CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS, FUNCTION_TREE_HEIGHT, + MAX_ENCRYPTED_LOGS_PER_TX, MAX_FIELD_VALUE, MAX_KEY_VALIDATION_REQUESTS_PER_TX, + MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX, MAX_L2_TO_L1_MSGS_PER_TX, + MAX_NOTE_ENCRYPTED_LOGS_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX, MAX_NULLIFIER_READ_REQUESTS_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_PUBLIC_DATA_READS_PER_CALL, @@ -205,7 +205,10 @@ impl FixtureBuilder { let contract_data = fixtures::contracts::default_contract; let contract_function = fixtures::contract_functions::default_private_function; - builder.use_contract(contract_data).use_function(contract_function) + builder.use_contract(contract_data).use_function( + contract_function, + fixtures::contract_functions::default_vk, + ) } pub fn as_parent_contract(&mut self) -> Self { @@ -248,7 +251,7 @@ impl FixtureBuilder { let _ = self.use_contract(contract_data); self.contract_address = AztecAddress::from_field(contract_index as Field); - self.use_function(function_data) + self.use_function(function_data, fixtures::contract_functions::default_vk) } pub fn use_contract(&mut self, contract_data: ContractData) -> Self { @@ -261,10 +264,15 @@ impl FixtureBuilder { *self } - pub fn use_function(&mut self, function_data: ContractFunction) -> Self { + pub fn use_function( + &mut self, + function_data: ContractFunction, + vk: [Field; CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS], + ) -> Self { self.function_data = function_data.data; self.function_leaf_membership_witness = function_data.membership_witness; self.acir_hash = function_data.acir_hash; + self.client_ivc_vk = VerificationKey { key: vk, hash: function_data.vk_hash }; *self } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures/contract_functions.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures/contract_functions.nr index ffecfd4ef69..9a08c162fcc 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures/contract_functions.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures/contract_functions.nr @@ -1,5 +1,5 @@ use crate::abis::{function_data::FunctionData, function_selector::FunctionSelector}; -use crate::constants::FUNCTION_TREE_HEIGHT; +use crate::constants::{CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS, FUNCTION_TREE_HEIGHT}; use crate::merkle_tree::membership::MembershipWitness; pub struct ContractFunction { @@ -9,10 +9,12 @@ pub struct ContractFunction { membership_witness: MembershipWitness, } +global default_vk = [0; CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS]; + // sibling_path taken from __snapshots__/noir_test_gen.test.ts.snap global default_private_function = ContractFunction { data: FunctionData { selector: FunctionSelector { inner: 1010101 }, is_private: true }, - vk_hash: 0, + vk_hash: crate::hash::verification_key_hash(default_vk), acir_hash: 1111, membership_witness: MembershipWitness { leaf_index: 0, @@ -48,7 +50,7 @@ pub fn get_protocol_contract_function(contract_index: u32) -> ContractFunction { selector: FunctionSelector { inner: 98989 + contract_index }, is_private: true, }, - vk_hash: 0, + vk_hash: crate::hash::verification_key_hash(default_vk), acir_hash: 5555 + contract_index as Field, membership_witness: MembershipWitness { leaf_index: contract_index as Field, diff --git a/yarn-project/circuits.js/src/contract/contract_class.ts b/yarn-project/circuits.js/src/contract/contract_class.ts index 74915757622..8809a2bbe02 100644 --- a/yarn-project/circuits.js/src/contract/contract_class.ts +++ b/yarn-project/circuits.js/src/contract/contract_class.ts @@ -60,9 +60,6 @@ export function getContractClassFromArtifact( export function getContractClassPrivateFunctionFromArtifact( f: FunctionArtifact, ): ContractClass['privateFunctions'][number] { - if (!f.verificationKey) { - throw new Error('Private function must have a verification key'); - } return { selector: FunctionSelector.fromNameAndParameters(f.name, f.parameters), vkHash: computeVerificationKeyHash(f), @@ -74,7 +71,7 @@ export function getContractClassPrivateFunctionFromArtifact( */ export function computeVerificationKeyHash(f: FunctionArtifact) { if (!f.verificationKey) { - throw new Error('Private function must have a verification key'); + throw new Error(`Private function ${f.name} must have a verification key`); } return hashVK(vkAsFieldsMegaHonk(Buffer.from(f.verificationKey, 'base64'))); } diff --git a/yarn-project/protocol-contracts/src/protocol_contract_data.ts b/yarn-project/protocol-contracts/src/protocol_contract_data.ts index 16ca54a6eb4..d15809994ce 100644 --- a/yarn-project/protocol-contracts/src/protocol_contract_data.ts +++ b/yarn-project/protocol-contracts/src/protocol_contract_data.ts @@ -52,12 +52,12 @@ export const ProtocolContractAddress: Record export const ProtocolContractLeaf = { AuthRegistry: Fr.fromString('0x264d5813e33795397db05b027f17c6d16f38289f7e8c7ce3ed27a8428c5ffc47'), ContractInstanceDeployer: Fr.fromString('0x0a2d2bebf9ed365ecf2fe61b1da069c93d3c0cc252a3ebd29a7e04c83bc88f52'), - ContractClassRegisterer: Fr.fromString('0x1f6709a774da0656ece30dcb29f604f13ea39e5bebba158ad4ee3ca55d32ee7d'), + ContractClassRegisterer: Fr.fromString('0x0f88f50f884e2eec68412b410c4a3aa59c01db01a1abd56ef565135260a6f9a7'), MultiCallEntrypoint: Fr.fromString('0x1bf3e24391488ef068ffca602ba37aca41533a2e3c73fbea247340f31be05fd7'), - FeeJuice: Fr.fromString('0x1002548e0fa75e8aad3f6ed92a8e0f3dd99273139341b7c2fe2915ef7f32b571'), - Router: Fr.fromString('0x0713c42228cc09b0b0a0aaa010cb49d8ba1d9404c299e472693306127b17fac7'), + FeeJuice: Fr.fromString('0x09230c2f71ca8177ccc6739319384b30f496d9d67586bafe50084f690b466fcc'), + Router: Fr.fromString('0x216898d7b99953e9650f5889a515077739e4f2db6e71a557b7cd85d5494ba1d4'), }; export const protocolContractTreeRoot = Fr.fromString( - '0x2b9ff3b378c200af8b4bda92b6d0c5aebd3fe7d8b3d1265a412b9548e98559c7', + '0x26b6a04e7986132a4c4565895b74078deafd21569a83f24e2c0021fb9c4e9630', ); From 894a75a4d35a1ff8aab595f7331586525340685d Mon Sep 17 00:00:00 2001 From: sirasistant Date: Tue, 5 Nov 2024 16:10:51 +0000 Subject: [PATCH 05/17] fixes --- noir-projects/noir-contracts/bootstrap.sh | 8 ++++---- ...clude_verification_keys.js => postprocess_contract.js} | 7 +++++-- yarn-project/types/src/abi/contract_artifact.ts | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) rename noir-projects/noir-contracts/scripts/{include_verification_keys.js => postprocess_contract.js} (91%) diff --git a/noir-projects/noir-contracts/bootstrap.sh b/noir-projects/noir-contracts/bootstrap.sh index 79e93bd2cfd..655a7d638d0 100755 --- a/noir-projects/noir-contracts/bootstrap.sh +++ b/noir-projects/noir-contracts/bootstrap.sh @@ -22,12 +22,12 @@ $NARGO compile --silence-warnings --inliner-aggressiveness 0 echo "Transpiling contracts..." scripts/transpile.sh -echo "Generating contract vks..." +echo "Postprocessing contracts..." BB_HASH=${BB_HASH:-$(cd ../../ && git ls-tree -r HEAD | grep 'barretenberg/cpp' | awk '{print $3}' | git hash-object --stdin)} echo Using BB hash $BB_HASH -vkDir="./target/keys" -mkdir -p $vkDir +tempDir="./target/tmp" +mkdir -p $tempDir for artifactPath in "./target"/*.json; do - BB_HASH=$BB_HASH node ./scripts/include_verification_keys.js "$artifactPath" "$vkDir" + BB_HASH=$BB_HASH node ./scripts/postprocess_contract.js "$artifactPath" "$tempDir" done diff --git a/noir-projects/noir-contracts/scripts/include_verification_keys.js b/noir-projects/noir-contracts/scripts/postprocess_contract.js similarity index 91% rename from noir-projects/noir-contracts/scripts/include_verification_keys.js rename to noir-projects/noir-contracts/scripts/postprocess_contract.js index d3c02dc0748..b423bf2a50f 100644 --- a/noir-projects/noir-contracts/scripts/include_verification_keys.js +++ b/noir-projects/noir-contracts/scripts/postprocess_contract.js @@ -64,8 +64,11 @@ async function main() { let [artifactPath, tempFolder] = process.argv.slice(2); const artifact = JSON.parse(await fs.readFile(artifactPath, "utf8")); const barretenbergHash = await getBarretenbergHash(); - for (const functionArtifact of artifact.functions.filter((functionArtifact) => - functionArtifact.custom_attributes.includes("private") + for (const functionArtifact of artifact.functions.filter( + // See contract_artifact.ts (getFunctionType) for reference + (functionArtifact) => + !functionArtifact.custom_attributes.includes("public") && + !functionArtifact.is_unconstrained )) { const artifactName = `${artifact.name}-${functionArtifact.name}`; const artifactHash = generateArtifactHash( diff --git a/yarn-project/types/src/abi/contract_artifact.ts b/yarn-project/types/src/abi/contract_artifact.ts index e718b6237af..e6c12bd4427 100644 --- a/yarn-project/types/src/abi/contract_artifact.ts +++ b/yarn-project/types/src/abi/contract_artifact.ts @@ -128,7 +128,7 @@ function generateFunctionParameter(param: NoirCompiledContractFunctionParameter) type NoirCompiledContractFunction = NoirCompiledContract['functions'][number]; /** - * Generates a function build artifact. Replaces verification key with a mock value. + * Generates a function build artifact. * @param fn - Noir function entry. * @param contract - Parent contract. * @returns Function artifact. From ed6819dfbf77c8bc2ed459fc71c0a0221994ee8e Mon Sep 17 00:00:00 2001 From: sirasistant Date: Tue, 5 Nov 2024 16:23:14 +0000 Subject: [PATCH 06/17] chore: update protocol contract data --- .../protocol-contracts/src/protocol_contract_data.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/yarn-project/protocol-contracts/src/protocol_contract_data.ts b/yarn-project/protocol-contracts/src/protocol_contract_data.ts index d15809994ce..6e164ad14ad 100644 --- a/yarn-project/protocol-contracts/src/protocol_contract_data.ts +++ b/yarn-project/protocol-contracts/src/protocol_contract_data.ts @@ -52,12 +52,12 @@ export const ProtocolContractAddress: Record export const ProtocolContractLeaf = { AuthRegistry: Fr.fromString('0x264d5813e33795397db05b027f17c6d16f38289f7e8c7ce3ed27a8428c5ffc47'), ContractInstanceDeployer: Fr.fromString('0x0a2d2bebf9ed365ecf2fe61b1da069c93d3c0cc252a3ebd29a7e04c83bc88f52'), - ContractClassRegisterer: Fr.fromString('0x0f88f50f884e2eec68412b410c4a3aa59c01db01a1abd56ef565135260a6f9a7'), - MultiCallEntrypoint: Fr.fromString('0x1bf3e24391488ef068ffca602ba37aca41533a2e3c73fbea247340f31be05fd7'), + ContractClassRegisterer: Fr.fromString('0x1f6709a774da0656ece30dcb29f604f13ea39e5bebba158ad4ee3ca55d32ee7d'), + MultiCallEntrypoint: Fr.fromString('0x2be4d47f4c42bf7c74e75387229c8e0cc89d0d086449122a5265abdf5ea70129'), FeeJuice: Fr.fromString('0x09230c2f71ca8177ccc6739319384b30f496d9d67586bafe50084f690b466fcc'), - Router: Fr.fromString('0x216898d7b99953e9650f5889a515077739e4f2db6e71a557b7cd85d5494ba1d4'), + Router: Fr.fromString('0x0713c42228cc09b0b0a0aaa010cb49d8ba1d9404c299e472693306127b17fac7'), }; export const protocolContractTreeRoot = Fr.fromString( - '0x26b6a04e7986132a4c4565895b74078deafd21569a83f24e2c0021fb9c4e9630', + '0x18584311736bcb2bc73511541f10e7f7e80a07091b6da022bddb257f96c36f00', ); From a1978bfbce72abf34d1e42cdd5660c0f4df9365d Mon Sep 17 00:00:00 2001 From: sirasistant Date: Wed, 6 Nov 2024 10:58:51 +0000 Subject: [PATCH 07/17] wip postprocess --- .../scripts/compile_then_transpile.sh | 28 +++++++++++++++---- aztec-nargo/Dockerfile | 3 ++ 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/avm-transpiler/scripts/compile_then_transpile.sh b/avm-transpiler/scripts/compile_then_transpile.sh index 97303dd314b..85d0b66b562 100755 --- a/avm-transpiler/scripts/compile_then_transpile.sh +++ b/avm-transpiler/scripts/compile_then_transpile.sh @@ -2,13 +2,14 @@ # This is a wrapper script for nargo. # Pass any args that you'd normally pass to nargo. # If the first arg is "compile", -# run nargo and then transpile any created artifacts. +# run nargo and then postprocess any created artifacts. # # Usage: compile_then_transpile.sh [nargo args] set -eu NARGO=${NARGO:-nargo} TRANSPILER=${TRANSPILER:-avm-transpiler} +BB=${BB:-bb} if [ "${1:-}" != "compile" ]; then # if not compiling, just pass through to nargo verbatim @@ -18,14 +19,31 @@ fi shift # remove the compile arg so we can inject --show-artifact-paths # Forward all arguments to nargo, tee output to console -artifacts_to_transpile=$($NARGO compile --show-artifact-paths $@ | tee /dev/tty | grep -oP 'Saved contract artifact to: \K.*') +artifacts_to_process=$($NARGO compile --show-artifact-paths $@ | tee /dev/tty | grep -oP 'Saved contract artifact to: \K.*') # NOTE: the output that is teed to /dev/tty will normally not be redirectable by the caller. # If the script is run via docker, however, the user will see this output on stdout and will be able to redirect. -# Transpile each artifact -# `$artifacts_to_transpile` needs to be unquoted here, otherwise it will break if there are multiple artifacts -for artifact in $artifacts_to_transpile; do +# Postprocess each artifact +# `$artifacts_to_process` needs to be unquoted here, otherwise it will break if there are multiple artifacts +for artifact in $artifacts_to_process; do # transpiler input and output files are the same (modify in-place) $TRANSPILER "$artifact" "$artifact" + artifact_name=$(basename "$artifact") + echo "Generating verification keys for functions in $artifact_name" + # See contract_artifact.ts (getFunctionType) for reference + private_fn_indices=$(jq -r '.functions | to_entries | map(select((.value.custom_attributes | contains(["public"]) | not) and (.value.is_unconstrained == false))) | map(.key) | join(" ")' $artifact) + for fn_index in $private_fn_indices; do + fn_name=$(jq -r ".functions[$fn_index].name" $artifact) + fn_artifact=$(jq -r ".functions[$fn_index]" $artifact) + fn_artifact_path="$artifact.function_artifact_$fn_index.json" + echo $fn_artifact > $fn_artifact_path + + 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) + rm $fn_artifact_path + jq ".functions[$fn_index].verification_key = \"$verification_key\"" $artifact > $artifact.tmp + mv $artifact.tmp $artifact + done done diff --git a/aztec-nargo/Dockerfile b/aztec-nargo/Dockerfile index 95473b82f59..2a0626f60c8 100644 --- a/aztec-nargo/Dockerfile +++ b/aztec-nargo/Dockerfile @@ -4,6 +4,9 @@ FROM aztecprotocol/noir AS built-noir # to get built avm-transpiler binary FROM aztecprotocol/avm-transpiler AS built-transpiler +# to get built barretenberg binary +FROM --platform=linux/amd64 aztecprotocol/barretenberg-x86_64-linux-clang as barretenberg + FROM ubuntu:noble # Install Tini as nargo doesn't handle signals properly. From 45b84bbaf1eab1f069e311eaa2d47e0894fdeea1 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Wed, 6 Nov 2024 11:39:55 +0000 Subject: [PATCH 08/17] chore: update dockerfiles and earthfiles --- avm-transpiler/Dockerfile | 1 - avm-transpiler/Earthfile | 1 - aztec-nargo/Dockerfile | 6 ++++-- aztec-nargo/Earthfile | 6 ++++-- .../compile_then_postprocess.sh | 2 +- boxes/Dockerfile | 10 ++++++++-- boxes/Earthfile | 7 ++++++- 7 files changed, 23 insertions(+), 10 deletions(-) rename avm-transpiler/scripts/compile_then_transpile.sh => aztec-nargo/compile_then_postprocess.sh (97%) diff --git a/avm-transpiler/Dockerfile b/avm-transpiler/Dockerfile index d695622a009..3d26426c478 100644 --- a/avm-transpiler/Dockerfile +++ b/avm-transpiler/Dockerfile @@ -9,6 +9,5 @@ RUN apt-get update && apt-get install -y git RUN ./scripts/bootstrap_native.sh FROM ubuntu:noble -COPY --from=0 /usr/src/avm-transpiler/scripts/compile_then_transpile.sh /usr/src/avm-transpiler/scripts/compile_then_transpile.sh COPY --from=0 /usr/src/avm-transpiler/target/release/avm-transpiler /usr/src/avm-transpiler/target/release/avm-transpiler ENTRYPOINT ["/usr/src/avm-transpiler/target/release/avm-transpiler"] diff --git a/avm-transpiler/Earthfile b/avm-transpiler/Earthfile index e4db70ea091..fc7ed7e5feb 100644 --- a/avm-transpiler/Earthfile +++ b/avm-transpiler/Earthfile @@ -18,7 +18,6 @@ build: --command="./scripts/bootstrap_native.sh && rm -rf target/release/{build,deps}" \ --build_artifacts="target" SAVE ARTIFACT target/release/avm-transpiler avm-transpiler - SAVE ARTIFACT scripts/compile_then_transpile.sh format: FROM +source diff --git a/aztec-nargo/Dockerfile b/aztec-nargo/Dockerfile index 2a0626f60c8..5d33560568e 100644 --- a/aztec-nargo/Dockerfile +++ b/aztec-nargo/Dockerfile @@ -16,7 +16,9 @@ RUN apt-get update && apt-get install -y git tini && rm -rf /var/lib/apt/lists/* # Copy binaries to /usr/bin COPY --from=built-noir /usr/src/noir/noir-repo/target/release/nargo /usr/bin/nargo COPY --from=built-transpiler /usr/src/avm-transpiler/target/release/avm-transpiler /usr/bin/avm-transpiler +COPY --from=barretenberg /usr/src/barretenberg/cpp/build/bin/bb /usr/bin/bb + # Copy in script that calls both binaries -COPY ./avm-transpiler/scripts/compile_then_transpile.sh /usr/src/avm-transpiler/scripts/compile_then_transpile.sh +COPY ./aztec-nargo/scripts/compile_then_postprocess.sh /usr/src/aztec-nargo/scripts/compile_then_postprocess.sh -ENTRYPOINT ["/usr/bin/tini", "--", "/usr/src/avm-transpiler/scripts/compile_then_transpile.sh"] +ENTRYPOINT ["/usr/bin/tini", "--", "/usr/src/avm-transpiler/scripts/compile_then_postprocess.sh"] diff --git a/aztec-nargo/Earthfile b/aztec-nargo/Earthfile index f0615e9bd65..63d170e599e 100644 --- a/aztec-nargo/Earthfile +++ b/aztec-nargo/Earthfile @@ -9,11 +9,13 @@ run: # Copy binaries to /usr/bin COPY ../noir+nargo/nargo /usr/bin/nargo COPY ../avm-transpiler+build/avm-transpiler /usr/bin/avm-transpiler + COPY ../barretenberg/cpp/+preset-release/bin/bb /usr/bin/bb + # Copy in script that calls both binaries - COPY ../avm-transpiler+build/compile_then_transpile.sh /usr/bin/compile_then_transpile.sh + COPY ./compile_then_postprocess.sh /usr/bin/compile_then_postprocess.sh ENV PATH "/usr/bin:${PATH}" - ENTRYPOINT ["/usr/bin/tini", "--", "/usr/bin/compile_then_transpile.sh"] + ENTRYPOINT ["/usr/bin/tini", "--", "/usr/bin/compile_then_postprocess.sh"] SAVE IMAGE aztecprotocol/aztec-nargo export-aztec-nargo: diff --git a/avm-transpiler/scripts/compile_then_transpile.sh b/aztec-nargo/compile_then_postprocess.sh similarity index 97% rename from avm-transpiler/scripts/compile_then_transpile.sh rename to aztec-nargo/compile_then_postprocess.sh index 85d0b66b562..c859377609d 100755 --- a/avm-transpiler/scripts/compile_then_transpile.sh +++ b/aztec-nargo/compile_then_postprocess.sh @@ -4,7 +4,7 @@ # If the first arg is "compile", # run nargo and then postprocess any created artifacts. # -# Usage: compile_then_transpile.sh [nargo args] +# Usage: compile_then_postprocess.sh [nargo args] set -eu NARGO=${NARGO:-nargo} diff --git a/boxes/Dockerfile b/boxes/Dockerfile index 6ca01d2f468..26707b8a08b 100644 --- a/boxes/Dockerfile +++ b/boxes/Dockerfile @@ -2,17 +2,23 @@ FROM aztecprotocol/aztec AS aztec FROM aztecprotocol/noir as noir FROM aztecprotocol/noir-projects as noir-projects +FROM --platform=linux/amd64 aztecprotocol/barretenberg-x86_64-linux-clang as barretenberg +FROM aztecprotocol/avm-transpiler AS transpiler # We need yarn. Start fresh container. FROM node:18.19.0 RUN apt update && apt install netcat-openbsd COPY --from=aztec /usr/src /usr/src -COPY --from=noir /usr/src/noir/noir-repo/target/release/nargo /usr/src/noir/noir-repo/target/release/nargo COPY --from=noir-projects /usr/src/noir-projects/aztec-nr /usr/src/noir-projects/aztec-nr COPY --from=noir-projects /usr/src/noir-projects/noir-protocol-circuits/crates/types /usr/src/noir-projects/noir-protocol-circuits/crates/types +# Copy binaries to /usr/bin +COPY --from=noir /usr/src/noir/noir-repo/target/release/nargo /usr/src/noir/noir-repo/target/release/nargo +COPY --from=transpiler /usr/src/avm-transpiler/target/release/avm-transpiler /usr/bin/avm-transpiler +COPY --from=barretenberg /usr/src/barretenberg/cpp/build/bin/bb /usr/bin/bb + WORKDIR /usr/src/boxes COPY . . -ENV AZTEC_NARGO=/usr/src/noir/noir-repo/target/release/nargo +ENV AZTEC_NARGO=/usr/aztec-nargo/compile_then_postprocess.sh ENV AZTEC_BUILDER=/usr/src/yarn-project/builder/aztec-builder-dest RUN yarn RUN npx -y playwright@1.42 install --with-deps diff --git a/boxes/Earthfile b/boxes/Earthfile index 3c349f8aa49..2629ac3e33c 100644 --- a/boxes/Earthfile +++ b/boxes/Earthfile @@ -31,10 +31,15 @@ build: COPY ../noir/+nargo/nargo /usr/src/noir/noir-repo/target/release/nargo COPY ../noir-projects/+build/aztec-nr /usr/src/noir-projects/aztec-nr COPY ../noir-projects/+build/noir-protocol-circuits/crates/types /usr/src/noir-projects/noir-protocol-circuits/crates/types + COPY ../avm-transpiler+build/avm-transpiler /usr/src/avm-transpiler/target/release/avm-transpiler + COPY ../barretenberg/cpp/+preset-release/bin/bb /usr/src/barretenberg/cpp/build/bin/bb WORKDIR /usr/src/boxes - ENV AZTEC_NARGO=/usr/src/noir/noir-repo/target/release/nargo + ENV NARGO=/usr/src/noir/noir-repo/target/release/nargo + ENV TRANSPILER=/usr/src/avm-transpiler/target/release/avm-transpiler + ENV BB=/usr/src/barretenberg/cpp/build/bin/bb + ENV AZTEC_NARGO=../aztec-nargo/compile_then_postprocess.sh ENV AZTEC_BUILDER=/usr/src/yarn-project/builder/aztec-builder-dest COPY . . RUN yarn build From eca91c8ef717e07c7bd3d40d07307076af3883e9 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Wed, 6 Nov 2024 12:01:01 +0000 Subject: [PATCH 09/17] fix paths --- aztec-nargo/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aztec-nargo/Dockerfile b/aztec-nargo/Dockerfile index 5d33560568e..3b7cbe5ee81 100644 --- a/aztec-nargo/Dockerfile +++ b/aztec-nargo/Dockerfile @@ -19,6 +19,6 @@ COPY --from=built-transpiler /usr/src/avm-transpiler/target/release/avm-transpil COPY --from=barretenberg /usr/src/barretenberg/cpp/build/bin/bb /usr/bin/bb # Copy in script that calls both binaries -COPY ./aztec-nargo/scripts/compile_then_postprocess.sh /usr/src/aztec-nargo/scripts/compile_then_postprocess.sh +COPY ./aztec-nargo/compile_then_postprocess.sh /usr/src/aztec-nargo/compile_then_postprocess.sh -ENTRYPOINT ["/usr/bin/tini", "--", "/usr/src/avm-transpiler/scripts/compile_then_postprocess.sh"] +ENTRYPOINT ["/usr/bin/tini", "--", "/usr/src/aztec-nargo/compile_then_postprocess.sh"] From a0d7d202a00d6f2e3420816d96afd66bc2a91097 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Wed, 6 Nov 2024 12:04:15 +0000 Subject: [PATCH 10/17] fix build manifest --- build_manifest.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/build_manifest.yml b/build_manifest.yml index e171cf14059..27af33a9b10 100644 --- a/build_manifest.yml +++ b/build_manifest.yml @@ -59,7 +59,9 @@ aztec-nargo: - ^aztec-nargo/ - ^avm-transpiler/ - ^noir/ + - ^barretenberg/ dependencies: + - barretenberg-x86_64-linux-clang - avm-transpiler - noir multiarch: buildx @@ -250,8 +252,10 @@ boxes: buildDir: boxes dependencies: - aztec - - noir - noir-projects + - noir + - avm-transpiler + - barretenberg-x86_64-linux-clang runDependencies: - aztec From 5bee07ee32483067a8accba2f95b466ccabe6e10 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Wed, 6 Nov 2024 12:15:27 +0000 Subject: [PATCH 11/17] remove unneeded rebuild patterns --- build_manifest.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/build_manifest.yml b/build_manifest.yml index 27af33a9b10..28982430bad 100644 --- a/build_manifest.yml +++ b/build_manifest.yml @@ -55,11 +55,6 @@ avm-transpiler: aztec-nargo: buildDir: . dockerfile: aztec-nargo/Dockerfile - rebuildPatterns: - - ^aztec-nargo/ - - ^avm-transpiler/ - - ^noir/ - - ^barretenberg/ dependencies: - barretenberg-x86_64-linux-clang - avm-transpiler From 7e026b41fd17bd4054a276427d1959211404bed9 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Wed, 6 Nov 2024 12:57:55 +0000 Subject: [PATCH 12/17] image fixes --- aztec-nargo/Dockerfile | 2 +- aztec-nargo/Earthfile | 2 +- boxes/Dockerfile | 2 +- boxes/Earthfile | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/aztec-nargo/Dockerfile b/aztec-nargo/Dockerfile index 3b7cbe5ee81..2b9a48681da 100644 --- a/aztec-nargo/Dockerfile +++ b/aztec-nargo/Dockerfile @@ -11,7 +11,7 @@ FROM --platform=linux/amd64 aztecprotocol/barretenberg-x86_64-linux-clang as bar FROM ubuntu:noble # Install Tini as nargo doesn't handle signals properly. # Install git as nargo needs it to clone. -RUN apt-get update && apt-get install -y git tini && rm -rf /var/lib/apt/lists/* && apt-get clean +RUN apt-get update && apt-get install -y git tini jq && rm -rf /var/lib/apt/lists/* && apt-get clean # Copy binaries to /usr/bin COPY --from=built-noir /usr/src/noir/noir-repo/target/release/nargo /usr/bin/nargo diff --git a/aztec-nargo/Earthfile b/aztec-nargo/Earthfile index 63d170e599e..d5dc430aabb 100644 --- a/aztec-nargo/Earthfile +++ b/aztec-nargo/Earthfile @@ -4,7 +4,7 @@ run: FROM ubuntu:noble # Install Tini as nargo doesn't handle signals properly. # Install git as nargo needs it to clone. - RUN apt-get update && apt-get install -y git tini && rm -rf /var/lib/apt/lists/* && apt-get clean + RUN apt-get update && apt-get install -y git tini jq && rm -rf /var/lib/apt/lists/* && apt-get clean # Copy binaries to /usr/bin COPY ../noir+nargo/nargo /usr/bin/nargo diff --git a/boxes/Dockerfile b/boxes/Dockerfile index 26707b8a08b..cd6a3ead2f9 100644 --- a/boxes/Dockerfile +++ b/boxes/Dockerfile @@ -7,7 +7,7 @@ FROM aztecprotocol/avm-transpiler AS transpiler # We need yarn. Start fresh container. FROM node:18.19.0 -RUN apt update && apt install netcat-openbsd +RUN apt update && apt install netcat-openbsd jq COPY --from=aztec /usr/src /usr/src COPY --from=noir-projects /usr/src/noir-projects/aztec-nr /usr/src/noir-projects/aztec-nr COPY --from=noir-projects /usr/src/noir-projects/noir-protocol-circuits/crates/types /usr/src/noir-projects/noir-protocol-circuits/crates/types diff --git a/boxes/Earthfile b/boxes/Earthfile index 2629ac3e33c..5e0f83dc011 100644 --- a/boxes/Earthfile +++ b/boxes/Earthfile @@ -39,7 +39,7 @@ build: ENV NARGO=/usr/src/noir/noir-repo/target/release/nargo ENV TRANSPILER=/usr/src/avm-transpiler/target/release/avm-transpiler ENV BB=/usr/src/barretenberg/cpp/build/bin/bb - ENV AZTEC_NARGO=../aztec-nargo/compile_then_postprocess.sh + ENV AZTEC_NARGO=/usr/src/aztec-nargo/compile_then_postprocess.sh ENV AZTEC_BUILDER=/usr/src/yarn-project/builder/aztec-builder-dest COPY . . RUN yarn build From b62de36021f861b5090eaea10705bee5036f39dc Mon Sep 17 00:00:00 2001 From: sirasistant Date: Wed, 6 Nov 2024 14:23:08 +0000 Subject: [PATCH 13/17] fix boxes build --- aztec-nargo/Earthfile | 1 + boxes/Earthfile | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/aztec-nargo/Earthfile b/aztec-nargo/Earthfile index d5dc430aabb..49a32e4a3b4 100644 --- a/aztec-nargo/Earthfile +++ b/aztec-nargo/Earthfile @@ -17,6 +17,7 @@ run: ENV PATH "/usr/bin:${PATH}" ENTRYPOINT ["/usr/bin/tini", "--", "/usr/bin/compile_then_postprocess.sh"] SAVE IMAGE aztecprotocol/aztec-nargo + SAVE ARTIFACT /usr/bin/compile_then_postprocess.sh /aztec-nargo export-aztec-nargo: FROM +run diff --git a/boxes/Earthfile b/boxes/Earthfile index 5e0f83dc011..d2febd89e91 100644 --- a/boxes/Earthfile +++ b/boxes/Earthfile @@ -33,13 +33,13 @@ build: COPY ../noir-projects/+build/noir-protocol-circuits/crates/types /usr/src/noir-projects/noir-protocol-circuits/crates/types COPY ../avm-transpiler+build/avm-transpiler /usr/src/avm-transpiler/target/release/avm-transpiler COPY ../barretenberg/cpp/+preset-release/bin/bb /usr/src/barretenberg/cpp/build/bin/bb - + COPY ../aztec-nargo+run/aztec-nargo /usr/src/aztec-nargo WORKDIR /usr/src/boxes ENV NARGO=/usr/src/noir/noir-repo/target/release/nargo ENV TRANSPILER=/usr/src/avm-transpiler/target/release/avm-transpiler ENV BB=/usr/src/barretenberg/cpp/build/bin/bb - ENV AZTEC_NARGO=/usr/src/aztec-nargo/compile_then_postprocess.sh + ENV AZTEC_NARGO=/usr/src/aztec-nargo ENV AZTEC_BUILDER=/usr/src/yarn-project/builder/aztec-builder-dest COPY . . RUN yarn build From 7e681921c1444652b25d884f9b1002f64081a776 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Wed, 6 Nov 2024 14:47:15 +0000 Subject: [PATCH 14/17] remove debug log --- .../private_call_data_validator/validate_contract_address.nr | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/validate_contract_address.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/validate_contract_address.nr index c9bbdaaece0..566cd989cbd 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/validate_contract_address.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/validate_contract_address.nr @@ -24,10 +24,7 @@ pub fn validate_contract_address( ); let protocol_contract_index = contract_address.to_field(); - debug_log_format( - "protocol_contract_index:{0} with computed_address: {1}", - [protocol_contract_index, computed_address.to_field()], - ); + let computed_protocol_contract_tree_root = if (MAX_PROTOCOL_CONTRACTS as Field).lt( protocol_contract_index, ) { From e5fb510a1964015ee2763b8afdf2944e13329a6a Mon Sep 17 00:00:00 2001 From: sirasistant Date: Wed, 6 Nov 2024 15:02:40 +0000 Subject: [PATCH 15/17] Added noir tests for vk validation --- .../validate_contract_address.nr | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_contract_address.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_contract_address.nr index 7928b8e889b..7f003f9df18 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_contract_address.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_contract_address.nr @@ -1,8 +1,7 @@ use crate::tests::private_call_data_validator_builder::PrivateCallDataValidatorBuilder; use dep::types::address::AztecAddress; -use std::embedded_curve_ops::{ - EmbeddedCurvePoint, EmbeddedCurveScalar, fixed_base_scalar_mul as derive_public_key, -}; +use std::embedded_curve_ops::{EmbeddedCurveScalar, fixed_base_scalar_mul as derive_public_key}; +use types::hash::verification_key_hash; impl PrivateCallDataValidatorBuilder { pub fn new_with_regular_contract() -> Self { @@ -103,3 +102,25 @@ fn validate_contract_address_protocol_contract_wrong_computed_address_fails() { builder.validate(); } + +#[test(should_fail_with = "Invalid VK hash")] +fn validate_contract_address_wrong_vk_hash_fails() { + let mut builder = PrivateCallDataValidatorBuilder::new_with_regular_contract(); + + // Set the contract_address to 0. + builder.private_call.client_ivc_vk.hash = 27; + + builder.validate(); +} + +#[test(should_fail_with = "computed contract address does not match expected one")] +fn validate_contract_address_wrong_vk_fails() { + let mut builder = PrivateCallDataValidatorBuilder::new_with_regular_contract(); + + // Set the contract_address to 0. + builder.private_call.client_ivc_vk.key[0] = 27; + builder.private_call.client_ivc_vk.hash = + verification_key_hash(builder.private_call.client_ivc_vk.key); + + builder.validate(); +} From 22bab9f7988cbaff52a553de332332597f567080 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Rodr=C3=ADguez?= Date: Wed, 6 Nov 2024 16:09:49 +0100 Subject: [PATCH 16/17] Apply suggestions from self code review --- .../validate_contract_address.nr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_contract_address.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_contract_address.nr index 7f003f9df18..dd7a5df1268 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_contract_address.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_contract_address.nr @@ -107,7 +107,7 @@ fn validate_contract_address_protocol_contract_wrong_computed_address_fails() { fn validate_contract_address_wrong_vk_hash_fails() { let mut builder = PrivateCallDataValidatorBuilder::new_with_regular_contract(); - // Set the contract_address to 0. + // Fake the vk hash so it doesn't match the preimage builder.private_call.client_ivc_vk.hash = 27; builder.validate(); @@ -117,7 +117,7 @@ fn validate_contract_address_wrong_vk_hash_fails() { fn validate_contract_address_wrong_vk_fails() { let mut builder = PrivateCallDataValidatorBuilder::new_with_regular_contract(); - // Set the contract_address to 0. + // Change the VK so the address doesn't match anymore builder.private_call.client_ivc_vk.key[0] = 27; builder.private_call.client_ivc_vk.hash = verification_key_hash(builder.private_call.client_ivc_vk.key); From b44fd96263ef35713fdd8d6e8f3c7155a0636ac6 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Thu, 7 Nov 2024 13:58:38 +0000 Subject: [PATCH 17/17] chore: update protocol contracts --- .../protocol-contracts/src/protocol_contract_data.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/yarn-project/protocol-contracts/src/protocol_contract_data.ts b/yarn-project/protocol-contracts/src/protocol_contract_data.ts index 6e164ad14ad..3e901637877 100644 --- a/yarn-project/protocol-contracts/src/protocol_contract_data.ts +++ b/yarn-project/protocol-contracts/src/protocol_contract_data.ts @@ -50,14 +50,14 @@ export const ProtocolContractAddress: Record }; export const ProtocolContractLeaf = { - AuthRegistry: Fr.fromString('0x264d5813e33795397db05b027f17c6d16f38289f7e8c7ce3ed27a8428c5ffc47'), - ContractInstanceDeployer: Fr.fromString('0x0a2d2bebf9ed365ecf2fe61b1da069c93d3c0cc252a3ebd29a7e04c83bc88f52'), - ContractClassRegisterer: Fr.fromString('0x1f6709a774da0656ece30dcb29f604f13ea39e5bebba158ad4ee3ca55d32ee7d'), + AuthRegistry: Fr.fromString('0x00d6c808f3c8a78645cce0ba37e17837da720d37a42d30814ce3aa80bb273e53'), + ContractInstanceDeployer: Fr.fromString('0x144e518ae79c22843ce5736fa723cbc072b93cb4508500f779037d5114c88310'), + ContractClassRegisterer: Fr.fromString('0x0503a6a49c9671be4b6d03be3db2bb36440631062755c776e9838e05a9afb1bd'), MultiCallEntrypoint: Fr.fromString('0x2be4d47f4c42bf7c74e75387229c8e0cc89d0d086449122a5265abdf5ea70129'), - FeeJuice: Fr.fromString('0x09230c2f71ca8177ccc6739319384b30f496d9d67586bafe50084f690b466fcc'), - Router: Fr.fromString('0x0713c42228cc09b0b0a0aaa010cb49d8ba1d9404c299e472693306127b17fac7'), + FeeJuice: Fr.fromString('0x1a47084d9b143a50a18292b2677588b3d575a473a0edc11466696f5e1f434fb1'), + Router: Fr.fromString('0x26d7b664d410b94a7b0543defc361669cae93382087d92f875a411910c695167'), }; export const protocolContractTreeRoot = Fr.fromString( - '0x18584311736bcb2bc73511541f10e7f7e80a07091b6da022bddb257f96c36f00', + '0x141e7aceb024c6b5aa82f9d5a9da7207bdb2953679674a5ee306290a193d674c', );