Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 6 additions & 6 deletions l1-contracts/src/core/libraries/ConstantsGen.sol
Original file line number Diff line number Diff line change
Expand Up @@ -146,17 +146,17 @@ library Constants {
uint256 internal constant NULLIFIER_LENGTH = 3;
uint256 internal constant SCOPED_NULLIFIER_LENGTH = 4;
uint256 internal constant CALLER_CONTEXT_LENGTH = 3;
uint256 internal constant PRIVATE_CALL_REQUEST_LENGTH = 6;
uint256 internal constant SCOPED_PRIVATE_CALL_REQUEST_LENGTH = 7;
uint256 internal constant PRIVATE_CALL_REQUEST_LENGTH = 16;
uint256 internal constant SCOPED_PRIVATE_CALL_REQUEST_LENGTH = 17;
uint256 internal constant ROLLUP_VALIDATION_REQUESTS_LENGTH = 2;
uint256 internal constant STATE_REFERENCE_LENGTH = 8;
uint256 internal constant TX_CONTEXT_LENGTH = 9;
uint256 internal constant TX_REQUEST_LENGTH = 13;
uint256 internal constant TOTAL_FEES_LENGTH = 1;
uint256 internal constant HEADER_LENGTH = 23;
uint256 internal constant PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 393;
uint256 internal constant PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 433;
uint256 internal constant PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH = 482;
uint256 internal constant PRIVATE_CALL_STACK_ITEM_LENGTH = 396;
uint256 internal constant PRIVATE_CALL_STACK_ITEM_LENGTH = 436;
uint256 internal constant PUBLIC_CONTEXT_INPUTS_LENGTH = 41;
uint256 internal constant AGGREGATION_OBJECT_LENGTH = 16;
uint256 internal constant SCOPED_READ_REQUEST_LEN = 3;
Expand All @@ -166,8 +166,8 @@ library Constants {
uint256 internal constant COMBINED_ACCUMULATED_DATA_LENGTH = 333;
uint256 internal constant COMBINED_CONSTANT_DATA_LENGTH = 40;
uint256 internal constant CALL_REQUEST_LENGTH = 7;
uint256 internal constant PRIVATE_ACCUMULATED_DATA_LENGTH = 1152;
uint256 internal constant PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 2227;
uint256 internal constant PRIVATE_ACCUMULATED_DATA_LENGTH = 1232;
uint256 internal constant PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 2307;
uint256 internal constant PUBLIC_ACCUMULATED_DATA_LENGTH = 983;
uint256 internal constant PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 3258;
uint256 internal constant KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 383;
Expand Down
11 changes: 10 additions & 1 deletion noir-projects/aztec-nr/aztec/src/context/private_context.nr
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,16 @@ impl PrivateContext {
caller_context.storage_contract_address = self.inputs.call_context.storage_contract_address;
}
self.private_call_requests.push(
PrivateCallRequest { hash: item.hash(), caller_context, start_side_effect_counter, end_side_effect_counter }
PrivateCallRequest {

@sirasistant sirasistant Jul 4, 2024

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could it make sense for the call_private_function oracle to return directly the items necessary for the PrivateCallRequest struct and we validate that? If the oracle returns a call stack item that is largely unconstrained somebody could modify the above code to trust the oracle response when only part of it is constrained (the items that end up in PrivateCallRequest). Previously it was constrained because the whole of it was hashed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But we are also getting return values and such from it. Think we might look at it in a separate go?

target: item.contract_address,
call_context: item.public_inputs.call_context,
function_data: item.function_data,
args_hash: item.public_inputs.args_hash,
returns_hash: item.public_inputs.returns_hash,
caller_context,
start_side_effect_counter,
end_side_effect_counter
}
);

PackedReturns::new(item.public_inputs.returns_hash)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ impl PrivateCallDataValidator {
let caller_contract_address = scoped_call_request.contract_address;
let request = scoped_call_request.call_request;

assert_eq(
request.hash, call_stack_item.hash(), "calculated private_call_hash does not match provided private_call_hash at the top of the call stack"
assert(
request.matches_stack_item(call_stack_item), "calculated private_call_hash does not match provided private_call_hash at the top of the call stack"
);

let call_context = call_stack_item.public_inputs.call_context;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,7 @@ mod tests {
pub fn execute(&mut self) -> PrivateKernelCircuitPublicInputs {
let private_call = self.private_call.to_private_call_data();
// Update the previous_kernel's private_call_stack with the current call_stack_item.
let hash = private_call.call_stack_item.hash();
let is_delegate_call = private_call.call_stack_item.public_inputs.call_context.is_delegate_call;
self.previous_kernel.add_private_call_request(hash, is_delegate_call);
self.previous_kernel.add_private_call_from_call_stack_item(private_call.call_stack_item);
let previous_kernel = self.previous_kernel.to_private_kernel_data();

let kernel = PrivateKernelInnerCircuitPrivateInputs { previous_kernel, private_call };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ fn validate_against_call_request_mismatch_hash_fails() {

let mut request = builder.private_call.build_private_call_request();
// Tweak the hash to be a different value.
request.call_request.hash += 1;
request.call_request.args_hash += 1;

builder.validate_against_call_request(request);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl PrivateKernelCircuitOutputValidatorBuilder {
// Append one private call request for the current call.
let num_private_call_requests = self.previous_kernel.private_call_requests.len();
previous_kernel.end.private_call_stack[num_private_call_requests] = ScopedPrivateCallRequest::empty();
previous_kernel.end.private_call_stack[num_private_call_requests].call_request.hash = 98765432;
previous_kernel.end.private_call_stack[num_private_call_requests].call_request.args_hash = 98765432;

let previous_kernel_array_lengths = PrivateKernelCircuitPublicInputsArrayLengths::new(previous_kernel);
let private_call = self.private_call.to_private_call_data();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl PrivateKernelCircuitPublicInputsComposerBuilder {
let mut previous_kernel = self.previous_kernel.to_private_kernel_circuit_public_inputs();
let num_private_call_requests = self.previous_kernel.private_call_requests.len();
previous_kernel.end.private_call_stack[num_private_call_requests] = ScopedPrivateCallRequest::empty();
previous_kernel.end.private_call_stack[num_private_call_requests].call_request.hash = 98765432;
previous_kernel.end.private_call_stack[num_private_call_requests].call_request.args_hash = 98765432;

let private_call = self.private_call.to_private_call_data();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
use crate::{
abis::{caller_context::CallerContext, side_effect::{Ordered, RangeOrdered, Scoped}},
abis::{
private_call_stack_item::PrivateCallStackItem, call_context::CallContext,
function_data::FunctionData, caller_context::CallerContext,
side_effect::{Ordered, RangeOrdered, Scoped}
},
address::AztecAddress, constants::{PRIVATE_CALL_REQUEST_LENGTH, SCOPED_PRIVATE_CALL_REQUEST_LENGTH},
traits::{Empty, Serialize, Deserialize}, utils::reader::Reader
};

struct PrivateCallRequest {
hash: Field,
target: AztecAddress,
call_context: CallContext,
function_data: FunctionData,
args_hash: Field,
returns_hash: Field,
caller_context: CallerContext,
start_side_effect_counter: u32,
end_side_effect_counter: u32,
Expand All @@ -28,7 +36,11 @@ impl RangeOrdered for PrivateCallRequest {

impl Eq for PrivateCallRequest {
fn eq(self, other: PrivateCallRequest) -> bool {
(self.hash == other.hash)
(self.target == other.target)
& (self.call_context == other.call_context)
& (self.function_data == other.function_data)
& (self.args_hash == other.args_hash)
& (self.returns_hash == other.returns_hash)
& (self.caller_context == other.caller_context)
& (self.start_side_effect_counter == other.start_side_effect_counter)
& (self.end_side_effect_counter == other.end_side_effect_counter)
Expand All @@ -38,7 +50,11 @@ impl Eq for PrivateCallRequest {
impl Empty for PrivateCallRequest {
fn empty() -> Self {
PrivateCallRequest {
hash: 0,
target: AztecAddress::empty(),
call_context: CallContext::empty(),
function_data: FunctionData::empty(),
args_hash: 0,
returns_hash: 0,
caller_context: CallerContext::empty(),
start_side_effect_counter: 0,
end_side_effect_counter: 0,
Expand All @@ -50,7 +66,11 @@ impl Serialize<PRIVATE_CALL_REQUEST_LENGTH> for PrivateCallRequest {
fn serialize(self) -> [Field; PRIVATE_CALL_REQUEST_LENGTH] {
let mut fields: BoundedVec<Field, PRIVATE_CALL_REQUEST_LENGTH> = BoundedVec::new();

fields.push(self.hash);
fields.push(self.target.to_field());
fields.extend_from_array(self.call_context.serialize());
fields.extend_from_array(self.function_data.serialize());
fields.push(self.args_hash);
fields.push(self.returns_hash);
fields.extend_from_array(self.caller_context.serialize());
fields.push(self.start_side_effect_counter as Field);
fields.push(self.end_side_effect_counter as Field);
Expand All @@ -65,7 +85,11 @@ impl Deserialize<PRIVATE_CALL_REQUEST_LENGTH> for PrivateCallRequest {
fn deserialize(fields: [Field; PRIVATE_CALL_REQUEST_LENGTH]) -> PrivateCallRequest {
let mut reader = Reader::new(fields);
let item = PrivateCallRequest {
hash: reader.read(),
target: reader.read_struct(AztecAddress::deserialize),
call_context: reader.read_struct(CallContext::deserialize),
function_data: reader.read_struct(FunctionData::deserialize),
args_hash: reader.read(),
returns_hash: reader.read(),
caller_context: reader.read_struct(CallerContext::deserialize),
start_side_effect_counter: reader.read_u32(),
end_side_effect_counter: reader.read_u32(),
Expand All @@ -79,6 +103,18 @@ impl PrivateCallRequest {
pub fn scope(self, contract_address: AztecAddress) -> ScopedPrivateCallRequest {
ScopedPrivateCallRequest { call_request: self, contract_address }
}

pub fn matches_stack_item(self, stack_item: PrivateCallStackItem) -> bool {
(self.target == stack_item.contract_address)
& (self.call_context == stack_item.public_inputs.call_context)
& (self.function_data == stack_item.function_data)
& (self.args_hash == stack_item.public_inputs.args_hash)
& (self.returns_hash == stack_item.public_inputs.returns_hash)
& (self.start_side_effect_counter
== stack_item.public_inputs.start_side_effect_counter)
& (self.end_side_effect_counter
== stack_item.public_inputs.end_side_effect_counter)
}
}

struct ScopedPrivateCallRequest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,6 @@ fn empty_hash() {
let hash = item.hash();

// Value from private_call_stack_item.test.ts "computes empty item hash" test
let test_data_empty_hash = 0x157022d579f892f06461fb895cdf5550b24329e15e7a41df14f9dad582fa1bc5;
let test_data_empty_hash = 0x2dacef1b7e5d66445049df33ac3edad6689d86c83c1f11bb2bdaa4748309fd9f;
assert_eq(hash, test_data_empty_hash);
}
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,6 @@ fn empty_hash() {
let inputs = PrivateCircuitPublicInputs::empty();
let hash = inputs.hash();
// Value from private_circuit_public_inputs.test.ts "computes empty item hash" test
let test_data_empty_hash = 0x1eb5048b5bdcea5ba66519ecd1cbdb9e18fd957d52830b2bcb309f4ce9bcfbd3;
let test_data_empty_hash = 0x25748c9f85233dc2faf9eb73b1d2772d0fcb101075845a4f507baa837dc24f6b;
assert_eq(hash, test_data_empty_hash);
}
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ global SCOPED_NOTE_HASH_LENGTH = NOTE_HASH_LENGTH + 1;
global NULLIFIER_LENGTH = 3;
global SCOPED_NULLIFIER_LENGTH = NULLIFIER_LENGTH + 1;
global CALLER_CONTEXT_LENGTH = 2 * AZTEC_ADDRESS_LENGTH + 1;
global PRIVATE_CALL_REQUEST_LENGTH = 3 + CALLER_CONTEXT_LENGTH;
global PRIVATE_CALL_REQUEST_LENGTH = AZTEC_ADDRESS_LENGTH + CALL_CONTEXT_LENGTH + FUNCTION_DATA_LENGTH + 4 + CALLER_CONTEXT_LENGTH;
global SCOPED_PRIVATE_CALL_REQUEST_LENGTH = PRIVATE_CALL_REQUEST_LENGTH + AZTEC_ADDRESS_LENGTH;
global ROLLUP_VALIDATION_REQUESTS_LENGTH = MAX_BLOCK_NUMBER_LENGTH;
global STATE_REFERENCE_LENGTH: u32 = APPEND_ONLY_TREE_SNAPSHOT_LENGTH + PARTIAL_STATE_REFERENCE_LENGTH;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ impl FixtureBuilder {
}

pub fn build_private_call_request(self) -> ScopedPrivateCallRequest {
let hash = self.to_private_call_stack_item().hash();
let item = self.to_private_call_stack_item();
let is_delegate_call = self.is_delegate_call;
let mut caller_context = CallerContext::empty();
caller_context.is_static_call = self.is_static_call;
Expand All @@ -226,7 +226,11 @@ impl FixtureBuilder {
caller_context.storage_contract_address = self.storage_contract_address;
};
PrivateCallRequest {
hash,
target: item.contract_address,
call_context: item.public_inputs.call_context,
function_data: item.function_data,
args_hash: item.public_inputs.args_hash,
returns_hash: item.public_inputs.returns_hash,
caller_context,
start_side_effect_counter: self.counter_start,
end_side_effect_counter: self.counter
Expand Down Expand Up @@ -784,7 +788,33 @@ impl FixtureBuilder {
self.unencrypted_log_preimages_length = preimages_length;
}

pub fn add_private_call_request(&mut self, hash: Field, is_delegate_call: bool) {
pub fn add_private_call_from_call_stack_item(&mut self, item: PrivateCallStackItem) {
let mut caller_context = CallerContext::empty();
let is_delegate_call = item.public_inputs.call_context.is_delegate_call;
caller_context.is_static_call = self.is_static_call;
if is_delegate_call {
caller_context.msg_sender = self.msg_sender;
caller_context.storage_contract_address = self.storage_contract_address;
}
let start_counter = item.public_inputs.start_side_effect_counter;
let end_counter = item.public_inputs.end_side_effect_counter;
self.counter = end_counter + 1;

self.private_call_requests.push(
PrivateCallRequest {
target: item.contract_address,
call_context: item.public_inputs.call_context,
function_data: item.function_data,
args_hash: item.public_inputs.args_hash,
returns_hash: item.public_inputs.returns_hash,
caller_context,
start_side_effect_counter: start_counter,
end_side_effect_counter: end_counter
}.scope(self.contract_address)
);
}

pub fn add_private_call_request(&mut self, args_hash: Field, is_delegate_call: bool) {
let mut caller_context = CallerContext::empty();
caller_context.is_static_call = self.is_static_call;
if is_delegate_call {
Expand All @@ -794,8 +824,23 @@ impl FixtureBuilder {
let start_counter = self.next_counter();
let end_counter = start_counter + 10;
self.counter = end_counter + 1;

let target = AztecAddress::empty();
let call_context = CallContext::empty();
let function_data = FunctionData::empty();
let returns_hash = 0;

self.private_call_requests.push(
PrivateCallRequest { hash, caller_context, start_side_effect_counter: start_counter, end_side_effect_counter: end_counter }.scope(self.contract_address)
PrivateCallRequest {
target,
call_context,
function_data,
args_hash,
returns_hash,
caller_context,
start_side_effect_counter: start_counter,
end_side_effect_counter: end_counter
}.scope(self.contract_address)
);
}

Expand Down
12 changes: 6 additions & 6 deletions yarn-project/circuits.js/src/constants.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,17 +130,17 @@ export const SCOPED_NOTE_HASH_LENGTH = 4;
export const NULLIFIER_LENGTH = 3;
export const SCOPED_NULLIFIER_LENGTH = 4;
export const CALLER_CONTEXT_LENGTH = 3;
export const PRIVATE_CALL_REQUEST_LENGTH = 6;
export const SCOPED_PRIVATE_CALL_REQUEST_LENGTH = 7;
export const PRIVATE_CALL_REQUEST_LENGTH = 16;
export const SCOPED_PRIVATE_CALL_REQUEST_LENGTH = 17;
export const ROLLUP_VALIDATION_REQUESTS_LENGTH = 2;
export const STATE_REFERENCE_LENGTH = 8;
export const TX_CONTEXT_LENGTH = 9;
export const TX_REQUEST_LENGTH = 13;
export const TOTAL_FEES_LENGTH = 1;
export const HEADER_LENGTH = 23;
export const PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 393;
export const PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 433;
export const PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH = 482;
export const PRIVATE_CALL_STACK_ITEM_LENGTH = 396;
export const PRIVATE_CALL_STACK_ITEM_LENGTH = 436;
export const PUBLIC_CONTEXT_INPUTS_LENGTH = 41;
export const AGGREGATION_OBJECT_LENGTH = 16;
export const SCOPED_READ_REQUEST_LEN = 3;
Expand All @@ -150,8 +150,8 @@ export const PUBLIC_DATA_UPDATE_REQUEST_LENGTH = 3;
export const COMBINED_ACCUMULATED_DATA_LENGTH = 333;
export const COMBINED_CONSTANT_DATA_LENGTH = 40;
export const CALL_REQUEST_LENGTH = 7;
export const PRIVATE_ACCUMULATED_DATA_LENGTH = 1152;
export const PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 2227;
export const PRIVATE_ACCUMULATED_DATA_LENGTH = 1232;
export const PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 2307;
export const PUBLIC_ACCUMULATED_DATA_LENGTH = 983;
export const PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 3258;
export const KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 383;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`PrivateCallStackItem computes empty item hash 1`] = `Fr<0x157022d579f892f06461fb895cdf5550b24329e15e7a41df14f9dad582fa1bc5>`;
exports[`PrivateCallStackItem computes empty item hash 1`] = `Fr<0x2dacef1b7e5d66445049df33ac3edad6689d86c83c1f11bb2bdaa4748309fd9f>`;

exports[`PrivateCallStackItem computes hash 1`] = `Fr<0x029b1573da033e679c68a55e05987602c5e73419c4fdfdd6104e178a9a360834>`;
exports[`PrivateCallStackItem computes hash 1`] = `Fr<0x17171557d06226fae88f7e2b57e23acd8dd767160e5149965ca0f4bebbdedb06>`;
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`PrivateCircuitPublicInputs computes empty inputs hash 1`] = `Fr<0x1eb5048b5bdcea5ba66519ecd1cbdb9e18fd957d52830b2bcb309f4ce9bcfbd3>`;
exports[`PrivateCircuitPublicInputs computes empty inputs hash 1`] = `Fr<0x25748c9f85233dc2faf9eb73b1d2772d0fcb101075845a4f507baa837dc24f6b>`;

exports[`PrivateCircuitPublicInputs hash matches snapshot 1`] = `Fr<0x0b02f49b7283dacf553c5cfc0615c979fdd1cd146a1d4e71c78610345a711d22>`;
exports[`PrivateCircuitPublicInputs hash matches snapshot 1`] = `Fr<0x0d8c2da0c15b53e26d2f612cec5d0ac71ce21fb6e1b00caf3e8aa5a8bb02ad65>`;
7 changes: 6 additions & 1 deletion yarn-project/circuits.js/src/structs/call_context.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { FunctionSelector } from '@aztec/foundation/abi';
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { pedersenHash } from '@aztec/foundation/crypto';
import { Fr } from '@aztec/foundation/fields';
import { BufferReader, FieldReader, serializeToBuffer, serializeToFields } from '@aztec/foundation/serialize';
import { type FieldsOf } from '@aztec/foundation/types';

import { CALL_CONTEXT_LENGTH } from '../constants.gen.js';
import { CALL_CONTEXT_LENGTH, GeneratorIndex } from '../constants.gen.js';

/**
* Call context.
Expand Down Expand Up @@ -125,4 +126,8 @@ export class CallContext {
callContext.sideEffectCounter === this.sideEffectCounter
);
}

hash(): Fr {
return pedersenHash(this.toFields(), GeneratorIndex.CALL_CONTEXT);
}
}
9 changes: 9 additions & 0 deletions yarn-project/circuits.js/src/structs/function_data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ export class FunctionData {
return this.selector.isEmpty();
}

/**
* Returns whether this instance is equal to another.
* @param other
* @returns
*/
equals(other: FunctionData): boolean {
return this.selector.equals(other.selector) && this.isPrivate === other.isPrivate;
}

/**
* Returns a new instance of FunctionData with zero function selector.
* @param args - Arguments to pass to the constructor.
Expand Down
Loading