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 3 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
@@ -0,0 +1,8 @@
[package]
name = "public_kernel_lib"
type = "lib"
authors = [""]
compiler_version = ">=0.18.0"

[dependencies]
aztec = { path="../../../../aztec-nr/aztec" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use crate::block::Block;

struct HistoricalBlockData {
blocks_tree_root : Field,
block : Block,
// Private data
// This is marked in the cpp code as an enhancement
private_kernel_vk_tree_root : Field,
}

impl HistoricalBlockData {
fn assert_is_zero(self) {
self.block.assert_is_zero();
assert(self.private_kernel_vk_tree_root == 0);
}

fn to_array(self) -> [Field;7] {
// This comment was copied from the cpp codebase.
//
// TODO: Note private_kernel_vk_tree_root, is not included yet as
// it is not present in noir,
[
self.block.note_hash_tree_root,
self.block.nullifier_tree_root,
self.block.contract_tree_root,
self.block.l1_to_l2_data_tree_root,
self.blocks_tree_root,
self.block.public_data_tree_root,
self.block.global_variables_hash
]
}

fn note_hash_tree_root(self) -> Field {
self.block.note_hash_tree_root
}

fn contract_tree_root(self) -> Field {
self.block.contract_tree_root
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use crate::contrakt::storage_read::StorageRead;
use crate::contrakt::storage_update_request::StorageUpdateRequest;
use crate::address::Address;
use crate::abis::historical_block_data::HistoricalBlockData;
use dep::aztec::constants_gen;
use crate::hash::{NUM_FIELDS_PER_SHA256};
use dep::aztec::constants_gen::{
MAX_NEW_L2_TO_L1_MSGS_PER_CALL,
MAX_NEW_NULLIFIERS_PER_CALL,
MAX_NEW_COMMITMENTS_PER_CALL,
MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,
MAX_PUBLIC_DATA_READS_PER_CALL,
MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,
RETURN_VALUES_LENGTH,
};
use crate::abis::call_context::CallContext;
use crate::utils::bounded_vec::BoundedVec;

struct PublicCircuitPublicInputs{
call_context : CallContext,

args_hash : Field,
return_values : [Field; RETURN_VALUES_LENGTH],

contract_storage_update_requests : [StorageUpdateRequest;MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],
contract_storage_reads : [StorageRead; MAX_PUBLIC_DATA_READS_PER_CALL],

public_call_stack : [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],
new_commitments : [Field; MAX_NEW_COMMITMENTS_PER_CALL],
new_nullifiers : [Field; MAX_NEW_NULLIFIERS_PER_CALL],
new_l2_to_l1_msgs : [Field; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],

unencrypted_logs_hash : [Field; NUM_FIELDS_PER_SHA256],

// Here so that the gas cost of this request can be measured by circuits, without actually needing to feed in the
// variable-length data.
unencrypted_log_preimages_length : Field,

historical_block_data : HistoricalBlockData,

prover_address : Address,
}


impl PublicCircuitPublicInputs{
// TODO(https://github.com/AztecProtocol/aztec-packages/issues/3059) : Reuse aztec-nr
fn hash(self) -> Field {
let mut inputs: BoundedVec<Field, constants_gen::PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH> = BoundedVec::new(0);
inputs.push(self.call_context.hash());
inputs.push(self.args_hash);
inputs.push_array(self.return_values);
for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {
inputs.push(self.contract_storage_update_requests[i].hash());
}
for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {
inputs.push(self.contract_storage_reads[i].hash());
}
inputs.push_array(self.public_call_stack);
inputs.push_array(self.new_commitments);
inputs.push_array(self.new_nullifiers);
inputs.push_array(self.new_l2_to_l1_msgs);
inputs.push_array(self.unencrypted_logs_hash);
inputs.push(self.unencrypted_log_preimages_length);
inputs.push_array(self.historical_block_data.to_array());
inputs.push(self.prover_address.to_field());

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
@@ -0,0 +1,15 @@
use dep::aztec::constants_gen;

struct PublicDataRead {
leaf_index : Field,
value : Field,
}

impl PublicDataRead {
fn hash(self) -> Field {
dep::std::hash::pedersen_hash_with_separator([
self.leaf_index,
self.value,
], constants_gen::GENERATOR_INDEX__PUBLIC_DATA_READ)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use dep::aztec::constants_gen;

struct PublicDataUpdateRequest {
leaf_index : Field,
old_value : Field,
new_value : Field
}

impl PublicDataUpdateRequest {
fn hash(self) -> Field {
dep::std::hash::pedersen_hash_with_separator([
self.leaf_index,
self.old_value,
self.new_value
], constants_gen::GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use crate::address::{Address, EthAddress};
use crate::utils::bounded_vec:BoundedVec;
use dep::aztec::constants_gen::{MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL};
use crate::abis::call_stack_item::PublicCallStackItem;

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,

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use crate::utils;

// Aztec address
struct Address{
inner : Field
}

impl Address{

pub fn default() -> Self {
Self {
inner : 0
}
}

pub fn from_field(field : Field) -> Self {
Self {
inner : field
}
}

pub fn to_field(self) -> Field{
self.inner
}

pub fn assert_is_zero(self) {
assert(self.to_field() == 0);
}

pub fn conditional_assign(predicate: bool, lhs : Self, rhs : Self) -> Self{
let result = utils::conditional_assign(predicate, rhs.to_field(), lhs.to_field());
Self {
inner : result
}
}

pub fn eq(self, other : Self) -> bool {
self.to_field() == other.to_field()
}
}

struct EthAddress{
inner : Field
}

impl EthAddress{

pub fn default() -> Self {
Self {
inner : 0
}
}

pub fn from_field(field : Field) -> Self {
Self {
inner : field
}
}

pub fn to_field(self) -> Field{
self.inner
}

pub fn assert_is_zero(self) {
assert(self.to_field() == 0);
}

pub fn conditional_assign(predicate: bool, lhs : Self, rhs : Self) -> Self{
let result = utils::conditional_assign(predicate, rhs.to_field(), lhs.to_field());
Self {
inner : result
}
}

pub fn eq(self, other : Self) -> bool {
self.to_field() == other.to_field()
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use crate::abis::function_selector::FunctionSelector;
use crate::address::{EthAddress,Address};
use dep::aztec::constants_gen;

struct CallContext{
msg_sender : Address,
storage_contract_address : Address,
portal_contract_address : EthAddress,

function_selector : FunctionSelector,

is_delegate_call : bool,
is_static_call : bool,
is_contract_deployment : bool,
}

impl CallContext {
fn hash(self) -> Field {
dep::std::hash::pedersen_hash_with_separator([
self.msg_sender.to_field(),
self.storage_contract_address.to_field(),
self.portal_contract_address.to_field(),
self.function_selector.to_field(),
self.is_delegate_call as Field,
self.is_static_call as Field,
self.is_contract_deployment as Field,
], constants_gen::GENERATOR_INDEX__CALL_CONTEXT)
}

fn assert_is_zero(self) {
assert(self.msg_sender.to_field() == 0);
assert(self.storage_contract_address.to_field() == 0);
assert(self.portal_contract_address.to_field() == 0);
assert(self.function_selector.to_field() == 0);
assert(self.is_delegate_call == false);
assert(self.is_static_call == false);
assert(self.is_contract_deployment == false);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use crate::address::Address;
use crate::abis::function_data::FunctionData;
use dep::aztec::constants_gen::{MAX_READ_REQUESTS_PER_CALL};
use crate::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs;
use crate::abis::public_circuit_public_inputs::PublicCircuitPublicInputs;
use dep::aztec::constants_gen;

// TODO(Noir-bug): These should be type aliases

struct PublicCallStackItem {
inner : CallStackItem<PublicCircuitPublicInputs>
}

struct PrivateCallStackItem {
inner : CallStackItem<PrivateCircuitPublicInputs>
}

// Parametrize function over the public inputs.
// The public inputs can be from either a public or a private circuit
// TODO: We could monomorphize this struct and create a PrivateCallStackItem and
// TODO: a PublicCallStackItem
struct CallStackItem<AppCircuitPublicInputs> {
// Comment copied from the cpp codebase
//
// This is the _actual_ contract address relating to where this function's code resides in the
// contract tree. Regardless of whether this is a call or delegatecall, this
// `contract_address` _does not change_. Amongst other things, it's used as a lookup for
// getting the correct code from the tree. There is a separate `storage_contract_address`
// within a CallStackItem which varies depending on whether this is a call or delegatecall.
contract_address : Address,

public_inputs : AppCircuitPublicInputs,

// True if this call stack item represents a request to execute a function rather than a
// fulfilled execution. Used when enqueuing calls from private to public functions.
is_execution_request : bool,

function_data : FunctionData,
}

// TODO(Traits): Defining a hash trait bound
// Would allow the impl to be over `T : Hash`
// Where T is public inputs

// Noir(bug): If we can use a type alias instead of a new struct
// then we can remove the getter methods below for things like
// public_inputs and contract_address
impl PublicCallStackItem {
fn hash(self) -> Field {
dep::std::hash::pedersen_hash_with_separator([
self.inner.contract_address.to_field(),
self.inner.function_data.hash(),
self.inner.public_inputs.hash(),
], constants_gen::GENERATOR_INDEX__CALL_STACK_ITEM)
}

fn public_inputs(self) -> PublicCircuitPublicInputs {
self.inner.public_inputs
}

fn contract_address(self) -> Address{
self.inner.contract_address
}

fn function_data(self) -> FunctionData{
self.inner.function_data
}
}
impl PrivateCallStackItem {
fn hash(self) -> Field {
dep::std::hash::pedersen_hash_with_separator([
self.inner.contract_address.to_field(),
self.inner.function_data.hash(),
self.inner.public_inputs.hash(),
], constants_gen::GENERATOR_INDEX__CALL_STACK_ITEM)
}

fn public_inputs(self) -> PrivateCircuitPublicInputs {
self.inner.public_inputs
}

fn contract_address(self) -> Address{
self.inner.contract_address
}

fn function_data(self) -> FunctionData{
self.inner.function_data
}
}
Loading