Skip to content

Commit ce0eee0

Browse files
feat: Add verify proof calls to private kernels (#10533)
Co-authored-by: ledwards2225 <l.edwards.d@gmail.com>
1 parent 5d4cdc1 commit ce0eee0

21 files changed

+80
-63
lines changed

aztec-nargo/compile_then_postprocess.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ for artifact in $artifacts_to_process; do
4141

4242
echo "Generating verification key for function $fn_name"
4343
# BB outputs the verification key to stdout as raw bytes, however, we need to base64 encode it before storing it in the artifact
44-
verification_key=$($BB write_vk_mega_honk -h -b ${fn_artifact_path} -o - | base64)
44+
verification_key=$($BB write_vk_for_ivc -h -b ${fn_artifact_path} -o - | base64)
4545
rm $fn_artifact_path
4646
jq ".functions[$fn_index].verification_key = \"$verification_key\"" $artifact > $artifact.tmp
4747
mv $artifact.tmp $artifact

barretenberg/cpp/src/barretenberg/constants.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ static constexpr uint32_t CONST_PG_LOG_N = 20;
1313

1414
static constexpr uint32_t CONST_ECCVM_LOG_N = 15;
1515

16-
static constexpr uint32_t MAX_LOOKUP_TABLES_SIZE = 70000;
16+
static constexpr uint32_t MAX_LOOKUP_TABLES_SIZE = 75000;
1717

1818
static constexpr uint32_t MAX_DATABUS_SIZE = 10000;
1919
} // namespace bb

barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/composer_lib.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ void construct_lookup_table_polynomials(const RefArray<typename Flavor::Polynomi
2323
// ignored, as used for regular constraints and padding to the next power of 2.
2424
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1033): construct tables and counts at top of trace
2525
const size_t tables_size = circuit.get_tables_size();
26+
ASSERT(tables_size <= MAX_LOOKUP_TABLES_SIZE); // if false, may need to increase constant
2627
ASSERT(dyadic_circuit_size > tables_size + additional_offset);
2728
size_t offset = dyadic_circuit_size - tables_size - additional_offset;
2829

