Skip to content

Commit

Permalink
Merge 0e087ad into c0a24fb
Browse files Browse the repository at this point in the history
  • Loading branch information
sirasistant authored Dec 18, 2023
2 parents c0a24fb + 0e087ad commit 9e5fca9
Showing 1 changed file with 109 additions and 57 deletions.
166 changes: 109 additions & 57 deletions yarn-project/noir-protocol-circuits/src/crates/types/src/hash.nr
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,11 @@ pub fn hash_args<N>(args: [Field; N]) -> Field {
}
}


// Checks that `value` is a member of a merkle tree with root `root` at position `index`
// The witness being the `sibling_path`
pub fn assert_check_membership<N>(value : Field, index : Field, sibling_path : [Field; N], root : Field) {
pub fn assert_check_membership<N>(value: Field, index: Field, sibling_path: [Field; N], root: Field) {
let calculated_root = root_from_sibling_path(value, index, sibling_path);
assert(calculated_root == root, "membership check failed");
// assert(calculated_root == root, "membership check failed");
}

// Calculate the Merkle tree root from the sibling path and leaf.
Expand All @@ -89,7 +88,7 @@ pub fn assert_check_membership<N>(value : Field, index : Field, sibling_path : [
// TODO: I'd generally like to avoid u256 for algorithms like
// this because it means we never even need to consider cases where
// the index is greater than p.
pub fn root_from_sibling_path<N>(leaf : Field, leaf_index : Field, sibling_path : [Field; N]) -> Field {
pub fn root_from_sibling_path<N>(leaf: Field, leaf_index: Field, sibling_path: [Field; N]) -> Field {
let mut node = leaf;
let indices = leaf_index.to_le_bits(N);

Expand All @@ -110,62 +109,76 @@ pub fn root_from_sibling_path<N>(leaf : Field, leaf_index : Field, sibling_path
// builds it up. We should build it up and then pass the leaf preimage as a parameter.
// We can then choose to have a general method that takes in anything hashable
// and deduplicate the logic in `contract_tree_root_from_siblings`
pub fn function_tree_root_from_siblings(selector : FunctionSelector, is_internal : bool, is_private : bool, vk_hash : Field, acir_hash : Field, function_leaf_index : Field, function_leaf_sibling_path : [Field; FUNCTION_TREE_HEIGHT]) -> Field {
let function_leaf_preimage = FunctionLeafPreimage{
selector: selector,
is_internal : is_internal,
is_private : is_private,
vk_hash : vk_hash,
acir_hash : acir_hash,
};
pub fn function_tree_root_from_siblings(
selector: FunctionSelector,
is_internal: bool,
is_private: bool,
vk_hash: Field,
acir_hash: Field,
function_leaf_index: Field,
function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]
) -> Field {
let function_leaf_preimage = FunctionLeafPreimage { selector, is_internal, is_private, vk_hash, acir_hash };

let function_leaf = function_leaf_preimage.hash();

let function_tree_root =
root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path);
let function_tree_root = root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path);

function_tree_root
}

// Calculate the contract tree root from the sibling path and leaf preimage.
pub fn contract_tree_root_from_siblings(function_tree_root : Field, storage_contract_address : AztecAddress, portal_contract_address : EthAddress, contract_leaf_index : Field,contract_leaf_sibling_path : [Field; CONTRACT_TREE_HEIGHT]) -> Field {
pub fn contract_tree_root_from_siblings(
function_tree_root: Field,
storage_contract_address: AztecAddress,
portal_contract_address: EthAddress,
contract_leaf_index: Field,
contract_leaf_sibling_path: [Field; CONTRACT_TREE_HEIGHT]
) -> Field {
//TODO(Kev): if we use shorthand syntax here, we get an error as expected,
// since variable name is `storage_contract_address` but the span is incorrect.
let contract_leaf_preimage = ContractLeafPreimage { contract_address: storage_contract_address,
portal_contract_address,
function_tree_root };

let contract_leaf_preimage = ContractLeafPreimage { contract_address: storage_contract_address, portal_contract_address, function_tree_root };

let contract_leaf = contract_leaf_preimage.hash();

let computed_contract_tree_root =
root_from_sibling_path(contract_leaf, contract_leaf_index, contract_leaf_sibling_path);

let computed_contract_tree_root = root_from_sibling_path(contract_leaf, contract_leaf_index, contract_leaf_sibling_path);

computed_contract_tree_root
}

pub fn read_request_root_from_siblings(read_request : Field, leaf_index : Field, sibling_path : [Field; NOTE_HASH_TREE_HEIGHT]) -> Field {
pub fn read_request_root_from_siblings(
read_request: Field,
leaf_index: Field,
sibling_path: [Field; NOTE_HASH_TREE_HEIGHT]
) -> Field {
root_from_sibling_path(read_request, leaf_index, sibling_path)
}

pub fn silo_commitment(address : AztecAddress, inner_commitment : Field) -> Field {
pedersen_hash([
pub fn silo_commitment(address: AztecAddress, inner_commitment: Field) -> Field {
pedersen_hash(
[
address.to_field(),
inner_commitment,
], GENERATOR_INDEX__SILOED_COMMITMENT)
inner_commitment
],
GENERATOR_INDEX__SILOED_COMMITMENT
)
}

pub fn silo_nullifier(address : AztecAddress, nullifier : Field) -> Field {
pedersen_hash([
pub fn silo_nullifier(address: AztecAddress, nullifier: Field) -> Field {
pedersen_hash(
[
address.to_field(),
nullifier,
], GENERATOR_INDEX__OUTER_NULLIFIER)
nullifier
],
GENERATOR_INDEX__OUTER_NULLIFIER
)
}

fn merkle_hash(left : Field, right : Field) -> Field {
fn merkle_hash(left: Field, right: Field) -> Field {
pedersen_hash([left, right], 0)
}

pub fn stdlib_recursion_verification_key_compress_native_vk(_vk : VerificationKey) -> Field {
pub fn stdlib_recursion_verification_key_compress_native_vk(_vk: VerificationKey) -> Field {
// Original cpp code
// stdlib::recursion::verification_key<CT::bn254>::compress_native(private_call.vk, GeneratorIndex::VK);
// The above cpp method is only ever called on verification key, so it has been special cased here
Expand All @@ -174,14 +187,22 @@ pub fn stdlib_recursion_verification_key_compress_native_vk(_vk : VerificationKe
}

// TODO CPP uses blake2s for this
pub fn compute_new_contract_address_hash(new_contract_address : AztecAddress) -> Field {
pub fn compute_new_contract_address_hash(new_contract_address: AztecAddress) -> Field {
dep::std::hash::pedersen_hash([new_contract_address.to_field()])
}

pub fn compute_l2_to_l1_hash(contract_address : AztecAddress, rollup_version_id: Field, portal_contract_address : EthAddress, chain_id : Field, content : Field) -> Field {
pub fn compute_l2_to_l1_hash(
contract_address: AztecAddress,
rollup_version_id: Field,
portal_contract_address: EthAddress,
chain_id: Field,
content: Field
) -> Field {
let mut bytes: BoundedVec<u8, 160> = BoundedVec::new(0);

let inputs = [contract_address.to_field(), rollup_version_id, portal_contract_address.to_field(), chain_id, content];
let inputs = [
contract_address.to_field(), rollup_version_id, portal_contract_address.to_field(), chain_id, content
];
for i in 0..inputs.len() {
// TODO are bytes be in fr.to_buffer() ?
let item_bytes = inputs[i].to_be_bytes(32);
Expand All @@ -193,14 +214,21 @@ pub fn compute_l2_to_l1_hash(contract_address : AztecAddress, rollup_version_id:
sha256_to_field(bytes.storage)
}

pub fn compute_constructor_hash(function_data : FunctionData, args_hash : Field, constructor_vk_hash : Field) -> Field {
pub fn compute_constructor_hash(
function_data: FunctionData,
args_hash: Field,
constructor_vk_hash: Field
) -> Field {
let function_data_hash = function_data.hash();

pedersen_hash([
pedersen_hash(
[
function_data_hash,
args_hash,
constructor_vk_hash
], GENERATOR_INDEX__CONSTRUCTOR)
],
GENERATOR_INDEX__CONSTRUCTOR
)
}

// sha256 hash is stored in two fields to accommodate all 256-bits of the hash
Expand All @@ -217,7 +245,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
//
pub 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 All @@ -228,7 +256,7 @@ pub fn accumulate_sha256(input : [U128; 4]) -> [Field; NUM_FIELDS_PER_SHA256] {
// TODO(David): This does not seem to be getting guaranteed anywhere in the code?
//
// Concatenate 4 u128 bit integers into a byte array.
let mut hash_input_flattened = [0;64];
let mut hash_input_flattened = [0; 64];
for offset in 0..4 {
let input_as_bytes = input[offset].to_be_bytes();
for byte_index in 0..16 {
Expand All @@ -241,50 +269,74 @@ pub fn accumulate_sha256(input : [U128; 4]) -> [Field; NUM_FIELDS_PER_SHA256] {
U256::from_bytes32(sha_digest).to_u128_limbs()
}

pub fn compute_logs_hash(previous_log_hash : [Field;2], current_log_hash : [Field;2]) -> [Field; NUM_FIELDS_PER_SHA256] {
accumulate_sha256([
pub fn compute_logs_hash(
previous_log_hash: [Field; 2],
current_log_hash: [Field; 2]
) -> [Field; NUM_FIELDS_PER_SHA256] {
accumulate_sha256(
[
U128::from_field(previous_log_hash[0]),
U128::from_field(previous_log_hash[1]),
U128::from_field(current_log_hash[0]),
U128::from_field(current_log_hash[1])
])
]
)
}

pub fn compute_partial_address(contract_address_salt : Field, function_tree_root : Field, constructor_hash : Field) -> Field {
pedersen_hash([
pub fn compute_partial_address(
contract_address_salt: Field,
function_tree_root: Field,
constructor_hash: Field
) -> Field {
pedersen_hash(
[
// TODO why the zeroes?
0,
0,
contract_address_salt,
function_tree_root,
constructor_hash
], GENERATOR_INDEX__PARTIAL_ADDRESS)
],
GENERATOR_INDEX__PARTIAL_ADDRESS
)
}

pub fn compute_contract_address_from_partial(point : Point, partial_address : Field) -> AztecAddress {
let field = pedersen_hash([
pub fn compute_contract_address_from_partial(point: Point, partial_address: Field) -> AztecAddress {
let field = pedersen_hash(
[
point.x,
point.y,
partial_address
], GENERATOR_INDEX__CONTRACT_ADDRESS);
],
GENERATOR_INDEX__CONTRACT_ADDRESS
);
AztecAddress::from_field(field)
}

pub fn compute_commitment_nonce(first_nullifier : Field, commitment_index : Field) -> Field {
pedersen_hash([
pub fn compute_commitment_nonce(first_nullifier: Field, commitment_index: Field) -> Field {
pedersen_hash(
[
first_nullifier,
commitment_index
], GENERATOR_INDEX__COMMITMENT_NONCE)
],
GENERATOR_INDEX__COMMITMENT_NONCE
)
}

pub fn compute_unique_siloed_commitment(nonce: Field, siloed_commitment: Field) -> Field {
pedersen_hash([
pedersen_hash(
[
nonce,
siloed_commitment
], GENERATOR_INDEX__UNIQUE_COMMITMENT)
],
GENERATOR_INDEX__UNIQUE_COMMITMENT
)
}

pub fn compute_unique_siloed_commitments<N>(first_nullifier: Field, siloed_commitments: [Field; N]) -> [Field; N] {
pub fn compute_unique_siloed_commitments<N>(
first_nullifier: Field,
siloed_commitments: [Field; N]
) -> [Field; N] {
let mut unique_siloed_commitments = [0; N];
for i in 0..N {
let siloed_commitment = siloed_commitments[i];
Expand All @@ -298,4 +350,4 @@ pub fn compute_unique_siloed_commitments<N>(first_nullifier: Field, siloed_commi

pub fn pedersen_hash<N>(inputs: [Field; N], hash_index: u32) -> Field {
dep::std::hash::pedersen_hash_with_separator(inputs, hash_index)
}
}

0 comments on commit 9e5fca9

Please sign in to comment.