Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
benesjan committed Nov 28, 2023
1 parent 6c00d69 commit de4fe0a
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 6 deletions.
9 changes: 9 additions & 0 deletions yarn-project/acir-simulator/src/acvm/oracle/oracle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ export class Oracle {
return witness.map(toACVMField);
}

async getSiblingPath([blockNumber]: ACVMField[], [treeId]: ACVMField[], [index]: ACVMField[]): Promise<ACVMField[]> {
const parsedBlockNumber = frToNumber(fromACVMField(blockNumber));
const parsedTreeId = frToNumber(fromACVMField(treeId));
const parsedIndex = fromACVMField(index);

const path = await this.typedOracle.getSiblingPath(parsedBlockNumber, parsedTreeId, parsedIndex);
return path.map(toACVMField);
}

async getLowNullifierMembershipWitness(
[blockNumber]: ACVMField[],
[nullifier]: ACVMField[], // nullifier, we try to find the low nullifier witness for (to prove non-inclusion)
Expand Down
4 changes: 4 additions & 0 deletions yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ export abstract class TypedOracle {
throw new Error('Not available.');
}

getSiblingPath(_blockNumber: number, _treeId: MerkleTreeId, _index: Fr): Promise<Fr[]> {
throw new Error('Not available.');
}

getLowNullifierMembershipWitness(
_blockNumber: number,
_nullifier: Fr,
Expand Down
11 changes: 11 additions & 0 deletions yarn-project/acir-simulator/src/client/view_data_oracle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,17 @@ export class ViewDataOracle extends TypedOracle {
return [new Fr(index), ...siblingPath];
}

/**
* Fetches the sibling path for at a given index, block from and tree.
* @param blockNumber - The block number at which to get the membership witness.
* @param treeId - The tree id
* @param index - Index of the leaf to get sibling path for
* @returns The index and sibling path concatenated [index, sibling_path]
*/
public getSiblingPath(blockNumber: number, treeId: MerkleTreeId, index: Fr): Promise<Fr[]> {
return this.db.getSiblingPath(blockNumber, treeId, index.toBigInt());
}

/**
* Returns a low nullifier membership witness for a given nullifier at a given block.
* @param blockNumber - The block number at which to get the index.
Expand Down
1 change: 1 addition & 0 deletions yarn-project/aztec-nr/aztec/src/oracle.nr
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ mod get_low_nullifier_membership_witness;
mod get_membership_witness;
mod get_public_key;
mod get_secret_key;
mod get_sibling_path;
mod rand;
mod enqueue_public_function_call;
mod get_block_data;
Expand Down
10 changes: 10 additions & 0 deletions yarn-project/aztec-nr/aztec/src/oracle/get_sibling_path.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use crate::constants_gen::NOTE_HASH_TREE_HEIGHT;
use crate::utils::arr_copy_slice;

#[oracle(geSiblingPath)]
fn get_sibling_path_oracle<N>(_block_number: Field, _tree_id: Field, _index: Field) -> [Field; N] {}

unconstrained pub fn get_sibling_path<N>(block_number: Field, tree_id: Field, index: Field) -> [Field; N] {
let value: [Field; N] = get_sibling_path_oracle(block_number, tree_id, index);
value
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ describe('e2e_inclusion_proofs_contract', () => {
let accounts: CompleteAddress[];

let contract: InclusionProofsContract;
const publicValue = 236n;

beforeAll(async () => {
({ pxe, teardown, wallets, accounts } = await setup(1));

contract = await InclusionProofsContract.deploy(wallets[0]).send().deployed();
contract = await InclusionProofsContract.deploy(wallets[0], publicValue).send().deployed();
}, 100_000);

afterAll(() => teardown());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@ contract InclusionProofs {
state_vars::{
map::Map,
set::Set,
public_state::PublicState,
},
selector::compute_selector,
types::{
address::AztecAddress,
type_serialization::field_serialization::FieldSerializationMethods,
},
types::address::AztecAddress,
context::Context,
note::{
note_getter_options::NoteGetterOptions,
Expand All @@ -18,18 +23,22 @@ contract InclusionProofs {
constants_gen::{
NOTE_HASH_TREE_HEIGHT,
HISTORIC_BLOCKS_TREE_HEIGHT,
PUBLIC_DATA_TREE_HEIGHT,
GENERATOR_INDEX__PUBLIC_LEAF_INDEX,
},
oracle::{
get_block_data::get_block_data,
get_membership_witness::{
get_membership_witness,
MembershipWitness,
},
get_sibling_path::get_sibling_path,
get_low_nullifier_membership_witness::{
get_low_nullifier_membership_witness,
LowNullifierMembershipWitness,
},
},
hash::pedersen_hash,
// oracle::debug_log::debug_log_format,
};
use dep::value_note::value_note::{ValueNote, ValueNoteMethods, VALUE_NOTE_LEN};
Expand All @@ -41,6 +50,7 @@ contract InclusionProofs {

struct Storage {
balances: Map<Set<ValueNote, VALUE_NOTE_LEN>>,
public_value: PublicState<Field, 1>,
}

impl Storage {
Expand All @@ -53,12 +63,25 @@ contract InclusionProofs {
Set::new(context, slot, ValueNoteMethods)
},
),
public_value: PublicState::new(
context,
2, // Storage slot
FieldSerializationMethods,
),
}
}
}

#[aztec(private)]
fn constructor() {}
fn constructor(public_value: Field) {
let selector = compute_selector("_initialize((Field))");
context.call_public_function(context.this_address(), selector, [public_value]);
}

#[aztec(public)]
internal fn _initialize(value: Field) {
storage.public_value.write(value);
}

// Mints `amount` of LP tokens to `owner`.
#[aztec(private)]
Expand Down Expand Up @@ -204,6 +227,58 @@ contract InclusionProofs {
);
}

#[aztec(private)]
fn provePublicValueInclusion(
public_value: Field,
block_number: Field, // The block at which we'll prove that the public value exists
) {
// TODO: assert that block number is less than the block number of context.block_data
// --> This will either require a new oracle method that returns block_data.global_variables_hash preimage
// or modifying the private context so that we somehow expose it.

// 1)
let blocks_tree_root = context.block_data.blocks_tree_root;

// 2)
let block_data = get_block_data(block_number);

// 3)
let block_hash = block_data.block_hash();

// 4)
let blocks_tree_id = 5;
let witness: MembershipWitness<HISTORIC_BLOCKS_TREE_HEIGHT, HISTORIC_BLOCKS_TREE_HEIGHT + 1> =
get_membership_witness(block_number, blocks_tree_id, block_hash);

// 5)
// In our test case this should be tree root at the latest block and should correspond to the membership
// witness we obtain from oracle
assert(
blocks_tree_root == compute_merkle_root(block_hash, witness.index, witness.path),
"Proving membership of a block in blocks tree failed"
);

// 6)
// We have to compute the leaf index here because unlike in the case of note commitments, public values are
// siloed with contract address so an oracle could cheat and give us a membership witness for arbitrary
// value in the public data tree.
let public_value_leaf_index = pedersen_hash(
[context.this_address(), storage.public_value.storage_slot],
GENERATOR_INDEX__PUBLIC_LEAF_INDEX
);

// 7)
let public_data_tree_id = 3;
let path: [Field; PUBLIC_DATA_TREE_HEIGHT] =
get_sibling_path(block_number, public_data_tree_id, public_value_leaf_index);

// 8)
assert(
block_data.note_hash_tree_root == compute_merkle_root(public_value, public_value_leaf_index, path),
"Proving membership of a value in public data tree failed"
);
}

// Computes note hash and nullifier.
// Note 1: Needs to be defined by every contract producing logs.
// Note 2: Having it in all the contracts gives us the ability to compute the note hash and nullifier differently for different kind of notes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ contract TokenBridge {
context::{Context},
hash::{compute_secret_hash},
state_vars::{public_state::PublicState},
types::type_serialization::field_serialization::{
FieldSerializationMethods, FIELD_SERIALIZED_LEN,
},
types::type_serialization::field_serialization::FieldSerializationMethods,
types::address::{AztecAddress, EthereumAddress},
selector::compute_selector,
};
Expand Down

0 comments on commit de4fe0a

Please sign in to comment.