barretenberg/cpp/src/barretenberg/polynomials/shared_shifted_virtual_zeroes_array.hpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,10 @@ template <typename T> struct SharedShiftedVirtualZeroesArray {
8585

8686
T& operator[](size_t index)
8787
{
88-
ASSERT(index >= start_ && index < end_);
88+
if (index < start_ || index >= end_) {
89+
vinfo("index = ", index, ", start_ = ", start_, ", end_ = ", end_);
90+
ASSERT(false);
91+
}
8992
return data()[index - start_];
9093
}
9194
// get() is more useful, but for completeness with the non-const operator[]

noir-projects/Earthfile

+1-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ source:
1919
COPY package.json yarn.lock .
2020
RUN yarn
2121

22-
COPY mega_honk_circuits.json .
23-
COPY ivc_integration_circuits.json .
22+
COPY client_ivc_circuits.json .
2423
COPY --dir aztec-nr noir-contracts noir-protocol-circuits mock-protocol-circuits scripts .
2524

2625
build-contracts:
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[
2+
"private_kernel_init",
3+
"private_kernel_inner",
4+
"private_kernel_reset.*",
5+
"private_kernel_tail.*",
6+
"app_creator",
7+
"app_reader"
8+
]

noir-projects/gates_report.sh

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ set -eu
55
# The script needs some slight updating as `nargo info` expects a complete JSON object, while this script expects a single object field
66
# representing a list of circuit reports for a program.
77
# 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
8-
MEGA_HONK_CIRCUIT_PATTERNS=$(jq -r '.[]' mega_honk_circuits.json)
8+
MEGA_HONK_CIRCUIT_PATTERNS=$(jq -r '.[]' client_ivc_circuits.json)
99

1010
cd noir-protocol-circuits
1111
PROTOCOL_CIRCUITS_DIR=$PWD
@@ -31,13 +31,13 @@ for pathname in "$PROTOCOL_CIRCUITS_DIR/target"/*.json; do
3131
fi
3232
done
3333

34-
# If it's mega honk, we need to use the gates_mega_honk command
34+
# If it's mega honk, we need to use the gates_mega_honk command
3535
if [ "$IS_MEGA_HONK_CIRCUIT" = "true" ]; then
3636
GATES_INFO=$($BB_BIN gates_mega_honk -h -b "$pathname")
3737
else
3838
GATES_INFO=$($BB_BIN gates -h -b "$pathname")
3939
fi
40-
40+
4141
MAIN_FUNCTION_INFO=$(echo $GATES_INFO | jq -r '.functions[0] | .name = "main"')
4242
echo "{\"package_name\": \"$ARTIFACT_NAME\", \"functions\": [$MAIN_FUNCTION_INFO]" >> gates_report.json
4343

noir-projects/ivc_integration_circuits.json

-8
This file was deleted.

noir-projects/mega_honk_circuits.json

-6
This file was deleted.

noir-projects/noir-contracts/scripts/postprocess_contract.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ async function generateVkForFunction(functionArtifact, outputFolder) {
3838
);
3939

4040
try {
41-
const writeVkCommand = `${BB_BIN_PATH} write_vk_mega_honk -h -b "${functionArtifactPath}" -o "${outputVkPath}" `;
41+
const writeVkCommand = `${BB_BIN_PATH} write_vk_for_ivc -h -b "${functionArtifactPath}" -o "${outputVkPath}" `;
4242

4343
console.log("WRITE VK CMD: ", writeVkCommand);
4444

noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr

+4
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ impl PrivateKernelInitCircuitPrivateInputs {
4949
}
5050

5151
pub fn execute(self) -> PrivateKernelCircuitPublicInputs {
52+
if !std::runtime::is_unconstrained() {
53+
self.private_call.verify(true);
54+
}
55+
5256
// Generate output.
5357
let output = unsafe { self.generate_output() };
5458

noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr

+5
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ impl PrivateKernelInnerCircuitPrivateInputs {
4747
}
4848

4949
pub fn execute(self) -> PrivateKernelCircuitPublicInputs {
50+
if !std::runtime::is_unconstrained() {
51+
self.previous_kernel.verify();
52+
self.private_call.verify(false);
53+
}
54+
5055
// Generate output.
5156
let output = unsafe { self.generate_output() };
5257

noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr

+4
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ impl<let NH_RR_PENDING: u32, let NH_RR_SETTLED: u32, let NLL_RR_PENDING: u32, le
6565
nullifier_siloing_amount: u32,
6666
private_log_siloing_amount: u32,
6767
) -> PrivateKernelCircuitPublicInputs {
68+
if !std::runtime::is_unconstrained() {
69+
self.previous_kernel.verify();
70+
}
71+
6872
let previous_public_inputs = self.previous_kernel.public_inputs;
6973
let validation_request_processor = PrivateValidationRequestProcessor {
7074
validation_requests: previous_public_inputs.validation_requests,

noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr

+3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ impl PrivateKernelTailCircuitPrivateInputs {
3333
}
3434

3535
pub fn execute(self) -> KernelCircuitPublicInputs {
36+
if !std::runtime::is_unconstrained() {
37+
self.previous_kernel.verify();
38+
}
3639
// Generate output.
3740
let output = unsafe { self.generate_output() };
3841

noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr

+3
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ impl PrivateKernelTailToPublicCircuitPrivateInputs {
3434
}
3535

3636
pub fn execute(self) -> PrivateToPublicKernelCircuitPublicInputs {
37+
if !std::runtime::is_unconstrained() {
38+
self.previous_kernel.verify();
39+
}
3740
// Generate output.
3841
let output = unsafe { self.generate_output() };
3942

noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel/private_call_data.nr

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use crate::{
22
abis::private_circuit_public_inputs::PrivateCircuitPublicInputs,
33
address::SaltedInitializationHash,
4-
constants::{FUNCTION_TREE_HEIGHT, PROTOCOL_CONTRACT_TREE_HEIGHT},
4+
constants::{
5+
FUNCTION_TREE_HEIGHT, PROOF_TYPE_OINK, PROOF_TYPE_PG, PROTOCOL_CONTRACT_TREE_HEIGHT,
6+
},
57
merkle_tree::membership::MembershipWitness,
68
proof::verification_key::ClientIVCVerificationKey,
79
public_keys::PublicKeys,
@@ -22,6 +24,18 @@ pub struct PrivateCallData {
2224
pub acir_hash: Field,
2325
}
2426

27+
impl PrivateCallData {
28+
fn verify(self, is_first_app: bool) {
29+
let proof_type = if is_first_app {
30+
PROOF_TYPE_OINK
31+
} else {
32+
PROOF_TYPE_PG
33+
};
34+
// Client IVC public inputs are linked in the backend via the databus
35+
std::verify_proof_with_type(self.vk.key, [], [], 0, proof_type);
36+
}
37+
}
38+
2539
pub struct PrivateCallDataWithoutPublicInputs {
2640
pub vk: ClientIVCVerificationKey,
2741

noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel_data.nr

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use crate::{
22
abis::kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs,
3-
constants::{PRIVATE_KERNEL_RESET_INDEX, VK_TREE_HEIGHT},
3+
constants::{PRIVATE_KERNEL_RESET_INDEX, PROOF_TYPE_PG, VK_TREE_HEIGHT},
44
merkle_tree::membership::assert_check_membership,
5-
proof::verification_key::ClientIVCVerificationKey,
5+
proof::{traits::Verifiable, verification_key::ClientIVCVerificationKey},
66
utils::arrays::find_index_hint,
77
};
88

@@ -38,6 +38,13 @@ impl PrivateKernelData {
3838
}
3939
}
4040

41+
impl Verifiable for PrivateKernelData {
42+
fn verify(self) {
43+
// Client IVC public inputs are linked in the backend via the databus
44+
std::verify_proof_with_type(self.vk.key, [], [], 0, PROOF_TYPE_PG);
45+
}
46+
}
47+
4148
pub struct PrivateKernelDataWithoutPublicInputs {
4249
vk: ClientIVCVerificationKey,
4350
vk_index: u32,

noir-projects/noir-protocol-circuits/scripts/flamegraph.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ fi
123123
DEST="$SCRIPT_DIR/../dest"
124124
mkdir -p $DEST
125125

126-
MEGA_HONK_CIRCUIT_PATTERNS=$(jq -r '.[]' "$SCRIPT_DIR/../../mega_honk_circuits.json")
126+
MEGA_HONK_CIRCUIT_PATTERNS=$(jq -r '.[]' "$SCRIPT_DIR/../../client_ivc_circuits.json")
127127

128128
# Process each CIRCUIT_NAME.
129129
for CIRCUIT_NAME in "${CIRCUIT_NAMES[@]}"; do

noir-projects/scripts/generate_vk_json.js

+13-34
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ const fs = require("fs/promises");
33
const child_process = require("child_process");
44
const crypto = require("crypto");
55

6-
const megaHonkPatterns = require("../mega_honk_circuits.json");
7-
const ivcIntegrationPatterns = require("../ivc_integration_circuits.json");
6+
const clientIvcPatterns = require("../client_ivc_circuits.json");
87
const {
98
readVKFromS3,
109
writeVKToS3,
@@ -33,19 +32,13 @@ async function getBytecodeHash(artifactPath) {
3332
return crypto.createHash("md5").update(bytecode).digest("hex");
3433
}
3534

36-
async function getArtifactHash(
37-
artifactPath,
38-
isMegaHonk,
39-
isIvcIntegration,
40-
isRecursive
41-
) {
35+
async function getArtifactHash(artifactPath, isClientIvc, isRecursive) {
4236
const bytecodeHash = await getBytecodeHash(artifactPath);
4337
const barretenbergHash = await getBarretenbergHash();
4438
return generateArtifactHash(
4539
barretenbergHash,
4640
bytecodeHash,
47-
isMegaHonk,
48-
isIvcIntegration,
41+
isClientIvc,
4942
isRecursive
5043
);
5144
}
@@ -68,26 +61,19 @@ async function hasArtifactHashChanged(artifactHash, vkDataPath) {
6861
return true;
6962
}
7063

71-
function isMegaHonkCircuit(artifactName) {
72-
return megaHonkPatterns.some((pattern) =>
73-
artifactName.match(new RegExp(pattern))
74-
);
75-
}
76-
function isIvcIntegrationCircuit(artifactName) {
77-
return ivcIntegrationPatterns.some((pattern) =>
64+
function isClientIvcCircuit(artifactName) {
65+
return clientIvcPatterns.some((pattern) =>
7866
artifactName.match(new RegExp(pattern))
7967
);
8068
}
8169

8270
async function processArtifact(artifactPath, artifactName, outputFolder) {
83-
const isMegaHonk = isMegaHonkCircuit(artifactName);
84-
const isIvcIntegration = isIvcIntegrationCircuit(artifactName);
71+
const isClientIvc = isClientIvcCircuit(artifactName);
8572
const isRecursive = true;
8673

8774
const artifactHash = await getArtifactHash(
8875
artifactPath,
89-
isMegaHonk,
90-
isIvcIntegration,
76+
isClientIvc,
9177
isRecursive
9278
);
9379

@@ -106,8 +92,7 @@ async function processArtifact(artifactPath, artifactName, outputFolder) {
10692
outputFolder,
10793
artifactPath,
10894
artifactHash,
109-
isMegaHonk,
110-
isIvcIntegration,
95+
isClientIvc,
11196
isRecursive
11297
);
11398
await writeVKToS3(artifactName, artifactHash, JSON.stringify(vkData));
@@ -123,14 +108,11 @@ async function generateVKData(
123108
outputFolder,
124109
artifactPath,
125110
artifactHash,
126-
isMegaHonk,
127-
isIvcIntegration,
111+
isClientIvc,
128112
isRecursive
129113
) {
130-
if (isMegaHonk) {
131-
console.log("Generating new mega honk vk for", artifactName);
132-
} else if (isIvcIntegration) {
133-
console.log("Generating new IVC vk for", artifactName);
114+
if (isClientIvc) {
115+
console.log("Generating new client ivc vk for", artifactName);
134116
} else {
135117
console.log("Generating new vk for", artifactName);
136118
}
@@ -142,8 +124,7 @@ async function generateVKData(
142124
const jsonVkPath = vkJsonFileNameForArtifactName(outputFolder, artifactName);
143125

144126
function getVkCommand() {
145-
if (isMegaHonk) return "write_vk_mega_honk";
146-
if (isIvcIntegration) return "write_vk_for_ivc";
127+
if (isClientIvc) return "write_vk_for_ivc";
147128
return "write_vk_ultra_honk";
148129
}
149130

@@ -154,9 +135,7 @@ async function generateVKData(
154135
console.log("WRITE VK CMD: ", writeVkCommand);
155136

156137
const vkAsFieldsCommand = `${BB_BIN_PATH} ${
157-
isMegaHonk || isIvcIntegration
158-
? "vk_as_fields_mega_honk"
159-
: "vk_as_fields_ultra_honk"
138+
isClientIvc ? "vk_as_fields_mega_honk" : "vk_as_fields_ultra_honk"
160139
} -k "${binaryVkPath}" -o "${jsonVkPath}"`;
161140

162141
await new Promise((resolve, reject) => {

noir-projects/scripts/verification_keys.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,11 @@ function generateS3Client() {
6767
function generateArtifactHash(
6868
barretenbergHash,
6969
bytecodeHash,
70-
isMegaHonk,
70+
isClientIvc,
7171
isRecursive
7272
) {
7373
return `${barretenbergHash}-${bytecodeHash}-${
74-
isMegaHonk ? "mega-honk" : "ultra-honk"
74+
isClientIvc ? "client-ivc" : "ultra-honk"
7575
}-${isRecursive}`;
7676
}
7777

yarn-project/bb-prover/src/prover/bb_private_kernel_prover.ts

+1
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ export class BBNativePrivateKernelProver implements PrivateKernelProver {
105105
path.join(directory, 'acir.msgpack'),
106106
path.join(directory, 'witnesses.msgpack'),
107107
this.log.info,
108+
true,
108109
);
109110

110111
if (provingResult.status === BB_RESULT.FAILURE) {

0 commit comments

Comments
 (0)