Skip to content

Commit

Permalink
feat: public kernel in noir (#3186)
Browse files Browse the repository at this point in the history
starting rewrite based off of
#2740

literal cpp -> noir translation for first conversion
---------

Co-authored-by: kevaundray <kevtheappdev@gmail.com>
Co-authored-by: Álvaro Rodríguez <sirasistant@gmail.com>
Co-authored-by: Leila Wang <leizciw@gmail.com>
  • Loading branch information
4 people authored Nov 16, 2023
1 parent 8ae44dd commit 15a522b
Show file tree
Hide file tree
Showing 45 changed files with 1,342 additions and 21 deletions.
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: 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,55 @@
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();

// 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,49 @@
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;


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 public when in this public kernel version");
}


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 public kernel
self.validate_inputs();

// 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()
}
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()
}
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
Loading

0 comments on commit 15a522b

Please sign in to comment.