Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: public kernel in noir #3186

Merged
merged 38 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
3845a05
add start of public kernel private previous
dan-aztec Nov 1, 2023
b3b78fc
Merge remote-tracking branch 'origin/master' into dan/public-kernel-noir
kevaundray Nov 1, 2023
0ff674b
semver check
kevaundray Nov 1, 2023
ee3f910
more common functions
dan-aztec Nov 1, 2023
e4c0350
Update yarn-project/noir-protocol-circuits/src/crates/public-kernel-p…
dan-aztec Nov 1, 2023
8f120b1
dont duplicate from private-kernel-lib
dan-aztec Nov 1, 2023
134adc5
switch to private-kernel-lib for deps
dan-aztec Nov 2, 2023
bf7395f
Merge branch 'master' into dan/public-kernel-noir
sirasistant Nov 2, 2023
b8c2b84
fix: fix some import statements after reorg
sirasistant Nov 2, 2023
0e40e98
fix: fix some imports
sirasistant Nov 2, 2023
369f999
start compile fixes
dan-aztec Nov 2, 2023
c049a01
more bugs
dan-aztec Nov 2, 2023
2de99bc
more bad code fixes
dan-aztec Nov 2, 2023
0990b20
&mut
dan-aztec Nov 2, 2023
0a75d50
Merge branch 'master' into dan/public-kernel-noir
sirasistant Nov 3, 2023
47b8bf8
fix: fixed some compilation issues
sirasistant Nov 3, 2023
d6713cb
fix: fixed the last compile issues
sirasistant Nov 3, 2023
557446a
feat: added type conversions
sirasistant Nov 3, 2023
1c1c744
feat: wire up the public kernel private prev
sirasistant Nov 3, 2023
17f1c3e
fix: hash mismatch fix
sirasistant Nov 6, 2023
2b5f306
fix: run simulated public kernel
sirasistant Nov 6, 2023
045f2d1
fix: fix shape of public call stack
sirasistant Nov 6, 2023
007b27d
chore: added logs for the bench
sirasistant Nov 6, 2023
e4cb2b6
fix: actually simulate in parallel
sirasistant Nov 6, 2023
c510baa
Merge branch 'master' into dan/public-kernel-noir
sirasistant Nov 6, 2023
e3bd615
test: added interop testing for public call stack
sirasistant Nov 6, 2023
c28ae34
Merge branch 'master' into dan/public-kernel-noir
sirasistant Nov 6, 2023
c22e462
Merge remote-tracking branch 'origin/master' into dan/public-kernel-noir
LeilaWang Nov 7, 2023
c7f1572
Update type.
LeilaWang Nov 7, 2023
9775d08
Update yarn-project/noir-protocol-circuits/src/crates/public-kernel-l…
kevaundray Nov 7, 2023
025b5d0
merge conflicts
dan-aztec Nov 15, 2023
0459fc7
bad merge deletions
dan-aztec Nov 15, 2023
c2cc7fc
formatting
dan-aztec Nov 15, 2023
6782067
format hpp
dan-aztec Nov 16, 2023
32e0146
formatting
dan-aztec Nov 16, 2023
c27244b
comments
dan-aztec Nov 16, 2023
0aacd7d
correct return types in acvm execution
dan-aztec Nov 16, 2023
dd07f9a
Merge branch 'master' into dan/public-kernel-noir
dan-aztec Nov 16, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('benchmarks/publish_rollup', () => {
// Simulate and simultaneously send ROLLUP_SIZE txs. These should not yet be processed since sequencer is stopped.
context.logger(`Assembling rollup with ${txCount} txs`);
const sentTxs = await sendTxs(txCount, context, contract);

context.logger.info(`Sent ${txCount} txs`);
// Restart sequencer to process all txs together
sequencer.restart();

Expand Down
4 changes: 3 additions & 1 deletion yarn-project/end-to-end/src/benchmarks/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,13 @@ export async function sendTxs(
contract: BenchmarkingContract,
): Promise<SentTx[]> {
const calls = times(txCount, index => makeCall(index, context, contract));
calls.forEach(call => call.simulate({ skipPublicSimulation: true }));
await Promise.all(calls.map(call => call.simulate({ skipPublicSimulation: true })));

const sentTxs = calls.map(call => call.send());

// Awaiting txHash waits until the aztec node has received the tx into its p2p pool
await Promise.all(sentTxs.map(tx => tx.getTxHash()));

await sleep(100);

return sentTxs;
Expand Down
4 changes: 4 additions & 0 deletions yarn-project/noir-protocol-circuits/src/Nargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ members = [
"crates/private-kernel-inner-simulated",
"crates/private-kernel-ordering",
"crates/private-kernel-ordering-simulated",
"crates/public-kernel-private-previous",
"crates/public-kernel-private-previous-simulated",
"crates/public-kernel-public-previous",
"crates/public-kernel-public-previous-simulated",
"crates/rollup-lib",
"crates/rollup-merge",
"crates/rollup-base",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ exports[`Noir compatibility tests (interop_testing.nr) ComputeContractAddressFro

exports[`Noir compatibility tests (interop_testing.nr) Function leaf matches noir 1`] = `"0x1ad8ece7f40e63d011ae47c6ce6cdaf31d632a23f5cf35bbeaaf69c8302afdbc"`;

exports[`Noir compatibility tests (interop_testing.nr) Public call stack item matches noir 1`] = `"0x0a370c67b66e30901470c11a199764a914fc0fcfbc737ed03153079b2765813a"`;

exports[`Noir compatibility tests (interop_testing.nr) Public call stack item request matches noir 1`] = `"0x1d51d7758d792c9cd6edd8e8ec5f1f9fb1f974abc1af6bb4cf9f2328ef306c96"`;

exports[`Noir compatibility tests (interop_testing.nr) TxRequest Hash matches Noir 1`] = `"0x0b487ff2900ae1178e131bfe333fdbc351beef658f7c0d62db2801429b1aab75"`;

exports[`Private kernel Executes private kernel init circuit for a contract deployment 1`] = `
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "public_kernel_lib"
type = "lib"
authors = [""]
compiler_version = ">=0.18.0"

[dependencies]
aztec = { path = "../../../../aztec-nr/aztec" }
types = { path = "../types" }
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mod public_call_data;
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use dep::aztec::constants_gen::{MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL};
use dep::types::address::{Address, EthAddress};
use dep::types::utils::bounded_vec::BoundedVec;
use dep::types::abis::call_stack_item::PublicCallStackItem;
use dep::types::mocked::Proof;

struct PublicCallData {
call_stack_item: PublicCallStackItem,
public_call_stack_preimages: [PublicCallStackItem; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],

proof: Proof,
portal_contract_address: EthAddress,
bytecode_hash: Field,

}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use dep::types::address::Address;
use dep::aztec::{
constants_gen,
constants_gen::{GENERATOR_INDEX__PUBLIC_LEAF_INDEX},
hash::sha256_to_field,
};

pub fn compute_public_data_tree_index(contract_address: Address, storage_slot: Field) -> Field {
dep::std::hash::pedersen_hash_with_separator([
contract_address.to_field(),
storage_slot
], constants_gen::GENERATOR_INDEX__PUBLIC_LEAF_INDEX)
}

pub fn compute_public_data_tree_value(value: Field) -> Field {
// as it's a public value, it doesn't require hashing.
// leaving this function here in case we decide to change this.
value
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
mod abis;
// TODO: rename to be precise as to what its common to (the public kernel circuits).
mod common;

mod hash;

mod public_kernel_private_previous;
mod public_kernel_public_previous;

use public_kernel_private_previous::PublicKernelPrivatePreviousInputs;
use public_kernel_public_previous::PublicKernelPublicPreviousInputs;
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use crate::abis::public_call_data::PublicCallData;
use dep::types::abis::previous_kernel_data::PreviousKernelData;
use dep::types::abis::kernel_circuit_public_inputs::{KernelCircuitPublicInputs, KernelCircuitPublicInputsBuilder};
use crate::common;
use dep::std::unsafe;
// translated from cpp impl in
// aztec-packages/circuits/cpp/src/aztec3/circuits/kernel/public/native_public_kernel_circuit_private_previous_kernel.cpp

struct PublicKernelPrivatePreviousInputs {
previous_kernel: PreviousKernelData,
public_call: PublicCallData,
}

impl PublicKernelPrivatePreviousInputs {

fn validate_inputs(self) {
let private_call_stack = self.previous_kernel.public_inputs.end.private_call_stack;
for i in 0..private_call_stack.len() {
let private_call = private_call_stack[i];
assert(private_call == 0,
"Private call stack must be empty when executing in the public kernel (i.e. all private calls must have been completed)");
}

let previous_call_is_private = self.previous_kernel.public_inputs.is_private;
assert(previous_call_is_private == true,
"Previous kernel must be private when in this public kernel version");
}


fn public_kernel_private_previous(self) -> KernelCircuitPublicInputs {
// construct the circuit outputs
let mut public_inputs: KernelCircuitPublicInputsBuilder = unsafe::zeroed();

// initialise the end state with our provided previous kernel state
common::initialize_end_values(self.previous_kernel, &mut public_inputs);

// validate the inputs common to all invocation circumstances
common::validate_inputs(self.public_call);

// validate the inputs unique to having a previous private kernel
self.validate_inputs();

// to implement:
// validate the kernel execution common to all invocation circumstances
common::validate_kernel_execution(self.public_call);

// validate our public call hash
common::validate_this_public_call_hash(self.public_call,&mut public_inputs);

common::update_public_end_values(self.public_call,&mut public_inputs);

common::accumulate_unencrypted_logs(self.public_call, self.previous_kernel,&mut public_inputs);

public_inputs.finish()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use crate::abis::public_call_data::PublicCallData;
use dep::types::abis::previous_kernel_data::PreviousKernelData;
use dep::types::KernelCircuitPublicInputs;
use dep::types::abis::kernel_circuit_public_inputs::KernelCircuitPublicInputsBuilder;
use crate::common;
use dep::std::unsafe;
// translated from cpp impl in
// aztec-packages/circuits/cpp/src/aztec3/circuits/kernel/public/native_public_kernel_circuit_public_previous_kernel.cpp

// this is really the same as PublicKernelPrivatePreviousInputs...
kevaundray marked this conversation as resolved.
Show resolved Hide resolved
struct PublicKernelPublicPreviousInputs {
previous_kernel: PreviousKernelData,
public_call: PublicCallData,
}

impl PublicKernelPublicPreviousInputs {

// this is the only difference between the two PublicKernels' logic:
fn validate_inputs(self) {
let previous_call_is_private = self.previous_kernel.public_inputs.is_private;
assert(previous_call_is_private == false,
"Previous kernel must be private when in this public kernel version");
dan-aztec marked this conversation as resolved.
Show resolved Hide resolved
}


fn public_kernel_public_previous(self) -> KernelCircuitPublicInputs {
// construct the circuit outputs
let mut public_inputs: KernelCircuitPublicInputsBuilder = unsafe::zeroed();

// initialise the end state with our provided previous kernel state
common::initialize_end_values(self.previous_kernel, &mut public_inputs);

// validate the inputs common to all invocation circumstances
common::validate_inputs(self.public_call);

// validate the inputs unique to having a previous private kernel
dan-aztec marked this conversation as resolved.
Show resolved Hide resolved
self.validate_inputs();

// to implement:
dan-aztec marked this conversation as resolved.
Show resolved Hide resolved
// validate the kernel execution common to all invocation circumstances
common::validate_kernel_execution(self.public_call);

// validate our public call hash
common::validate_this_public_call_hash(self.public_call, &mut public_inputs);

common::update_public_end_values(self.public_call,&mut public_inputs);

common::accumulate_unencrypted_logs(self.public_call, self.previous_kernel,&mut public_inputs);

public_inputs.finish()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "public_kernel_private_previous_simulated"
type = "bin"
authors = [""]
compiler_version = ">=0.18.0"

[dependencies]
types = { path = "../types" }
public_kernel_lib = { path = "../public-kernel-lib" }
aztec = { path = "../../../../aztec-nr/aztec" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use dep::public_kernel_lib::{PublicKernelPrivatePreviousInputs};
use dep::types::{KernelCircuitPublicInputs};

unconstrained fn main(input: PublicKernelPrivatePreviousInputs) -> distinct pub KernelCircuitPublicInputs {
input.public_kernel_private_previous() // function naming?
dan-aztec marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "public_kernel_private_previous"
type = "bin"
authors = [""]
compiler_version = ">=0.18.0"

[dependencies]
types = { path = "../types" }
public_kernel_lib = { path = "../public-kernel-lib" }
aztec = { path = "../../../../aztec-nr/aztec" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use dep::public_kernel_lib::{PublicKernelPrivatePreviousInputs};
use dep::types::{KernelCircuitPublicInputs};

fn main(input: PublicKernelPrivatePreviousInputs) -> distinct pub KernelCircuitPublicInputs {
input.public_kernel_private_previous() // function naming?
dan-aztec marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "public_kernel_public_previous_simulated"
type = "bin"
authors = [""]
compiler_version = ">=0.18.0"

[dependencies]
types = { path = "../types" }
public_kernel_lib = { path = "../public-kernel-lib" }
aztec = { path = "../../../../aztec-nr/aztec" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use dep::public_kernel_lib::{PublicKernelPublicPreviousInputs};
use dep::types::{KernelCircuitPublicInputs};

unconstrained fn main(input: PublicKernelPublicPreviousInputs) -> distinct pub KernelCircuitPublicInputs {
input.public_kernel_public_previous()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "public_kernel_public_previous"
type = "bin"
authors = [""]
compiler_version = ">=0.18.0"

[dependencies]
types = { path = "../types" }
public_kernel_lib = { path = "../public-kernel-lib" }
aztec = { path = "../../../../aztec-nr/aztec" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use dep::public_kernel_lib::{PublicKernelPublicPreviousInputs};
use dep::types::{KernelCircuitPublicInputs};

fn main(input: PublicKernelPublicPreviousInputs) -> distinct pub KernelCircuitPublicInputs {
input.public_kernel_public_previous()
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,30 @@ struct PublicCallStackItem {

impl PublicCallStackItem {
fn hash(self) -> Field {
let item = if self.is_execution_request {
self.as_execution_request()
} else {
self
};

dep::std::hash::pedersen_hash_with_separator([
self.contract_address.to_field(),
self.function_data.hash(),
self.public_inputs.hash(),
item.contract_address.to_field(),
item.function_data.hash(),
item.public_inputs.hash(),
], GENERATOR_INDEX__CALL_STACK_ITEM)
}

fn as_execution_request(self) -> Self {
let public_inputs = self.public_inputs;
let mut request_public_inputs: PublicCircuitPublicInputs = dep::std::unsafe::zeroed();
request_public_inputs.call_context = public_inputs.call_context;
request_public_inputs.args_hash = public_inputs.args_hash;

PublicCallStackItem {
contract_address: self.contract_address,
function_data: self.function_data,
is_execution_request: true,
public_inputs: request_public_inputs,
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ impl PrivateCircuitPublicInputs{
fields.push(self.chain_id);
fields.push(self.version);

assert_eq(fields.len(), constants_gen::PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH, "Incorrect number of input fields when hashing PrivateCircuitPublicInputs");

dep::std::hash::pedersen_hash_with_separator(fields.storage, constants_gen::GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ impl PublicCircuitPublicInputs{
inputs.push_array(self.historical_block_data.to_array());
inputs.push(self.prover_address.to_field());

assert_eq(inputs.len(), constants_gen::PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH, "Incorrect number of input fields when hashing PublicCircuitPublicInputs");

dep::std::hash::pedersen_hash_with_separator(inputs.storage, constants_gen::GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,15 @@ impl PublicDataRead {
self.value,
], constants_gen::GENERATOR_INDEX__PUBLIC_DATA_READ)
}

pub fn empty() -> Self {
Self {
leaf_index : 0,
value : 0,
}
}

pub fn is_empty(self) -> bool {
(self.leaf_index == 0) & (self.value == 0)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@ struct PublicDataUpdateRequest {
}

impl PublicDataUpdateRequest {
pub fn empty() -> Self {
Self {
leaf_index : 0,
old_value : 0,
new_value : 0
}
}

pub fn is_empty(self) -> bool {
(self.leaf_index == 0) & (self.old_value == 0) & (self.new_value == 0)
}

fn hash(self) -> Field {
dep::std::hash::pedersen_hash_with_separator([
self.leaf_index,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ global NUM_FIELDS_PER_SHA256 : Field = 2;
// Returning a Field would be desirable because then this can be replaced with
// poseidon without changing the rest of the code
//
fn accumulate_sha256(input : [U128; 4]) -> [Field; NUM_FIELDS_PER_SHA256] {
pub fn accumulate_sha256(input : [U128; 4]) -> [Field; NUM_FIELDS_PER_SHA256] {
// This is a note about the cpp code, since it takes an array of Fields
// instead of a U128.
// 4 Field elements when converted to bytes will usually
Expand Down
Loading