From d3fe3f390b71a5f43890333e3ff1346bd79c05ff Mon Sep 17 00:00:00 2001 From: sirasistant Date: Wed, 28 Aug 2024 09:57:38 +0000 Subject: [PATCH 01/12] feat: Use poseidon for fn selectors --- noir-projects/aztec-nr/authwit/src/auth.nr | 140 +++++++++--------- .../contracts/fee_juice_contract/src/lib.nr | 10 +- .../token_portal_content_hash_lib/src/lib.nr | 12 +- .../contracts/uniswap_contract/src/util.nr | 20 +-- .../crates/types/src/abis/event_selector.nr | 8 +- .../types/src/abis/function_selector.nr | 8 +- .../crates/types/src/hash.nr | 39 +++++ .../foundation/src/abi/event_selector.ts | 4 +- .../foundation/src/abi/function_selector.ts | 4 +- .../src/crypto/poseidon/index.test.ts | 10 +- .../foundation/src/crypto/poseidon/index.ts | 21 +++ 11 files changed, 172 insertions(+), 104 deletions(-) diff --git a/noir-projects/aztec-nr/authwit/src/auth.nr b/noir-projects/aztec-nr/authwit/src/auth.nr index aff8007f83f5..e647f011c348 100644 --- a/noir-projects/aztec-nr/authwit/src/auth.nr +++ b/noir-projects/aztec-nr/authwit/src/auth.nr @@ -11,9 +11,9 @@ use dep::aztec::{prelude::Deserialize, context::{PrivateContext, PublicContext, /** * Authenticaion witness helper library * - * Authentication Witness is a scheme for authenticating actions on Aztec, so users can allow third-parties + * Authentication Witness is a scheme for authenticating actions on Aztec, so users can allow third-parties * (e.g. protocols or other users) to execute an action on their behalf. - * + * * This library provides helper functions to manage such witnesses. * The authentication witness, is some "witness" (data) that authenticates a `message_hash`. * The simplest example of an authentication witness, is a signature. The signature is the "evidence", @@ -28,23 +28,23 @@ use dep::aztec::{prelude::Deserialize, context::{PrivateContext, PublicContext, * - version: the version of the chain that the message is being consumed on, * - inner_hash: the hash of the "inner" message that is being consumed, this is the "actual" message or action. * - * While the `inner_hash` could be anything, such as showing you signed a specific message, it will often be - * a hash of the "action" to approve, along with who made the call. As part of this library, we provide a few + * While the `inner_hash` could be anything, such as showing you signed a specific message, it will often be + * a hash of the "action" to approve, along with who made the call. As part of this library, we provide a few * helper functions to deal with such messages. * * For example, we provide helper function that is used for checking that the message is an encoding of the current call. - * This can be used to let some contract "allow" another contract to act on its behalf, as long as it can + * This can be used to let some contract "allow" another contract to act on its behalf, as long as it can * show that it is acting on behalf of the contract. * - * If we take a case of allowing a contract to transfer tokens on behalf of an account, the `inner_hash` can be + * If we take a case of allowing a contract to transfer tokens on behalf of an account, the `inner_hash` can be * derived as: * inner_hash = hash(caller, "transfer", hash(to, amount)) - * + * * Where the `caller` would be the address of the contract that is trying to transfer the tokens, and `to` and `amount` - * the arguments for the transfer. - * + * the arguments for the transfer. + * * Note that we have both a `caller` and a `consumer`, the `consumer` will be the contract that is consuming the message, - * in the case of the transfer, it would be the `Token` contract itself, while the caller, will be the actor that is + * in the case of the transfer, it would be the `Token` contract itself, while the caller, will be the actor that is * allowed to transfer the tokens. * * @@ -52,30 +52,30 @@ use dep::aztec::{prelude::Deserialize, context::{PrivateContext, PublicContext, * is executed on the user's device, so we can use `oracles` to "ask" the user (not contract) for information. In public * we cannot do this, since it is executed by the sequencer (someone else). Therefore we can instead use a "registry" * to store the messages that we have approved. - * - * A simple example would be a "token" that is being "pulled" from one account into another. We will first outline - * how this would look in private, and then in public later. - * - * Say that a user `Alice` wants to deposit some tokens into a DeFi protocol (say a DEX). - * `Alice` would make a `deposit` transaction, that she is executing using her account contract. - * The account would call the `DeFi` contract to execute `deposit`, which would try to pull funds from the `Token` - * contract. Since the `DeFi` contract is trying to pull funds from an account that is not its own, it needs to - * convince the `Token` contract that it is allowed to do so. - * - * This is where the authentication witness comes in The `Token` contract computes a `message_hash` from the - * `transfer` call, and then asks `Alice Account` contract to verify that the `DeFi` contract is allowed to + * + * A simple example would be a "token" that is being "pulled" from one account into another. We will first outline + * how this would look in private, and then in public later. + * + * Say that a user `Alice` wants to deposit some tokens into a DeFi protocol (say a DEX). + * `Alice` would make a `deposit` transaction, that she is executing using her account contract. + * The account would call the `DeFi` contract to execute `deposit`, which would try to pull funds from the `Token` + * contract. Since the `DeFi` contract is trying to pull funds from an account that is not its own, it needs to + * convince the `Token` contract that it is allowed to do so. + * + * This is where the authentication witness comes in The `Token` contract computes a `message_hash` from the + * `transfer` call, and then asks `Alice Account` contract to verify that the `DeFi` contract is allowed to * execute that call. - * - * `Alice Account` contract can then ask `Alice` if she wants to allow the `DeFi` contract to pull funds from her + * + * `Alice Account` contract can then ask `Alice` if she wants to allow the `DeFi` contract to pull funds from her * account. If she does, she will sign the `message_hash` and return the signature to the `Alice Account` which * will validate it and return success to the `Token` contract which will then allow the `DeFi` contract to pull * funds from `Alice`. - * + * * To ensure that the same "approval" cannot be used multiple times, we also compute a `nullifier` for the * authentication witness, and emit it from the `Token` contract (consumer). - * - * Note that we can do this flow as we are in private were we can do oracle calls out from contracts. - * + * + * Note that we can do this flow as we are in private were we can do oracle calls out from contracts. + * * * Person Contract Contract Contract * Alice Alice Account Token DeFi @@ -116,10 +116,10 @@ use dep::aztec::{prelude::Deserialize, context::{PrivateContext, PublicContext, * | | | | * | | | | * - * - * If we instead were in public, we cannot do the same flow. Instead we would use an authentication registry to store - * the messages that we have approved. - * + * + * If we instead were in public, we cannot do the same flow. Instead we would use an authentication registry to store + * the messages that we have approved. + * * To approve a message, `Alice Account` can make a `set_authorized` call to the registry, to set a `message_hash` * as authorized. This is essentially a mapping from `message_hash` to `true` for `Alice Contract`. Every account * has its own map in the registry, so `Alice` cannot approve a message for `Bob`. @@ -170,33 +170,33 @@ use dep::aztec::{prelude::Deserialize, context::{PrivateContext, PublicContext, * * * --- FAQ --- - * Q: Why are we using a success flag of `keccak256("IS_VALID()")` instead of just returning a boolean? + * Q: Why are we using a success flag of `poseidon2_hash_bytes("IS_VALID()")` instead of just returning a boolean? * A: We want to make sure that we don't accidentally return `true` if there is a collision in the function selector. - * By returning a hash of `IS_VALID()`, it becomes very unlikely that there is both a colission and we return + * By returning a hash of `IS_VALID()`, it becomes very unlikely that there is both a colission and we return * a success flag. - * + * * Q: Why are we using static calls? * A: We are using static calls to ensure that the account contract cannot re-enter. If it was a normal call, it * could make a new call and do a re-entry attack. Using a static ensures that it cannot update any state. * * Q: Would it not be cheaper to use a nullifier instead of updating state in public? - * A: At a quick glance, a public state update + nullifier is 96 bytes, but two state updates are 128, so it would be - * cheaper to use a nullifier, if this is the way it would always be done. However, if both the approval and the + * A: At a quick glance, a public state update + nullifier is 96 bytes, but two state updates are 128, so it would be + * cheaper to use a nullifier, if this is the way it would always be done. However, if both the approval and the * consumption is done in the same transaction, then we will be able to squash the updates (only final tx state diff is posted to DA), and now it is cheaper. - * + * * Q: Why is the chain id and the version part of the message hash? * A: The chain id and the version is part of the message hash to ensure that the message is only valid on a specific - * chain to avoid a case where the same message could be used across multiple chains. + * chain to avoid a case where the same message could be used across multiple chains. */ -global IS_VALID_SELECTOR = 0xabf64ad4; // 4 first bytes of keccak256("IS_VALID()") +global IS_VALID_SELECTOR = 0x47dacd73; // 4 first bytes of poseidon2_hash_bytes("IS_VALID()") -/** +/** * Assert that `on_behalf_of` have authorized the current call with a valid authentication witness - * - * Computing the `inner_hash` using the `msg_sender`, `selector` and `args_hash` and then making a call out to the + * + * Computing the `inner_hash` using the `msg_sender`, `selector` and `args_hash` and then making a call out to the * `on_behalf_of` contract to verify that the `inner_hash` is valid. - * + * * @param on_behalf_of The address that have authorized the current call */ // docs:start:assert_current_call_valid_authwit @@ -206,14 +206,14 @@ pub fn assert_current_call_valid_authwit(context: &mut PrivateContext, on_behalf } // docs:end:assert_current_call_valid_authwit -/** +/** * Assert that a specific `inner_hash` is valid for the `on_behalf_of` address - * + * * Used as an internal function for `assert_current_call_valid_authwit` and can be used as a standalone function when * the `inner_hash` is from a different source, e.g., say a block of text etc. - * + * * @param on_behalf_of The address that have authorized the current call - * @param inner_hash The hash of the message to authorize + * @param inner_hash The hash of the message to authorize */ pub fn assert_inner_hash_valid_authwit(context: &mut PrivateContext, on_behalf_of: AztecAddress, inner_hash: Field) { // We perform a static call here and not a standard one to ensure that the account contract cannot re-enter. @@ -229,15 +229,15 @@ pub fn assert_inner_hash_valid_authwit(context: &mut PrivateContext, on_behalf_o context.push_nullifier(nullifier); } -/** +/** * Assert that `on_behalf_of` have authorized the current call in the authentication registry - * - * Computing the `inner_hash` using the `msg_sender`, `selector` and `args_hash` and then making a call out to the + * + * Computing the `inner_hash` using the `msg_sender`, `selector` and `args_hash` and then making a call out to the * `on_behalf_of` contract to verify that the `inner_hash` is valid. - * + * * Note that the authentication registry will take the `msg_sender` into account as the consumer, so this will only * work if the `msg_sender` is the same as the `consumer` when the `message_hash` was inserted into the registry. - * + * * @param on_behalf_of The address that have authorized the current call */ // docs:start:assert_current_call_valid_authwit_public @@ -249,15 +249,15 @@ pub fn assert_current_call_valid_authwit_public(context: &mut PublicContext, on_ } // docs:end:assert_current_call_valid_authwit_public -/** +/** * Assert that `on_behalf_of` have authorized a speicifc `inner_hash` in the authentication registry - * - * Computing the `inner_hash` using the `msg_sender`, `selector` and `args_hash` and then making a call out to the + * + * Computing the `inner_hash` using the `msg_sender`, `selector` and `args_hash` and then making a call out to the * `on_behalf_of` contract to verify that the `inner_hash` is valid. * * Note that the authentication registry will take the `msg_sender` into account as the consumer, so this will only * work if the `msg_sender` is the same as the `consumer` when the `message_hash` was inserted into the registry. - * + * * @param on_behalf_of The address that have authorized the `inner_hash` */ pub fn assert_inner_hash_valid_authwit_public(context: &mut PublicContext, on_behalf_of: AztecAddress, inner_hash: Field) { @@ -271,12 +271,12 @@ pub fn assert_inner_hash_valid_authwit_public(context: &mut PublicContext, on_be } /** - * Compute the `message_hash` from a function call to be used by an authentication witness - * + * Compute the `message_hash` from a function call to be used by an authentication witness + * * Useful for when you need a non-account contract to approve during execution. For example if you need a contract * to make a call to nested contract, e.g., contract A wants to exit token T to L1 using bridge B, so it needs to allow * B to transfer T on its behalf. - * + * * @param caller The address of the contract that is calling the function, in the example above, this would be B * @param consumer The address of the contract that is consuming the message, in the example above, this would be T * @param chain_id The chain id of the chain that the message is being consumed on @@ -301,21 +301,21 @@ pub fn compute_authwit_message_hash_from_call( /** * Computes the `inner_hash` of the authentication witness - * + * * This is used internally, but also useful in cases where you want to compute the `inner_hash` for a specific message * that is not necessarily a call, but just some "bytes" or text. - * + * * @param args The arguments to hash */ pub fn compute_inner_authwit_hash(args: [Field; N]) -> Field { poseidon2_hash_with_separator(args, GENERATOR_INDEX__AUTHWIT_INNER) } -/** +/** * Computs the `authwit_nullifier` for a specific `on_behalf_of` and `inner_hash` - * + * * Using the `on_behalf_of` and the `inner_hash` to ensure that the nullifier is siloed for a specific `on_behalf_of`. - * + * * @param on_behalf_of The address that have authorized the `inner_hash` * @param inner_hash The hash of the message to authorize */ @@ -328,7 +328,7 @@ pub fn compute_authwit_nullifier(on_behalf_of: AztecAddress, inner_hash: Field) /** * Computes the `message_hash` for the authentication witness - * + * * @param consumer The address of the contract that is consuming the message * @param chain_id The chain id of the chain that the message is being consumed on * @param version The version of the chain that the message is being consumed on @@ -348,9 +348,9 @@ pub fn compute_authwit_message_hash(consumer: AztecAddress, chain_id: Field, ver /** * Helper function to set the authorization status of a message hash - * + * * Wraps a public call to the authentication registry to set the authorization status of a `message_hash` - * + * * @param message_hash The hash of the message to authorize * @param authorize True if the message should be authorized, false if it should be revoked */ @@ -365,10 +365,10 @@ pub fn set_authorized(context: &mut PublicContext, message_hash: Field, authoriz /** * Helper function to reject all authwits - * + * * Wraps a public call to the authentication registry to set the `reject_all` flag * - * @param reject True if all authwits should be rejected, false otherwise + * @param reject True if all authwits should be rejected, false otherwise */ pub fn set_reject_all(context: &mut PublicContext, reject: bool) { context.call_public_function( diff --git a/noir-projects/noir-contracts/contracts/fee_juice_contract/src/lib.nr b/noir-projects/noir-contracts/contracts/fee_juice_contract/src/lib.nr index d8b059b4755c..e356c92b37bc 100644 --- a/noir-projects/noir-contracts/contracts/fee_juice_contract/src/lib.nr +++ b/noir-projects/noir-contracts/contracts/fee_juice_contract/src/lib.nr @@ -16,11 +16,11 @@ pub fn get_bridge_gas_msg_hash(owner: AztecAddress, amount: Field) -> Field { hash_bytes[i + 36] = amount_bytes[i]; } - // Function selector: 0x3e87b9be keccak256('mint_public(bytes32,uint256)') - hash_bytes[0] = 0x3e; - hash_bytes[1] = 0x87; - hash_bytes[2] = 0xb9; - hash_bytes[3] = 0xbe; + // Function selector: 0xd7f8da85 poseidon2HashBytes('mint_public(bytes32,uint256)') + hash_bytes[0] = 0xd7; + hash_bytes[1] = 0xf8; + hash_bytes[2] = 0xda; + hash_bytes[3] = 0x85; let content_hash = sha256_to_field(hash_bytes); content_hash diff --git a/noir-projects/noir-contracts/contracts/token_portal_content_hash_lib/src/lib.nr b/noir-projects/noir-contracts/contracts/token_portal_content_hash_lib/src/lib.nr index cba27bb6ef90..564238a7d03e 100644 --- a/noir-projects/noir-contracts/contracts/token_portal_content_hash_lib/src/lib.nr +++ b/noir-projects/noir-contracts/contracts/token_portal_content_hash_lib/src/lib.nr @@ -14,11 +14,11 @@ pub fn get_mint_public_content_hash(owner: AztecAddress, amount: Field) -> Field hash_bytes[i + 36] = amount_bytes[i]; } - // Function selector: 0x3e87b9be keccak256('mint_public(bytes32,uint256)') - hash_bytes[0] = 0x3e; - hash_bytes[1] = 0x87; - hash_bytes[2] = 0xb9; - hash_bytes[3] = 0xbe; + // Function selector: 0xd7f8da85 poseidon2HashBytes('mint_public(bytes32,uint256)') + hash_bytes[0] = 0xd7; + hash_bytes[1] = 0xf8; + hash_bytes[2] = 0xda; + hash_bytes[3] = 0x85; let content_hash = sha256_to_field(hash_bytes); content_hash @@ -41,7 +41,7 @@ pub fn get_mint_private_content_hash( hash_bytes[i + 36] = amount_bytes[i]; } - // Function selector: 0xefa012c1 keccak256('mint_private(bytes32,uint256)') + // Function selector: 0x9594afd9 poseidon2HashBytes('mint_private(bytes32,uint256)') hash_bytes[0] = 0xef; hash_bytes[1] = 0xa0; hash_bytes[2] = 0x12; diff --git a/noir-projects/noir-contracts/contracts/uniswap_contract/src/util.nr b/noir-projects/noir-contracts/contracts/uniswap_contract/src/util.nr index a2f08dea4cfb..a3cbb6ad1829 100644 --- a/noir-projects/noir-contracts/contracts/uniswap_contract/src/util.nr +++ b/noir-projects/noir-contracts/contracts/uniswap_contract/src/util.nr @@ -25,11 +25,11 @@ pub fn compute_swap_public_content_hash( let secret_hash_for_L1_to_l2_message_bytes = secret_hash_for_L1_to_l2_message.to_be_bytes(32); let caller_on_L1_bytes = caller_on_L1.to_field().to_be_bytes(32); - // function selector: 0xf18186d8 keccak256("swap_public(address,uint256,uint24,address,uint256,bytes32,bytes32,address)") - hash_bytes[0] = 0xf1; - hash_bytes[1] = 0x81; - hash_bytes[2] = 0x86; - hash_bytes[3] = 0xd8; + // function selector: 0xc9339214 poseidon2HashBytes("swap_public(address,uint256,uint24,address,uint256,bytes32,bytes32,address)") + hash_bytes[0] = 0xc9; + hash_bytes[1] = 0x33; + hash_bytes[2] = 0x92; + hash_bytes[3] = 0x14; for i in 0..32 { hash_bytes[i + 4] = input_token_portal_bytes[i]; @@ -71,11 +71,11 @@ pub fn compute_swap_private_content_hash( let secret_hash_for_L1_to_l2_message_bytes = secret_hash_for_L1_to_l2_message.to_be_bytes(32); let caller_on_L1_bytes = caller_on_L1.to_field().to_be_bytes(32); - // function selector: 0x16f416eb keccak256("swap_private(address,uint256,uint24,address,uint256,bytes32,bytes32,address)") - hash_bytes[0] = 0x16; - hash_bytes[1] = 0xf4; - hash_bytes[2] = 0x16; - hash_bytes[3] = 0xeb; + // function selector: 0x8fe7f43b poseidon2HashBytes("swap_private(address,uint256,uint24,address,uint256,bytes32,bytes32,address)") + hash_bytes[0] = 0x8f; + hash_bytes[1] = 0xe7; + hash_bytes[2] = 0xf4; + hash_bytes[3] = 0x3b; for i in 0..32 { hash_bytes[i + 4] = input_token_portal_bytes[i]; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/event_selector.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/event_selector.nr index 063e186006ac..ba3117ce9fbc 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/event_selector.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/event_selector.nr @@ -53,14 +53,14 @@ impl EventSelector { pub fn from_signature(signature: str) -> Self { let bytes = signature.as_bytes(); - let hash = std::hash::keccak256(bytes, bytes.len() as u32); + let hash = crate::hash::poseidon2_hash_bytes(bytes); - let mut selector_be_bytes = [0; SELECTOR_SIZE]; + let mut selector_bytes = [0; SELECTOR_SIZE]; for i in 0..SELECTOR_SIZE { - selector_be_bytes[i] = hash[i]; + selector_bytes[i] = hash[i]; } - EventSelector::from_field(field_from_bytes(selector_be_bytes, true)) + EventSelector::from_field(field_from_bytes(selector_bytes, true)) } pub fn zero() -> Self { diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/function_selector.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/function_selector.nr index 9e3ba609118f..9f26f6271f78 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/function_selector.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/function_selector.nr @@ -53,14 +53,14 @@ impl FunctionSelector { pub fn from_signature(signature: str) -> Self { let bytes = signature.as_bytes(); - let hash = std::hash::keccak256(bytes, bytes.len() as u32); + let hash = crate::hash::poseidon2_hash_bytes(bytes); - let mut selector_be_bytes = [0; SELECTOR_SIZE]; + let mut selector_bytes = [0; SELECTOR_SIZE]; for i in 0..SELECTOR_SIZE { - selector_be_bytes[i] = hash[i]; + selector_bytes[i] = hash[i]; } - FunctionSelector::from_field(field_from_bytes(selector_be_bytes, true)) + FunctionSelector::from_field(field_from_bytes(selector_bytes, true)) } pub fn zero() -> Self { diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr b/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr index a9afe4dc9b93..cbb2df483609 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr @@ -15,6 +15,7 @@ use crate::{ recursion::verification_key::VerificationKey, traits::{is_empty, ToField}, utils::field::field_from_bytes_32_trunc, point::Point }; +use super::utils::field::field_from_bytes; pub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field { let sha256_hashed = std::hash::sha256(bytes_to_hash); @@ -276,6 +277,44 @@ pub fn poseidon2_hash_with_separator( sponge.squeeze() } +#[no_predicates] +pub fn poseidon2_hash_bytes(inputs: [u8; N]) -> [u8; 32] { + // We manually hash the inputs here, since we cannot express with the type system a constant size inputs array of Math.ceil(N/31) + let mut in_len = N / 31; + let mut has_padding = false; + if N % 31 != 0 { + in_len += 1; + has_padding = true; + } + + let two_pow_64 = 18446744073709551616; + let iv : Field = (in_len as Field) * two_pow_64; + let mut sponge = std::hash::poseidon2::Poseidon2::new(iv); + + let mut current_field = [0; 31]; + for i in 0..inputs.len() { + let index = i % 31; + current_field[index] = inputs[i]; + if index == 30 { + sponge.absorb(field_from_bytes(current_field, false)); + current_field = [0; 31]; + } + } + if has_padding { + sponge.absorb(field_from_bytes(current_field, false)); + } + + let hashed_field = sponge.squeeze(); + + let mut result = [0; 32]; + let hashed_field_bytes = hashed_field.to_le_bytes(32); + + for i in 0..32 { + result[i] = hashed_field_bytes[i]; + } + result +} + pub fn pedersen_commitment(inputs: [Field; N], hash_index: u32) -> Point { std::hash::pedersen_commitment_with_separator(inputs, hash_index) } diff --git a/yarn-project/foundation/src/abi/event_selector.ts b/yarn-project/foundation/src/abi/event_selector.ts index d7cbe951a468..eb5d53e34a18 100644 --- a/yarn-project/foundation/src/abi/event_selector.ts +++ b/yarn-project/foundation/src/abi/event_selector.ts @@ -1,5 +1,5 @@ import { fromHex, toBigIntBE } from '../bigint-buffer/index.js'; -import { keccak256, randomBytes } from '../crypto/index.js'; +import { poseidon2HashBytes, randomBytes } from '../crypto/index.js'; import { type Fr } from '../fields/fields.js'; import { BufferReader } from '../serialize/buffer_reader.js'; import { Selector } from './selector.js'; @@ -44,7 +44,7 @@ export class EventSelector extends Selector { if (/\s/.test(signature)) { throw new Error('Signature cannot contain whitespace'); } - return EventSelector.fromBuffer(keccak256(Buffer.from(signature)).subarray(0, Selector.SIZE)); + return EventSelector.fromBuffer(poseidon2HashBytes(Buffer.from(signature)).subarray(0, Selector.SIZE)); } /** diff --git a/yarn-project/foundation/src/abi/function_selector.ts b/yarn-project/foundation/src/abi/function_selector.ts index c37df24d8395..34af83270f7a 100644 --- a/yarn-project/foundation/src/abi/function_selector.ts +++ b/yarn-project/foundation/src/abi/function_selector.ts @@ -1,5 +1,5 @@ import { fromHex, toBigIntBE } from '../bigint-buffer/index.js'; -import { keccak256, randomBytes } from '../crypto/index.js'; +import { poseidon2HashBytes, randomBytes } from '../crypto/index.js'; import { type Fr } from '../fields/fields.js'; import { BufferReader } from '../serialize/buffer_reader.js'; import { FieldReader } from '../serialize/field_reader.js'; @@ -73,7 +73,7 @@ export class FunctionSelector extends Selector { if (/\s/.test(signature)) { throw new Error('Signature cannot contain whitespace'); } - return FunctionSelector.fromBuffer(keccak256(Buffer.from(signature)).subarray(0, Selector.SIZE)); + return FunctionSelector.fromBuffer(poseidon2HashBytes(Buffer.from(signature)).subarray(0, Selector.SIZE)); } /** diff --git a/yarn-project/foundation/src/crypto/poseidon/index.test.ts b/yarn-project/foundation/src/crypto/poseidon/index.test.ts index a12998a12131..4e0f368ea153 100644 --- a/yarn-project/foundation/src/crypto/poseidon/index.test.ts +++ b/yarn-project/foundation/src/crypto/poseidon/index.test.ts @@ -1,5 +1,5 @@ import { Fr } from '../../fields/fields.js'; -import { poseidon2Permutation } from './index.js'; +import { poseidon2HashBytes, poseidon2Permutation } from './index.js'; describe('poseidon2Permutation', () => { it('test vectors from cpp should match', () => { @@ -22,3 +22,11 @@ describe('poseidon2Permutation', () => { ]); }); }); + +describe('poseidon2HashBytes', () => { + it('test', () => { + const buf = Buffer.from('IS_VALID()'); + const hash = poseidon2HashBytes(buf); + expect(hash.slice(0, 4).toString('hex')).toEqual('47dacd73'); + }); +}); diff --git a/yarn-project/foundation/src/crypto/poseidon/index.ts b/yarn-project/foundation/src/crypto/poseidon/index.ts index ad94ab3da967..3017f3aa9ff5 100644 --- a/yarn-project/foundation/src/crypto/poseidon/index.ts +++ b/yarn-project/foundation/src/crypto/poseidon/index.ts @@ -57,3 +57,24 @@ export function poseidon2Permutation(input: Fieldable[]): Fr[] { // assert(res.length === 4, 'Output state must be of size 4'); return res.map(o => Fr.fromBuffer(Buffer.from(o.toBuffer()))); } + +export function poseidon2HashBytes(input: Buffer): Buffer { + const inputFields = []; + for (let i = 0; i < input.length; i += 31) { + const fieldBytes = Buffer.alloc(32, 0); + input.slice(i, i + 31).copy(fieldBytes); + + // Noir builds the bytes as little-endian, so we need to reverse them. + fieldBytes.reverse(); + inputFields.push(Fr.fromBuffer(fieldBytes)); + } + + const resultBytes = Buffer.from( + BarretenbergSync.getSingleton() + .poseidon2Hash( + inputFields.map(i => new FrBarretenberg(i.toBuffer())), // TODO(#4189): remove this stupid conversion + ) + .toBuffer(), + ); + return resultBytes.reverse(); +} From e3b6f76fe7ea1522d983777d614f21bba3e1ca44 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Wed, 28 Aug 2024 14:04:00 +0000 Subject: [PATCH 02/12] feat: implement poseidon2 bytes in rust --- .../src/core/libraries/ConstantsGen.sol | 4 +- .../crates/types/src/constants.nr | 4 +- noir/noir-repo/Cargo.lock | 3 + .../bn254_blackbox_solver/src/lib.rs | 5 +- .../bn254_blackbox_solver/src/poseidon2.rs | 84 +++++++++++++++++++ noir/noir-repo/aztec_macros/Cargo.toml | 3 + .../src/transforms/contract_interface.rs | 40 +++++++-- yarn-project/circuits.js/src/constants.gen.ts | 4 +- 8 files changed, 134 insertions(+), 13 deletions(-) diff --git a/l1-contracts/src/core/libraries/ConstantsGen.sol b/l1-contracts/src/core/libraries/ConstantsGen.sol index 2e04e93dfe28..453a81f841de 100644 --- a/l1-contracts/src/core/libraries/ConstantsGen.sol +++ b/l1-contracts/src/core/libraries/ConstantsGen.sol @@ -138,9 +138,9 @@ library Constants { uint256 internal constant CANONICAL_AUTH_REGISTRY_ADDRESS = 16522644890256297179255458951626875692461008240031142745359776058397274208468; uint256 internal constant DEPLOYER_CONTRACT_ADDRESS = - 19310994760783330368337163480198602393920956587162708699802190083077641908361; + 14004383401928647177605797127979706176136674598575362510308153951334363095857; uint256 internal constant REGISTERER_CONTRACT_ADDRESS = - 2631409926445785927331173506476539962589925110142857699603561302478860342858; + 4205922897179207838560145152890933359001888854326328392591121836420153952208; uint256 internal constant FEE_JUICE_ADDRESS = 10248142274714515101077825679585135641434041564851038865006795089686437446849; uint256 internal constant AZTEC_ADDRESS_LENGTH = 1; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr index ebb231a48959..c5c74d7ec322 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -193,8 +193,8 @@ global L2_GAS_PER_NULLIFIER: u32 = 64; // CANONICAL CONTRACT ADDRESSES global CANONICAL_KEY_REGISTRY_ADDRESS = AztecAddress::from_field(0x156eabf84e3ea50d40e3330224f2d2e81648fff8f1f7ec1bc6d2873cca6e959d); global CANONICAL_AUTH_REGISTRY_ADDRESS = AztecAddress::from_field(0x24877c50868f86712240eb535d90d1c97403d074805dd3758c3aecb02958f8d4); -global DEPLOYER_CONTRACT_ADDRESS = AztecAddress::from_field(0x2ab1a2bd6d07d8d61ea56d85861446349e52c6b7c0612b702cb1e6db6ad0b089); -global REGISTERER_CONTRACT_ADDRESS = AztecAddress::from_field(0x05d15342d76e46e5be07d3cda0d753158431cdc5e39d29ce4e8fe1f5c070564a); +global DEPLOYER_CONTRACT_ADDRESS = AztecAddress::from_field(0x1ef6333a829b8820c75d5cb20a60d2025d43654674ad51470029d51b6e78e331); +global REGISTERER_CONTRACT_ADDRESS = AztecAddress::from_field(0x094c77cecb9b849ef9460f5ddcc3b536525fdeff5a7400395e6c2e07acd747d0); global FEE_JUICE_ADDRESS = AztecAddress::from_field(0x16a83e3395bc921a2441db55dce24f0e0932636901a2e676fa68b9b2b9a644c1); // LENGTH OF STRUCTS SERIALIZED TO FIELDS diff --git a/noir/noir-repo/Cargo.lock b/noir/noir-repo/Cargo.lock index f78fbfede275..7a21d01c3ae7 100644 --- a/noir/noir-repo/Cargo.lock +++ b/noir/noir-repo/Cargo.lock @@ -450,8 +450,11 @@ name = "aztec_macros" version = "0.33.0" dependencies = [ "acvm", + "bn254_blackbox_solver", "convert_case 0.6.0", + "hex", "iter-extended", + "itertools 0.10.5", "noirc_errors", "noirc_frontend", "regex", diff --git a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/lib.rs b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/lib.rs index 43ee6a9ddd25..952c4498d840 100644 --- a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/lib.rs +++ b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/lib.rs @@ -13,7 +13,10 @@ mod schnorr; use ark_ec::AffineRepr; pub use embedded_curve_ops::{embedded_curve_add, multi_scalar_mul}; pub use generator::generators::derive_generators; -pub use poseidon2::{field_from_hex, poseidon2_permutation, Poseidon2Config, POSEIDON2_CONFIG}; +pub use poseidon2::{ + field_from_hex, poseidon2_permutation, poseidon_hash, Poseidon2Config, Poseidon2Sponge, + POSEIDON2_CONFIG, +}; // Temporary hack, this ensure that we always use a bn254 field here // without polluting the feature flags of the `acir_field` crate. diff --git a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/poseidon2.rs b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/poseidon2.rs index dd3e8b725c20..64823e37029c 100644 --- a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/poseidon2.rs +++ b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/poseidon2.rs @@ -543,6 +543,75 @@ impl<'a> Poseidon2<'a> { } } +/// Performs a poseidon hash with a sponge construction equivalent to the one in poseidon2.nr +pub fn poseidon_hash(inputs: &[FieldElement]) -> Result { + let two_pow_64 = 18446744073709551616_u128.into(); + let iv = FieldElement::from(inputs.len()) * two_pow_64; + let mut sponge = Poseidon2Sponge::new(iv, 3); + for input in inputs.iter() { + sponge.absorb(*input)?; + } + sponge.squeeze() +} + +pub struct Poseidon2Sponge<'a> { + rate: usize, + poseidon: Poseidon2<'a>, + squeezed: bool, + cache: Vec, + state: Vec, +} + +impl<'a> Poseidon2Sponge<'a> { + pub fn new(iv: FieldElement, rate: usize) -> Poseidon2Sponge<'a> { + let mut result = Poseidon2Sponge { + cache: Vec::with_capacity(rate), + state: vec![FieldElement::zero(); rate + 1], + squeezed: false, + rate, + poseidon: Poseidon2::new(), + }; + result.state[rate] = iv; + result + } + + fn perform_duplex(&mut self) -> Result<(), BlackBoxResolutionError> { + // zero-pad the cache + for _ in self.cache.len()..self.rate { + self.cache.push(FieldElement::zero()); + } + // add the cache into sponge state + for i in 0..self.rate { + self.state[i] += self.cache[i]; + } + self.state = self.poseidon.permutation(&self.state, 4)?; + Ok(()) + } + + pub fn absorb(&mut self, input: FieldElement) -> Result<(), BlackBoxResolutionError> { + assert!(!self.squeezed); + if self.cache.len() == self.rate { + // If we're absorbing, and the cache is full, apply the sponge permutation to compress the cache + self.perform_duplex()?; + self.cache = vec![input]; + } else { + // If we're absorbing, and the cache is not full, add the input into the cache + self.cache.push(input); + } + Ok(()) + } + + pub fn squeeze(&mut self) -> Result { + assert!(!self.squeezed); + // If we're in absorb mode, apply sponge permutation to compress the cache. + self.perform_duplex()?; + self.squeezed = true; + + // Pop one item off the top of the permutation and return it. + Ok(self.state[0]) + } +} + #[cfg(test)] mod test { use acir::AcirField; @@ -562,4 +631,19 @@ mod test { ]; assert_eq!(result, expected_result); } + + #[test] + fn hash_smoke_test() { + let fields = [ + FieldElement::from(1u128), + FieldElement::from(2u128), + FieldElement::from(3u128), + FieldElement::from(4u128), + ]; + let result = super::poseidon_hash(&fields).expect("should hash successfully"); + assert_eq!( + result, + field_from_hex("130bf204a32cac1f0ace56c78b731aa3809f06df2731ebcf6b3464a15788b1b9"), + ); + } } diff --git a/noir/noir-repo/aztec_macros/Cargo.toml b/noir/noir-repo/aztec_macros/Cargo.toml index c9d88e36e282..fa3708d125f4 100644 --- a/noir/noir-repo/aztec_macros/Cargo.toml +++ b/noir/noir-repo/aztec_macros/Cargo.toml @@ -17,6 +17,9 @@ acvm.workspace = true noirc_frontend.workspace = true noirc_errors.workspace = true iter-extended.workspace = true +bn254_blackbox_solver.workspace = true convert_case = "0.6.0" regex = "1.10" tiny-keccak = { version = "2.0.0", features = ["keccak"] } +itertools = "^0.10" +hex.workspace = true diff --git a/noir/noir-repo/aztec_macros/src/transforms/contract_interface.rs b/noir/noir-repo/aztec_macros/src/transforms/contract_interface.rs index 7a8a71878577..d95d5baf2c72 100644 --- a/noir/noir-repo/aztec_macros/src/transforms/contract_interface.rs +++ b/noir/noir-repo/aztec_macros/src/transforms/contract_interface.rs @@ -1,5 +1,6 @@ use acvm::acir::AcirField; +use bn254_blackbox_solver::poseidon_hash; use noirc_errors::Location; use noirc_frontend::ast::{Ident, NoirFunction, UnresolvedTypeData}; use noirc_frontend::{ @@ -9,7 +10,7 @@ use noirc_frontend::{ Type, }; -use tiny_keccak::{Hasher, Keccak}; +use itertools::Itertools; use crate::utils::parse_utils::parse_program; use crate::utils::{ @@ -251,7 +252,7 @@ pub fn generate_contract_interface( module_name, stubs.iter().map(|(src, _)| src.to_owned()).collect::>().join("\n"), if has_storage_layout { storage_layout_getter.clone() } else { "".to_string() }, - if has_storage_layout { format!("#[contract_library_method]\n{}", storage_layout_getter) } else { "".to_string() } + if has_storage_layout { format!("#[contract_library_method]\n{}", storage_layout_getter) } else { "".to_string() } ); let (contract_interface_ast, errors) = parse_program(&contract_interface, empty_spans); @@ -295,10 +296,8 @@ fn compute_fn_signature_hash(fn_name: &str, parameters: &[Type]) -> u32 { fn_name, parameters.iter().map(signature_of_type).collect::>().join(",") ); - let mut keccak = Keccak::v256(); - let mut result = [0u8; 32]; - keccak.update(signature.as_bytes()); - keccak.finalize(&mut result); + + let result = poseidon2_hash_bytes(signature.as_bytes().to_vec()); // Take the first 4 bytes of the hash and convert them to an integer // If you change the following value you have to change NUM_BYTES_PER_NOTE_TYPE_ID in l1_note_payload.ts as well let num_bytes_per_note_type_id = 4; @@ -428,3 +427,32 @@ pub fn update_fn_signatures_in_contract_interface( } Ok(()) } +fn poseidon2_hash_bytes(inputs: Vec) -> Vec { + let fields: Vec<_> = inputs + .into_iter() + .chunks(31) + .into_iter() + .map(|bytes_chunk| { + let mut chunk_as_vec: Vec = bytes_chunk.collect(); + chunk_as_vec.extend(std::iter::repeat(0).take(32 - chunk_as_vec.len())); + // Build a little endian field element + chunk_as_vec.reverse(); + FieldElement::from_be_bytes_reduce(&chunk_as_vec) + }) + .collect(); + let mut hash_bytes = poseidon_hash(&fields).expect("Poseidon hash failed").to_be_bytes(); + hash_bytes.reverse(); + hash_bytes +} + +#[cfg(test)] +mod test { + use crate::transforms::contract_interface::poseidon2_hash_bytes; + + #[test] + fn test_poseidon2_hash_bytes() { + let mut hash = poseidon2_hash_bytes("IS_VALID()".as_bytes().to_vec()); + hash.truncate(4); + assert_eq!(hex::encode(&hash), "47dacd73"); + } +} diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index 306aca914065..b93b085571fb 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -122,9 +122,9 @@ export const CANONICAL_KEY_REGISTRY_ADDRESS = 9694109890306420370616891858093188542026876097103155811681068343994212062621n; export const CANONICAL_AUTH_REGISTRY_ADDRESS = 16522644890256297179255458951626875692461008240031142745359776058397274208468n; -export const DEPLOYER_CONTRACT_ADDRESS = 19310994760783330368337163480198602393920956587162708699802190083077641908361n; +export const DEPLOYER_CONTRACT_ADDRESS = 14004383401928647177605797127979706176136674598575362510308153951334363095857n; export const REGISTERER_CONTRACT_ADDRESS = - 2631409926445785927331173506476539962589925110142857699603561302478860342858n; + 4205922897179207838560145152890933359001888854326328392591121836420153952208n; export const FEE_JUICE_ADDRESS = 10248142274714515101077825679585135641434041564851038865006795089686437446849n; export const AZTEC_ADDRESS_LENGTH = 1; export const GAS_FEES_LENGTH = 2; From cca5331dcfedafb30fd422389ad211f1df20949e Mon Sep 17 00:00:00 2001 From: sirasistant Date: Wed, 28 Aug 2024 14:18:48 +0000 Subject: [PATCH 03/12] update constants --- l1-contracts/src/core/libraries/ConstantsGen.sol | 2 +- .../noir-protocol-circuits/crates/types/src/constants.nr | 2 +- yarn-project/circuits.js/src/constants.gen.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/l1-contracts/src/core/libraries/ConstantsGen.sol b/l1-contracts/src/core/libraries/ConstantsGen.sol index 453a81f841de..a35c744fc620 100644 --- a/l1-contracts/src/core/libraries/ConstantsGen.sol +++ b/l1-contracts/src/core/libraries/ConstantsGen.sol @@ -142,7 +142,7 @@ library Constants { uint256 internal constant REGISTERER_CONTRACT_ADDRESS = 4205922897179207838560145152890933359001888854326328392591121836420153952208; uint256 internal constant FEE_JUICE_ADDRESS = - 10248142274714515101077825679585135641434041564851038865006795089686437446849; + 6742376591449076198619058698679514594972390538037174982247442442972596189035; uint256 internal constant AZTEC_ADDRESS_LENGTH = 1; uint256 internal constant GAS_FEES_LENGTH = 2; uint256 internal constant GAS_LENGTH = 2; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr index c5c74d7ec322..3659560c3687 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -195,7 +195,7 @@ global CANONICAL_KEY_REGISTRY_ADDRESS = AztecAddress::from_field(0x156eabf84e3ea global CANONICAL_AUTH_REGISTRY_ADDRESS = AztecAddress::from_field(0x24877c50868f86712240eb535d90d1c97403d074805dd3758c3aecb02958f8d4); global DEPLOYER_CONTRACT_ADDRESS = AztecAddress::from_field(0x1ef6333a829b8820c75d5cb20a60d2025d43654674ad51470029d51b6e78e331); global REGISTERER_CONTRACT_ADDRESS = AztecAddress::from_field(0x094c77cecb9b849ef9460f5ddcc3b536525fdeff5a7400395e6c2e07acd747d0); -global FEE_JUICE_ADDRESS = AztecAddress::from_field(0x16a83e3395bc921a2441db55dce24f0e0932636901a2e676fa68b9b2b9a644c1); +global FEE_JUICE_ADDRESS = AztecAddress::from_field(0x0ee80cc73b879d0b41b286440ed208de53e441fb306578cdf0b20b7c0832b76b); // LENGTH OF STRUCTS SERIALIZED TO FIELDS global AZTEC_ADDRESS_LENGTH = 1; diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index b93b085571fb..38f3d4e64e45 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -125,7 +125,7 @@ export const CANONICAL_AUTH_REGISTRY_ADDRESS = export const DEPLOYER_CONTRACT_ADDRESS = 14004383401928647177605797127979706176136674598575362510308153951334363095857n; export const REGISTERER_CONTRACT_ADDRESS = 4205922897179207838560145152890933359001888854326328392591121836420153952208n; -export const FEE_JUICE_ADDRESS = 10248142274714515101077825679585135641434041564851038865006795089686437446849n; +export const FEE_JUICE_ADDRESS = 6742376591449076198619058698679514594972390538037174982247442442972596189035n; export const AZTEC_ADDRESS_LENGTH = 1; export const GAS_FEES_LENGTH = 2; export const GAS_LENGTH = 2; From 3763af680d7f80b5343ea9db3d6072b24bca9914 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Wed, 28 Aug 2024 14:32:33 +0000 Subject: [PATCH 04/12] more constant updates --- l1-contracts/src/core/libraries/ConstantsGen.sol | 4 ++-- .../noir-protocol-circuits/crates/types/src/constants.nr | 4 ++-- yarn-project/circuits.js/src/constants.gen.ts | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/l1-contracts/src/core/libraries/ConstantsGen.sol b/l1-contracts/src/core/libraries/ConstantsGen.sol index a35c744fc620..aa68fc9e1dc2 100644 --- a/l1-contracts/src/core/libraries/ConstantsGen.sol +++ b/l1-contracts/src/core/libraries/ConstantsGen.sol @@ -134,9 +134,9 @@ library Constants { uint256 internal constant L2_GAS_PER_NOTE_HASH = 32; uint256 internal constant L2_GAS_PER_NULLIFIER = 64; uint256 internal constant CANONICAL_KEY_REGISTRY_ADDRESS = - 9694109890306420370616891858093188542026876097103155811681068343994212062621; + 639638883883102015708927376977286479323003429972751272892463029564544935948; uint256 internal constant CANONICAL_AUTH_REGISTRY_ADDRESS = - 16522644890256297179255458951626875692461008240031142745359776058397274208468; + 11468751044532384554787682034362373061633944565658713451304908990088771320309; uint256 internal constant DEPLOYER_CONTRACT_ADDRESS = 14004383401928647177605797127979706176136674598575362510308153951334363095857; uint256 internal constant REGISTERER_CONTRACT_ADDRESS = diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr index 3659560c3687..c0faa77bce5f 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -191,8 +191,8 @@ global L2_GAS_PER_NOTE_HASH: u32 = 32; global L2_GAS_PER_NULLIFIER: u32 = 64; // CANONICAL CONTRACT ADDRESSES -global CANONICAL_KEY_REGISTRY_ADDRESS = AztecAddress::from_field(0x156eabf84e3ea50d40e3330224f2d2e81648fff8f1f7ec1bc6d2873cca6e959d); -global CANONICAL_AUTH_REGISTRY_ADDRESS = AztecAddress::from_field(0x24877c50868f86712240eb535d90d1c97403d074805dd3758c3aecb02958f8d4); +global CANONICAL_KEY_REGISTRY_ADDRESS = AztecAddress::from_field(0x016a05d4d2bbf343befb44e4989b4cf924e491d1dcecd8e7d062f8dec4a4680c); +global CANONICAL_AUTH_REGISTRY_ADDRESS = AztecAddress::from_field(0x195b1543269c57a03adc69ccefaef8f32d081a95fa07c071d9ba02ea6530b9f5); global DEPLOYER_CONTRACT_ADDRESS = AztecAddress::from_field(0x1ef6333a829b8820c75d5cb20a60d2025d43654674ad51470029d51b6e78e331); global REGISTERER_CONTRACT_ADDRESS = AztecAddress::from_field(0x094c77cecb9b849ef9460f5ddcc3b536525fdeff5a7400395e6c2e07acd747d0); global FEE_JUICE_ADDRESS = AztecAddress::from_field(0x0ee80cc73b879d0b41b286440ed208de53e441fb306578cdf0b20b7c0832b76b); diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index 38f3d4e64e45..26ba37db0029 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -119,9 +119,9 @@ export const L2_GAS_PER_LOG_BYTE = 4; export const L2_GAS_PER_NOTE_HASH = 32; export const L2_GAS_PER_NULLIFIER = 64; export const CANONICAL_KEY_REGISTRY_ADDRESS = - 9694109890306420370616891858093188542026876097103155811681068343994212062621n; + 639638883883102015708927376977286479323003429972751272892463029564544935948n; export const CANONICAL_AUTH_REGISTRY_ADDRESS = - 16522644890256297179255458951626875692461008240031142745359776058397274208468n; + 11468751044532384554787682034362373061633944565658713451304908990088771320309n; export const DEPLOYER_CONTRACT_ADDRESS = 14004383401928647177605797127979706176136674598575362510308153951334363095857n; export const REGISTERER_CONTRACT_ADDRESS = 4205922897179207838560145152890933359001888854326328392591121836420153952208n; From e393ec91a6b51bce6d6e6c93769eb230da395be7 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Sun, 15 Sep 2024 00:15:26 +0000 Subject: [PATCH 05/12] some changes --- .../contracts/fee_juice_contract/src/lib.nr | 10 +++++----- .../token_portal_content_hash_lib/src/lib.nr | 12 +++++------ .../contracts/uniswap_contract/src/util.nr | 20 +++++++++---------- .../crates/types/src/constants.nr | 1 + .../crates/types/src/hash.nr | 10 +--------- noir/noir-repo/Cargo.lock | 16 --------------- noir/noir-repo/aztec_macros/Cargo.toml | 1 - .../src/transforms/contract_interface.rs | 3 ++- .../src/transforms/note_interface.rs | 9 +++------ 9 files changed, 28 insertions(+), 54 deletions(-) diff --git a/noir-projects/noir-contracts/contracts/fee_juice_contract/src/lib.nr b/noir-projects/noir-contracts/contracts/fee_juice_contract/src/lib.nr index 9eaea6550159..de5dce2b1edd 100644 --- a/noir-projects/noir-contracts/contracts/fee_juice_contract/src/lib.nr +++ b/noir-projects/noir-contracts/contracts/fee_juice_contract/src/lib.nr @@ -16,11 +16,11 @@ pub fn get_bridge_gas_msg_hash(owner: AztecAddress, amount: Field) -> Field { hash_bytes[i + 36] = amount_bytes[i]; } - // Function selector: 0x63f44968 keccak256('claim(bytes32,uint256)') - hash_bytes[0] = 0x63; - hash_bytes[1] = 0xf4; - hash_bytes[2] = 0x49; - hash_bytes[3] = 0x68; + // Function selector: 0x3e87b9be keccak256('mint_public(bytes32,uint256)') + hash_bytes[0] = 0x3e; + hash_bytes[1] = 0x87; + hash_bytes[2] = 0xb9; + hash_bytes[3] = 0xbe; let content_hash = sha256_to_field(hash_bytes); content_hash diff --git a/noir-projects/noir-contracts/contracts/token_portal_content_hash_lib/src/lib.nr b/noir-projects/noir-contracts/contracts/token_portal_content_hash_lib/src/lib.nr index 3abe5a9d4ac8..f7789aefcd58 100644 --- a/noir-projects/noir-contracts/contracts/token_portal_content_hash_lib/src/lib.nr +++ b/noir-projects/noir-contracts/contracts/token_portal_content_hash_lib/src/lib.nr @@ -14,11 +14,11 @@ pub fn get_mint_public_content_hash(owner: AztecAddress, amount: Field) -> Field hash_bytes[i + 36] = amount_bytes[i]; } - // Function selector: 0xd7f8da85 poseidon2HashBytes('mint_public(bytes32,uint256)') - hash_bytes[0] = 0xd7; - hash_bytes[1] = 0xf8; - hash_bytes[2] = 0xda; - hash_bytes[3] = 0x85; + // Function selector: 0x3e87b9be keccak256('mint_public(bytes32,uint256)') + hash_bytes[0] = 0x3e; + hash_bytes[1] = 0x87; + hash_bytes[2] = 0xb9; + hash_bytes[3] = 0xbe; let content_hash = sha256_to_field(hash_bytes); content_hash @@ -41,7 +41,7 @@ pub fn get_mint_private_content_hash( hash_bytes[i + 36] = amount_bytes[i]; } - // Function selector: 0x9594afd9 poseidon2HashBytes('mint_private(bytes32,uint256)') + // Function selector: 0xefa012c1 keccak256('mint_private(bytes32,uint256)') hash_bytes[0] = 0xef; hash_bytes[1] = 0xa0; hash_bytes[2] = 0x12; diff --git a/noir-projects/noir-contracts/contracts/uniswap_contract/src/util.nr b/noir-projects/noir-contracts/contracts/uniswap_contract/src/util.nr index 545ab25c6959..afc689c2f0c2 100644 --- a/noir-projects/noir-contracts/contracts/uniswap_contract/src/util.nr +++ b/noir-projects/noir-contracts/contracts/uniswap_contract/src/util.nr @@ -25,11 +25,11 @@ pub fn compute_swap_public_content_hash( let secret_hash_for_L1_to_l2_message_bytes: [u8; 32] = secret_hash_for_L1_to_l2_message.to_be_bytes(); let caller_on_L1_bytes: [u8; 32] = caller_on_L1.to_field().to_be_bytes(); - // function selector: 0xc9339214 poseidon2HashBytes("swap_public(address,uint256,uint24,address,uint256,bytes32,bytes32,address)") - hash_bytes[0] = 0xc9; - hash_bytes[1] = 0x33; - hash_bytes[2] = 0x92; - hash_bytes[3] = 0x14; + // function selector: 0xf18186d8 keccak256("swap_public(address,uint256,uint24,address,uint256,bytes32,bytes32,address)") + hash_bytes[0] = 0xf1; + hash_bytes[1] = 0x81; + hash_bytes[2] = 0x86; + hash_bytes[3] = 0xd8; for i in 0..32 { hash_bytes[i + 4] = input_token_portal_bytes[i]; @@ -71,11 +71,11 @@ pub fn compute_swap_private_content_hash( let secret_hash_for_L1_to_l2_message_bytes: [u8; 32] = secret_hash_for_L1_to_l2_message.to_be_bytes(); let caller_on_L1_bytes: [u8; 32] = caller_on_L1.to_field().to_be_bytes(); - // function selector: 0x8fe7f43b poseidon2HashBytes("swap_private(address,uint256,uint24,address,uint256,bytes32,bytes32,address)") - hash_bytes[0] = 0x8f; - hash_bytes[1] = 0xe7; - hash_bytes[2] = 0xf4; - hash_bytes[3] = 0x3b; + // function selector: 0x16f416eb keccak256("swap_private(address,uint256,uint24,address,uint256,bytes32,bytes32,address)") + hash_bytes[0] = 0x16; + hash_bytes[1] = 0xf4; + hash_bytes[2] = 0x16; + hash_bytes[3] = 0xeb; for i in 0..32 { hash_bytes[i + 4] = input_token_portal_bytes[i]; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr index 5550de38ed13..060b60653525 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -196,6 +196,7 @@ global CANONICAL_AUTH_REGISTRY_ADDRESS = AztecAddress::from_field(0x195b1543269c global DEPLOYER_CONTRACT_ADDRESS = AztecAddress::from_field(0x1ef6333a829b8820c75d5cb20a60d2025d43654674ad51470029d51b6e78e331); global REGISTERER_CONTRACT_ADDRESS = AztecAddress::from_field(0x094c77cecb9b849ef9460f5ddcc3b536525fdeff5a7400395e6c2e07acd747d0); global FEE_JUICE_ADDRESS = AztecAddress::from_field(0x0ee80cc73b879d0b41b286440ed208de53e441fb306578cdf0b20b7c0832b76b); +global ROUTER_ADDRESS = AztecAddress::from_field(0x1011feaa54609098a884322267ec754c637b280c15aa79c3be9f1394e2b29cd3); // LENGTH OF STRUCTS SERIALIZED TO FIELDS global AZTEC_ADDRESS_LENGTH = 1; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr b/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr index 2c48e8e71268..009fe286fec7 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr @@ -304,15 +304,7 @@ pub fn poseidon2_hash_bytes(inputs: [u8; N]) -> [u8; 32] { sponge.absorb(field_from_bytes(current_field, false)); } - let hashed_field = sponge.squeeze(); - - let mut result = [0; 32]; - let hashed_field_bytes = hashed_field.to_le_bytes(32); - - for i in 0..32 { - result[i] = hashed_field_bytes[i]; - } - result + sponge.squeeze().to_le_bytes::<32>() } #[test] diff --git a/noir/noir-repo/Cargo.lock b/noir/noir-repo/Cargo.lock index 8f21df00fd8f..e8f06054cf71 100644 --- a/noir/noir-repo/Cargo.lock +++ b/noir/noir-repo/Cargo.lock @@ -450,7 +450,6 @@ dependencies = [ "noirc_errors", "noirc_frontend", "regex", - "tiny-keccak", ] [[package]] @@ -1127,12 +1126,6 @@ version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - [[package]] name = "crypto-bigint" version = "0.4.9" @@ -4546,15 +4539,6 @@ dependencies = [ "time-core", ] -[[package]] -name = "tiny-keccak" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" -dependencies = [ - "crunchy", -] - [[package]] name = "tinytemplate" version = "1.2.1" diff --git a/noir/noir-repo/aztec_macros/Cargo.toml b/noir/noir-repo/aztec_macros/Cargo.toml index 12d93254b74f..e7bee99b74e1 100644 --- a/noir/noir-repo/aztec_macros/Cargo.toml +++ b/noir/noir-repo/aztec_macros/Cargo.toml @@ -21,6 +21,5 @@ bn254_blackbox_solver.workspace = true convert_case = "0.6.0" im.workspace = true regex = "1.10" -tiny-keccak = { version = "2.0.0", features = ["keccak"] } itertools = "^0.10" hex.workspace = true diff --git a/noir/noir-repo/aztec_macros/src/transforms/contract_interface.rs b/noir/noir-repo/aztec_macros/src/transforms/contract_interface.rs index 24770a2f0aa4..3440690c84d2 100644 --- a/noir/noir-repo/aztec_macros/src/transforms/contract_interface.rs +++ b/noir/noir-repo/aztec_macros/src/transforms/contract_interface.rs @@ -428,7 +428,8 @@ pub fn update_fn_signatures_in_contract_interface( } Ok(()) } -fn poseidon2_hash_bytes(inputs: Vec) -> Vec { + +pub(crate) fn poseidon2_hash_bytes(inputs: Vec) -> Vec { let fields: Vec<_> = inputs .into_iter() .chunks(31) diff --git a/noir/noir-repo/aztec_macros/src/transforms/note_interface.rs b/noir/noir-repo/aztec_macros/src/transforms/note_interface.rs index d9c4a594fc69..b2a8d70626d0 100644 --- a/noir/noir-repo/aztec_macros/src/transforms/note_interface.rs +++ b/noir/noir-repo/aztec_macros/src/transforms/note_interface.rs @@ -12,8 +12,6 @@ use noirc_frontend::{ use acvm::AcirField; use regex::Regex; -// TODO(#7165): nuke the following dependency from here and Cargo.toml -use tiny_keccak::{Hasher, Keccak}; use crate::utils::parse_utils::parse_program; use crate::{ @@ -28,6 +26,8 @@ use crate::{ }, }; +use super::contract_interface::poseidon2_hash_bytes; + // Automatic implementation of most of the methods in the NoteInterface trait, guiding the user with meaningful error messages in case some // methods must be implemented manually. pub fn generate_note_interface_impl( @@ -751,10 +751,7 @@ fn generate_note_deserialize_content_source( // Utility function to generate the note type id as a Field fn compute_note_type_id(note_type: &str) -> u32 { // TODO(#4519) Improve automatic note id generation and assignment - let mut keccak = Keccak::v256(); - let mut result = [0u8; 32]; - keccak.update(note_type.as_bytes()); - keccak.finalize(&mut result); + let result = poseidon2_hash_bytes(note_type.as_bytes().to_vec()); // Take the first 4 bytes of the hash and convert them to an integer // If you change the following value you have to change NUM_BYTES_PER_NOTE_TYPE_ID in l1_note_payload.ts as well let num_bytes_per_note_type_id = 4; From 7394b6cf161c8347029bcbb96e84cff02c702048 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Sun, 15 Sep 2024 00:18:53 +0000 Subject: [PATCH 06/12] constants gen --- l1-contracts/src/core/libraries/ConstantsGen.sol | 8 +++++--- yarn-project/circuits.js/src/constants.gen.ts | 10 +++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/l1-contracts/src/core/libraries/ConstantsGen.sol b/l1-contracts/src/core/libraries/ConstantsGen.sol index c492ffc19bdc..96665098c7c3 100644 --- a/l1-contracts/src/core/libraries/ConstantsGen.sol +++ b/l1-contracts/src/core/libraries/ConstantsGen.sol @@ -143,6 +143,8 @@ library Constants { 4205922897179207838560145152890933359001888854326328392591121836420153952208; uint256 internal constant FEE_JUICE_ADDRESS = 6742376591449076198619058698679514594972390538037174982247442442972596189035; + uint256 internal constant ROUTER_ADDRESS = + 7268799613082469933251235702514160327341161584122631177360064643484764773587; uint256 internal constant AZTEC_ADDRESS_LENGTH = 1; uint256 internal constant GAS_FEES_LENGTH = 2; uint256 internal constant GAS_LENGTH = 2; @@ -191,16 +193,16 @@ library Constants { uint256 internal constant PUBLIC_CONTEXT_INPUTS_LENGTH = 42; uint256 internal constant AGGREGATION_OBJECT_LENGTH = 16; uint256 internal constant SCOPED_READ_REQUEST_LEN = 3; - uint256 internal constant PUBLIC_DATA_READ_LENGTH = 2; + uint256 internal constant PUBLIC_DATA_READ_LENGTH = 3; uint256 internal constant PRIVATE_VALIDATION_REQUESTS_LENGTH = 772; - uint256 internal constant PUBLIC_VALIDATION_REQUESTS_LENGTH = 770; + uint256 internal constant PUBLIC_VALIDATION_REQUESTS_LENGTH = 834; uint256 internal constant PUBLIC_DATA_UPDATE_REQUEST_LENGTH = 3; uint256 internal constant COMBINED_ACCUMULATED_DATA_LENGTH = 610; uint256 internal constant COMBINED_CONSTANT_DATA_LENGTH = 43; uint256 internal constant PRIVATE_ACCUMULATED_DATA_LENGTH = 1336; uint256 internal constant PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 2167; uint256 internal constant PUBLIC_ACCUMULATED_DATA_LENGTH = 1311; - uint256 internal constant PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 3885; + uint256 internal constant PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 3949; uint256 internal constant KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 663; uint256 internal constant CONSTANT_ROLLUP_DATA_LENGTH = 12; uint256 internal constant BASE_OR_MERGE_PUBLIC_INPUTS_LENGTH = 29; diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index f90a3773fd64..312d771ef96f 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -124,8 +124,8 @@ export const CANONICAL_AUTH_REGISTRY_ADDRESS = 11468751044532384554787682034362373061633944565658713451304908990088771320309n; export const DEPLOYER_CONTRACT_ADDRESS = 14004383401928647177605797127979706176136674598575362510308153951334363095857n; export const REGISTERER_CONTRACT_ADDRESS = - 2631409926445785927331173506476539962589925110142857699603561302478860342858n; -export const FEE_JUICE_ADDRESS = 10248142274714515101077825679585135641434041564851038865006795089686437446849n; + 4205922897179207838560145152890933359001888854326328392591121836420153952208n; +export const FEE_JUICE_ADDRESS = 6742376591449076198619058698679514594972390538037174982247442442972596189035n; export const ROUTER_ADDRESS = 7268799613082469933251235702514160327341161584122631177360064643484764773587n; export const AZTEC_ADDRESS_LENGTH = 1; export const GAS_FEES_LENGTH = 2; @@ -175,16 +175,16 @@ export const PRIVATE_CALL_STACK_ITEM_LENGTH = 649; export const PUBLIC_CONTEXT_INPUTS_LENGTH = 42; export const AGGREGATION_OBJECT_LENGTH = 16; export const SCOPED_READ_REQUEST_LEN = 3; -export const PUBLIC_DATA_READ_LENGTH = 2; +export const PUBLIC_DATA_READ_LENGTH = 3; export const PRIVATE_VALIDATION_REQUESTS_LENGTH = 772; -export const PUBLIC_VALIDATION_REQUESTS_LENGTH = 770; +export const PUBLIC_VALIDATION_REQUESTS_LENGTH = 834; export const PUBLIC_DATA_UPDATE_REQUEST_LENGTH = 3; export const COMBINED_ACCUMULATED_DATA_LENGTH = 610; export const COMBINED_CONSTANT_DATA_LENGTH = 43; export const PRIVATE_ACCUMULATED_DATA_LENGTH = 1336; export const PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 2167; export const PUBLIC_ACCUMULATED_DATA_LENGTH = 1311; -export const PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 3885; +export const PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 3949; export const KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 663; export const CONSTANT_ROLLUP_DATA_LENGTH = 12; export const BASE_OR_MERGE_PUBLIC_INPUTS_LENGTH = 29; From 50230b2bebbf813288c3055bb359fb2d60f9daa8 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Sun, 15 Sep 2024 00:30:08 +0000 Subject: [PATCH 07/12] fix messaging --- .../contracts/fee_juice_contract/src/lib.nr | 10 +++++----- .../token_portal_content_hash_lib/src/lib.nr | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/noir-projects/noir-contracts/contracts/fee_juice_contract/src/lib.nr b/noir-projects/noir-contracts/contracts/fee_juice_contract/src/lib.nr index de5dce2b1edd..9eaea6550159 100644 --- a/noir-projects/noir-contracts/contracts/fee_juice_contract/src/lib.nr +++ b/noir-projects/noir-contracts/contracts/fee_juice_contract/src/lib.nr @@ -16,11 +16,11 @@ pub fn get_bridge_gas_msg_hash(owner: AztecAddress, amount: Field) -> Field { hash_bytes[i + 36] = amount_bytes[i]; } - // Function selector: 0x3e87b9be keccak256('mint_public(bytes32,uint256)') - hash_bytes[0] = 0x3e; - hash_bytes[1] = 0x87; - hash_bytes[2] = 0xb9; - hash_bytes[3] = 0xbe; + // Function selector: 0x63f44968 keccak256('claim(bytes32,uint256)') + hash_bytes[0] = 0x63; + hash_bytes[1] = 0xf4; + hash_bytes[2] = 0x49; + hash_bytes[3] = 0x68; let content_hash = sha256_to_field(hash_bytes); content_hash diff --git a/noir-projects/noir-contracts/contracts/token_portal_content_hash_lib/src/lib.nr b/noir-projects/noir-contracts/contracts/token_portal_content_hash_lib/src/lib.nr index f7789aefcd58..51777093f703 100644 --- a/noir-projects/noir-contracts/contracts/token_portal_content_hash_lib/src/lib.nr +++ b/noir-projects/noir-contracts/contracts/token_portal_content_hash_lib/src/lib.nr @@ -14,12 +14,12 @@ pub fn get_mint_public_content_hash(owner: AztecAddress, amount: Field) -> Field hash_bytes[i + 36] = amount_bytes[i]; } - // Function selector: 0x3e87b9be keccak256('mint_public(bytes32,uint256)') - hash_bytes[0] = 0x3e; - hash_bytes[1] = 0x87; - hash_bytes[2] = 0xb9; - hash_bytes[3] = 0xbe; - + // Function selector: 0x63f44968 keccak256('claim(bytes32,uint256)') + hash_bytes[0] = 0x63; + hash_bytes[1] = 0xf4; + hash_bytes[2] = 0x49; + hash_bytes[3] = 0x68; + let content_hash = sha256_to_field(hash_bytes); content_hash } From 87c5435313eaf23ac28d2f164b137814a4d8157f Mon Sep 17 00:00:00 2001 From: sirasistant Date: Sun, 15 Sep 2024 15:32:37 +0000 Subject: [PATCH 08/12] feat: update selector computation, add to_be_radix comptime --- .../src/core/libraries/ConstantsGen.sol | 12 +++--- noir-projects/aztec-nr/authwit/src/auth.nr | 2 +- .../crates/types/src/abis/event_selector.nr | 8 ++-- .../types/src/abis/function_selector.nr | 20 +++++++--- .../crates/types/src/constants.nr | 12 +++--- .../crates/types/src/hash.nr | 4 +- .../src/transforms/contract_interface.rs | 36 ++++++++++------- .../src/transforms/note_interface.rs | 8 +--- .../src/hir/comptime/interpreter/builtin.rs | 39 ++++++++++++++++++- yarn-project/circuits.js/src/constants.gen.ts | 12 +++--- .../contract_address.test.ts.snap | 2 +- .../foundation/src/abi/event_selector.ts | 5 ++- .../src/abi/function_selector.test.ts | 9 ++++- .../foundation/src/abi/function_selector.ts | 5 ++- .../src/crypto/poseidon/index.test.ts | 8 ---- .../foundation/src/crypto/poseidon/index.ts | 17 ++++---- 16 files changed, 125 insertions(+), 74 deletions(-) diff --git a/l1-contracts/src/core/libraries/ConstantsGen.sol b/l1-contracts/src/core/libraries/ConstantsGen.sol index 96665098c7c3..0c4f2b65a07b 100644 --- a/l1-contracts/src/core/libraries/ConstantsGen.sol +++ b/l1-contracts/src/core/libraries/ConstantsGen.sol @@ -134,17 +134,17 @@ library Constants { uint256 internal constant L2_GAS_PER_NOTE_HASH = 32; uint256 internal constant L2_GAS_PER_NULLIFIER = 64; uint256 internal constant CANONICAL_KEY_REGISTRY_ADDRESS = - 639638883883102015708927376977286479323003429972751272892463029564544935948; + 6823425185167517386380694778823032861295161686691976789058601691508103815523; uint256 internal constant CANONICAL_AUTH_REGISTRY_ADDRESS = - 11468751044532384554787682034362373061633944565658713451304908990088771320309; + 19361441716519463065948254497947932755739298943049449145365332870925554042208; uint256 internal constant DEPLOYER_CONTRACT_ADDRESS = - 14004383401928647177605797127979706176136674598575362510308153951334363095857; + 17119407406465801909352274670277571579675739451008438338071219340964365249977; uint256 internal constant REGISTERER_CONTRACT_ADDRESS = - 4205922897179207838560145152890933359001888854326328392591121836420153952208; + 12405643717676802437578418009978929188439257864607100766293128479227092050857; uint256 internal constant FEE_JUICE_ADDRESS = - 6742376591449076198619058698679514594972390538037174982247442442972596189035; + 12096583827711775893711303288210371301779120762215263550909768879597884314839; uint256 internal constant ROUTER_ADDRESS = - 7268799613082469933251235702514160327341161584122631177360064643484764773587; + 13369993014609648298719593339393818582619449364029983937306132176549332172208; uint256 internal constant AZTEC_ADDRESS_LENGTH = 1; uint256 internal constant GAS_FEES_LENGTH = 2; uint256 internal constant GAS_LENGTH = 2; diff --git a/noir-projects/aztec-nr/authwit/src/auth.nr b/noir-projects/aztec-nr/authwit/src/auth.nr index f651a8edfd70..6dca5f75fd8a 100644 --- a/noir-projects/aztec-nr/authwit/src/auth.nr +++ b/noir-projects/aztec-nr/authwit/src/auth.nr @@ -189,7 +189,7 @@ use dep::aztec::{prelude::Deserialize, context::{PrivateContext, PublicContext, * chain to avoid a case where the same message could be used across multiple chains. */ -global IS_VALID_SELECTOR = 0x47dacd73; // 4 first bytes of poseidon2_hash_bytes("IS_VALID()") +global IS_VALID_SELECTOR = 0x47dacd73; // 4 last bytes of poseidon2_hash_bytes("IS_VALID()") /** * Assert that `on_behalf_of` have authorized the current call with a valid authentication witness diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/event_selector.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/event_selector.nr index f93bb4ce836e..b03f665d227a 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/event_selector.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/event_selector.nr @@ -53,12 +53,10 @@ impl EventSelector { let bytes = signature.as_bytes(); let hash = crate::hash::poseidon2_hash_bytes(bytes); - let mut selector_bytes = [0; SELECTOR_SIZE]; - for i in 0..SELECTOR_SIZE { - selector_bytes[i] = hash[i]; - } + // We choose the last SELECTOR_SIZE bytes of the hash to avoid getting the first byte that is not full + let hash_bytes = hash.to_be_bytes::(); - EventSelector::from_field(field_from_bytes(selector_bytes, true)) + EventSelector::from_field(field_from_bytes(hash_bytes, true)) } pub fn zero() -> Self { diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/function_selector.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/function_selector.nr index 236c749fa5fe..26ae4aeac2c8 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/function_selector.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/function_selector.nr @@ -53,15 +53,25 @@ impl FunctionSelector { let bytes = signature.as_bytes(); let hash = crate::hash::poseidon2_hash_bytes(bytes); - let mut selector_bytes = [0; SELECTOR_SIZE]; - for i in 0..SELECTOR_SIZE { - selector_bytes[i] = hash[i]; - } + // We choose the last SELECTOR_SIZE bytes of the hash to avoid getting the first byte that is not full + let hash_bytes = hash.to_be_bytes::(); - FunctionSelector::from_field(field_from_bytes(selector_bytes, true)) + FunctionSelector::from_field(field_from_bytes(hash_bytes, true)) } pub fn zero() -> Self { Self { inner: 0 } } } + +#[test] +fn test_is_valid_selector() { + let selector = FunctionSelector::from_signature("IS_VALID()"); + assert_eq(selector.to_field(), 0x73cdda47); +} + +#[test] +fn test_long_selector() { + let selector = FunctionSelector::from_signature("foo_and_bar_and_baz_and_foo_bar_baz_and_bar_foo"); + assert_eq(selector.to_field(), 0x7590a997); +} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr index 060b60653525..ed33835c7193 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -191,12 +191,12 @@ global L2_GAS_PER_NOTE_HASH: u32 = 32; global L2_GAS_PER_NULLIFIER: u32 = 64; // CANONICAL CONTRACT ADDRESSES -global CANONICAL_KEY_REGISTRY_ADDRESS = AztecAddress::from_field(0x016a05d4d2bbf343befb44e4989b4cf924e491d1dcecd8e7d062f8dec4a4680c); -global CANONICAL_AUTH_REGISTRY_ADDRESS = AztecAddress::from_field(0x195b1543269c57a03adc69ccefaef8f32d081a95fa07c071d9ba02ea6530b9f5); -global DEPLOYER_CONTRACT_ADDRESS = AztecAddress::from_field(0x1ef6333a829b8820c75d5cb20a60d2025d43654674ad51470029d51b6e78e331); -global REGISTERER_CONTRACT_ADDRESS = AztecAddress::from_field(0x094c77cecb9b849ef9460f5ddcc3b536525fdeff5a7400395e6c2e07acd747d0); -global FEE_JUICE_ADDRESS = AztecAddress::from_field(0x0ee80cc73b879d0b41b286440ed208de53e441fb306578cdf0b20b7c0832b76b); -global ROUTER_ADDRESS = AztecAddress::from_field(0x1011feaa54609098a884322267ec754c637b280c15aa79c3be9f1394e2b29cd3); +global CANONICAL_KEY_REGISTRY_ADDRESS = AztecAddress::from_field(0x0f15ebfaa7e1bb0d1c542c954a8f605909d0fa0a5fd829122bfdec15b4ada163); +global CANONICAL_AUTH_REGISTRY_ADDRESS = AztecAddress::from_field(0x2ace300b02ca5ab0a25052b1e852913a47292096997ca09f758c0e3624e84560); +global DEPLOYER_CONTRACT_ADDRESS = AztecAddress::from_field(0x25d93dc07b5baaf53a98caeae2679df3528cb83e11e2640a57a0a53abbaaadb9); +global REGISTERER_CONTRACT_ADDRESS = AztecAddress::from_field(0x1b6d5873cef5a35f681ab9468527f356c96e09b3c64603aef404ec2ad80aa3a9); +global FEE_JUICE_ADDRESS = AztecAddress::from_field(0x1abe6c7f5c4caf04cbf7556495e08ad9c0a225a5f9d33554ae07285b13c494d7); +global ROUTER_ADDRESS = AztecAddress::from_field(0x1d8f25db3e8faa6a96cb1ecf57876a2ee04581deb3c4f181488ccd817abcbdb0); // LENGTH OF STRUCTS SERIALIZED TO FIELDS global AZTEC_ADDRESS_LENGTH = 1; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr b/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr index 009fe286fec7..2b8832111a2b 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr @@ -278,7 +278,7 @@ pub fn poseidon2_hash_with_separator( } #[no_predicates] -pub fn poseidon2_hash_bytes(inputs: [u8; N]) -> [u8; 32] { +pub fn poseidon2_hash_bytes(inputs: [u8; N]) -> Field { // We manually hash the inputs here, since we cannot express with the type system a constant size inputs array of Math.ceil(N/31) let mut in_len = N / 31; let mut has_padding = false; @@ -304,7 +304,7 @@ pub fn poseidon2_hash_bytes(inputs: [u8; N]) -> [u8; 32] { sponge.absorb(field_from_bytes(current_field, false)); } - sponge.squeeze().to_le_bytes::<32>() + sponge.squeeze() } #[test] diff --git a/noir/noir-repo/aztec_macros/src/transforms/contract_interface.rs b/noir/noir-repo/aztec_macros/src/transforms/contract_interface.rs index 3440690c84d2..522489daa1b7 100644 --- a/noir/noir-repo/aztec_macros/src/transforms/contract_interface.rs +++ b/noir/noir-repo/aztec_macros/src/transforms/contract_interface.rs @@ -298,11 +298,7 @@ fn compute_fn_signature_hash(fn_name: &str, parameters: &[Type]) -> u32 { parameters.iter().map(signature_of_type).collect::>().join(",") ); - let result = poseidon2_hash_bytes(signature.as_bytes().to_vec()); - // Take the first 4 bytes of the hash and convert them to an integer - // If you change the following value you have to change NUM_BYTES_PER_NOTE_TYPE_ID in l1_note_payload.ts as well - let num_bytes_per_note_type_id = 4; - u32::from_be_bytes(result[0..num_bytes_per_note_type_id].try_into().unwrap()) + hash_to_selector(&signature) } // Updates the function signatures in the contract interface with the actual ones, replacing the placeholder. @@ -429,7 +425,7 @@ pub fn update_fn_signatures_in_contract_interface( Ok(()) } -pub(crate) fn poseidon2_hash_bytes(inputs: Vec) -> Vec { +fn poseidon2_hash_bytes(inputs: Vec) -> FieldElement { let fields: Vec<_> = inputs .into_iter() .chunks(31) @@ -442,19 +438,31 @@ pub(crate) fn poseidon2_hash_bytes(inputs: Vec) -> Vec { FieldElement::from_be_bytes_reduce(&chunk_as_vec) }) .collect(); - let mut hash_bytes = poseidon_hash(&fields).expect("Poseidon hash failed").to_be_bytes(); - hash_bytes.reverse(); - hash_bytes + + poseidon_hash(&fields).expect("Poseidon hash failed") +} + +pub(crate) fn hash_to_selector(inputs: &str) -> u32 { + let hash = poseidon2_hash_bytes(inputs.as_bytes().to_vec()).to_be_bytes(); + // Take the last 4 bytes of the hash and convert them to an integer + // If you change the following value you have to change NUM_BYTES_PER_NOTE_TYPE_ID in l1_note_payload.ts as well + let num_bytes_per_note_type_id = 4; + u32::from_be_bytes(hash[(32 - num_bytes_per_note_type_id)..32].try_into().unwrap()) } #[cfg(test)] mod test { - use crate::transforms::contract_interface::poseidon2_hash_bytes; + use crate::transforms::contract_interface::hash_to_selector; + + #[test] + fn test_selector_is_valid() { + let selector = hash_to_selector("IS_VALID()"); + assert_eq!(hex::encode(&selector.to_be_bytes()), "73cdda47"); + } #[test] - fn test_poseidon2_hash_bytes() { - let mut hash = poseidon2_hash_bytes("IS_VALID()".as_bytes().to_vec()); - hash.truncate(4); - assert_eq!(hex::encode(&hash), "47dacd73"); + fn test_long_selector() { + let selector = hash_to_selector("foo_and_bar_and_baz_and_foo_bar_baz_and_bar_foo"); + assert_eq!(hex::encode(&selector.to_be_bytes()), "7590a997"); } } diff --git a/noir/noir-repo/aztec_macros/src/transforms/note_interface.rs b/noir/noir-repo/aztec_macros/src/transforms/note_interface.rs index b2a8d70626d0..58e59d16102b 100644 --- a/noir/noir-repo/aztec_macros/src/transforms/note_interface.rs +++ b/noir/noir-repo/aztec_macros/src/transforms/note_interface.rs @@ -26,7 +26,7 @@ use crate::{ }, }; -use super::contract_interface::poseidon2_hash_bytes; +use super::contract_interface::hash_to_selector; // Automatic implementation of most of the methods in the NoteInterface trait, guiding the user with meaningful error messages in case some // methods must be implemented manually. @@ -751,11 +751,7 @@ fn generate_note_deserialize_content_source( // Utility function to generate the note type id as a Field fn compute_note_type_id(note_type: &str) -> u32 { // TODO(#4519) Improve automatic note id generation and assignment - let result = poseidon2_hash_bytes(note_type.as_bytes().to_vec()); - // Take the first 4 bytes of the hash and convert them to an integer - // If you change the following value you have to change NUM_BYTES_PER_NOTE_TYPE_ID in l1_note_payload.ts as well - let num_bytes_per_note_type_id = 4; - u32::from_be_bytes(result[0..num_bytes_per_note_type_id].try_into().unwrap()) + hash_to_selector(¬e_type) } pub fn inject_note_exports( diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index 8ca661127665..695f6eb7d165 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -169,6 +169,7 @@ impl<'local, 'context> Interpreter<'local, 'context> { "struct_def_name" => struct_def_name(interner, arguments, location), "struct_def_set_fields" => struct_def_set_fields(interner, arguments, location), "to_le_radix" => to_le_radix(arguments, return_type, location), + "to_be_radix" => to_be_radix(arguments, return_type, location), "trait_constraint_eq" => trait_constraint_eq(arguments, location), "trait_constraint_hash" => trait_constraint_hash(arguments, location), "trait_def_as_trait_constraint" => { @@ -770,7 +771,7 @@ fn to_le_radix( }; // Decompose the integer into its radix digits in little endian form. - let decomposed_integer = compute_to_radix(value, radix); + let decomposed_integer = compute_to_radix_le(value, radix); let decomposed_integer = vecmap(0..limb_count as usize, |i| match decomposed_integer.get(i) { Some(digit) => Value::U8(*digit), None => Value::U8(0), @@ -781,7 +782,41 @@ fn to_le_radix( )) } -fn compute_to_radix(field: FieldElement, radix: u32) -> Vec { +fn to_be_radix( + arguments: Vec<(Value, Location)>, + return_type: Type, + location: Location, +) -> IResult { + let (value, radix) = check_two_arguments(arguments, location)?; + + let value = get_field(value)?; + let radix = get_u32(radix)?; + let limb_count = if let Type::Array(length, _) = return_type { + if let Type::Constant(limb_count) = *length { + limb_count + } else { + return Err(InterpreterError::TypeAnnotationsNeededForMethodCall { location }); + } + } else { + return Err(InterpreterError::TypeAnnotationsNeededForMethodCall { location }); + }; + + // Decompose the integer into its radix digits in little endian form. + let decomposed_integer = compute_to_radix_le(value, radix); + + // Iterate in reverse to get the big endian result. + let decomposed_integer = + vecmap((0..limb_count as usize).rev(), |i| match decomposed_integer.get(i) { + Some(digit) => Value::U8(*digit), + None => Value::U8(0), + }); + Ok(Value::Array( + decomposed_integer.into(), + Type::Integer(Signedness::Unsigned, IntegerBitSize::Eight), + )) +} + +fn compute_to_radix_le(field: FieldElement, radix: u32) -> Vec { let bit_size = u32::BITS - (radix - 1).leading_zeros(); let radix_big = BigUint::from(radix); assert_eq!(BigUint::from(2u128).pow(bit_size), radix_big, "ICE: Radix must be a power of 2"); diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index 312d771ef96f..2f5baddd9ec9 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -119,14 +119,14 @@ export const L2_GAS_PER_LOG_BYTE = 4; export const L2_GAS_PER_NOTE_HASH = 32; export const L2_GAS_PER_NULLIFIER = 64; export const CANONICAL_KEY_REGISTRY_ADDRESS = - 639638883883102015708927376977286479323003429972751272892463029564544935948n; + 6823425185167517386380694778823032861295161686691976789058601691508103815523n; export const CANONICAL_AUTH_REGISTRY_ADDRESS = - 11468751044532384554787682034362373061633944565658713451304908990088771320309n; -export const DEPLOYER_CONTRACT_ADDRESS = 14004383401928647177605797127979706176136674598575362510308153951334363095857n; + 19361441716519463065948254497947932755739298943049449145365332870925554042208n; +export const DEPLOYER_CONTRACT_ADDRESS = 17119407406465801909352274670277571579675739451008438338071219340964365249977n; export const REGISTERER_CONTRACT_ADDRESS = - 4205922897179207838560145152890933359001888854326328392591121836420153952208n; -export const FEE_JUICE_ADDRESS = 6742376591449076198619058698679514594972390538037174982247442442972596189035n; -export const ROUTER_ADDRESS = 7268799613082469933251235702514160327341161584122631177360064643484764773587n; + 12405643717676802437578418009978929188439257864607100766293128479227092050857n; +export const FEE_JUICE_ADDRESS = 12096583827711775893711303288210371301779120762215263550909768879597884314839n; +export const ROUTER_ADDRESS = 13369993014609648298719593339393818582619449364029983937306132176549332172208n; export const AZTEC_ADDRESS_LENGTH = 1; export const GAS_FEES_LENGTH = 2; export const GAS_LENGTH = 2; diff --git a/yarn-project/circuits.js/src/contract/__snapshots__/contract_address.test.ts.snap b/yarn-project/circuits.js/src/contract/__snapshots__/contract_address.test.ts.snap index b0374a11e52e..a8a7d2f571b2 100644 --- a/yarn-project/circuits.js/src/contract/__snapshots__/contract_address.test.ts.snap +++ b/yarn-project/circuits.js/src/contract/__snapshots__/contract_address.test.ts.snap @@ -2,7 +2,7 @@ exports[`ContractAddress computeContractAddressFromInstance 1`] = `"0x0ea56faa48431d99cc2d073463d1b718c11174bb551a3d1d6f296b0096089dbb"`; -exports[`ContractAddress computeInitializationHash 1`] = `Fr<0x2f11768c825fac132c632372d7c6d657fd471a9f9db05a153c6927a24863ec53>`; +exports[`ContractAddress computeInitializationHash 1`] = `Fr<0x0a79e35b159f2755e79e7ac21aed31964a6446d279670b499595da24c66144ff>`; exports[`ContractAddress computePartialAddress 1`] = `Fr<0x2521255ebd14e8e3e7cd1e8a27d26a902ee9e74905b711950d580e826ba9010d>`; diff --git a/yarn-project/foundation/src/abi/event_selector.ts b/yarn-project/foundation/src/abi/event_selector.ts index eb5d53e34a18..f7c8ae06d99f 100644 --- a/yarn-project/foundation/src/abi/event_selector.ts +++ b/yarn-project/foundation/src/abi/event_selector.ts @@ -44,7 +44,10 @@ export class EventSelector extends Selector { if (/\s/.test(signature)) { throw new Error('Signature cannot contain whitespace'); } - return EventSelector.fromBuffer(poseidon2HashBytes(Buffer.from(signature)).subarray(0, Selector.SIZE)); + const hash = poseidon2HashBytes(Buffer.from(signature)); + // We take the last Selector.SIZE big endian bytes + const bytes = hash.toBuffer().slice(-Selector.SIZE); + return EventSelector.fromBuffer(bytes); } /** diff --git a/yarn-project/foundation/src/abi/function_selector.test.ts b/yarn-project/foundation/src/abi/function_selector.test.ts index 6cb6155e922a..a3f6d055354f 100644 --- a/yarn-project/foundation/src/abi/function_selector.test.ts +++ b/yarn-project/foundation/src/abi/function_selector.test.ts @@ -23,7 +23,12 @@ describe('FunctionSelector', () => { }); it('computes a function selector from signature', () => { - const res = FunctionSelector.fromSignature('transfer(address,uint256)'); - expect(res).toMatchSnapshot(); + const res = FunctionSelector.fromSignature('IS_VALID()'); + expect(res.toBuffer().toString('hex')).toMatchSnapshot(); + }); + + it('computes a function selector from a long string', () => { + const res = FunctionSelector.fromSignature('foo_and_bar_and_baz_and_foo_bar_baz_and_bar_foo'); + expect(res.toBuffer().toString('hex')).toMatchSnapshot(); }); }); diff --git a/yarn-project/foundation/src/abi/function_selector.ts b/yarn-project/foundation/src/abi/function_selector.ts index 34af83270f7a..7641234f9ab4 100644 --- a/yarn-project/foundation/src/abi/function_selector.ts +++ b/yarn-project/foundation/src/abi/function_selector.ts @@ -73,7 +73,10 @@ export class FunctionSelector extends Selector { if (/\s/.test(signature)) { throw new Error('Signature cannot contain whitespace'); } - return FunctionSelector.fromBuffer(poseidon2HashBytes(Buffer.from(signature)).subarray(0, Selector.SIZE)); + const hash = poseidon2HashBytes(Buffer.from(signature)); + // We take the last Selector.SIZE big endian bytes + const bytes = hash.toBuffer().slice(-Selector.SIZE); + return FunctionSelector.fromBuffer(bytes); } /** diff --git a/yarn-project/foundation/src/crypto/poseidon/index.test.ts b/yarn-project/foundation/src/crypto/poseidon/index.test.ts index 4e0f368ea153..2a28ce1d83a2 100644 --- a/yarn-project/foundation/src/crypto/poseidon/index.test.ts +++ b/yarn-project/foundation/src/crypto/poseidon/index.test.ts @@ -22,11 +22,3 @@ describe('poseidon2Permutation', () => { ]); }); }); - -describe('poseidon2HashBytes', () => { - it('test', () => { - const buf = Buffer.from('IS_VALID()'); - const hash = poseidon2HashBytes(buf); - expect(hash.slice(0, 4).toString('hex')).toEqual('47dacd73'); - }); -}); diff --git a/yarn-project/foundation/src/crypto/poseidon/index.ts b/yarn-project/foundation/src/crypto/poseidon/index.ts index 3017f3aa9ff5..1e1274ec7815 100644 --- a/yarn-project/foundation/src/crypto/poseidon/index.ts +++ b/yarn-project/foundation/src/crypto/poseidon/index.ts @@ -58,7 +58,7 @@ export function poseidon2Permutation(input: Fieldable[]): Fr[] { return res.map(o => Fr.fromBuffer(Buffer.from(o.toBuffer()))); } -export function poseidon2HashBytes(input: Buffer): Buffer { +export function poseidon2HashBytes(input: Buffer): Fr { const inputFields = []; for (let i = 0; i < input.length; i += 31) { const fieldBytes = Buffer.alloc(32, 0); @@ -69,12 +69,13 @@ export function poseidon2HashBytes(input: Buffer): Buffer { inputFields.push(Fr.fromBuffer(fieldBytes)); } - const resultBytes = Buffer.from( - BarretenbergSync.getSingleton() - .poseidon2Hash( - inputFields.map(i => new FrBarretenberg(i.toBuffer())), // TODO(#4189): remove this stupid conversion - ) - .toBuffer(), + return Fr.fromBuffer( + Buffer.from( + BarretenbergSync.getSingleton() + .poseidon2Hash( + inputFields.map(i => new FrBarretenberg(i.toBuffer())), // TODO(#4189): remove this stupid conversion + ) + .toBuffer(), + ), ); - return resultBytes.reverse(); } From 591aa3320702247fca023f536702a2117a9acc62 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Sun, 15 Sep 2024 16:09:46 +0000 Subject: [PATCH 09/12] fixes --- .../token_portal_content_hash_lib/src/lib.nr | 12 ++++++------ .../aztec_macros/src/transforms/note_interface.rs | 2 +- .../abi/__snapshots__/function_selector.test.ts.snap | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/noir-projects/noir-contracts/contracts/token_portal_content_hash_lib/src/lib.nr b/noir-projects/noir-contracts/contracts/token_portal_content_hash_lib/src/lib.nr index 51777093f703..f7789aefcd58 100644 --- a/noir-projects/noir-contracts/contracts/token_portal_content_hash_lib/src/lib.nr +++ b/noir-projects/noir-contracts/contracts/token_portal_content_hash_lib/src/lib.nr @@ -14,12 +14,12 @@ pub fn get_mint_public_content_hash(owner: AztecAddress, amount: Field) -> Field hash_bytes[i + 36] = amount_bytes[i]; } - // Function selector: 0x63f44968 keccak256('claim(bytes32,uint256)') - hash_bytes[0] = 0x63; - hash_bytes[1] = 0xf4; - hash_bytes[2] = 0x49; - hash_bytes[3] = 0x68; - + // Function selector: 0x3e87b9be keccak256('mint_public(bytes32,uint256)') + hash_bytes[0] = 0x3e; + hash_bytes[1] = 0x87; + hash_bytes[2] = 0xb9; + hash_bytes[3] = 0xbe; + let content_hash = sha256_to_field(hash_bytes); content_hash } diff --git a/noir/noir-repo/aztec_macros/src/transforms/note_interface.rs b/noir/noir-repo/aztec_macros/src/transforms/note_interface.rs index 58e59d16102b..b5d04e87e0a7 100644 --- a/noir/noir-repo/aztec_macros/src/transforms/note_interface.rs +++ b/noir/noir-repo/aztec_macros/src/transforms/note_interface.rs @@ -751,7 +751,7 @@ fn generate_note_deserialize_content_source( // Utility function to generate the note type id as a Field fn compute_note_type_id(note_type: &str) -> u32 { // TODO(#4519) Improve automatic note id generation and assignment - hash_to_selector(¬e_type) + hash_to_selector(note_type) } pub fn inject_note_exports( diff --git a/yarn-project/foundation/src/abi/__snapshots__/function_selector.test.ts.snap b/yarn-project/foundation/src/abi/__snapshots__/function_selector.test.ts.snap index 0336e9c4e93c..c59cdc3f81fc 100644 --- a/yarn-project/foundation/src/abi/__snapshots__/function_selector.test.ts.snap +++ b/yarn-project/foundation/src/abi/__snapshots__/function_selector.test.ts.snap @@ -1,3 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`FunctionSelector computes a function selector from signature 1`] = `Selector<0xa9059cbb>`; +exports[`FunctionSelector computes a function selector from a long string 1`] = `"7590a997"`; + +exports[`FunctionSelector computes a function selector from signature 1`] = `"73cdda47"`; From d1a3df9d82dfe33ca98198d3fe7f19cb4ea737f9 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Sun, 15 Sep 2024 17:52:33 +0000 Subject: [PATCH 10/12] fix deploy --- noir-projects/aztec-nr/aztec/src/deploy.nr | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/noir-projects/aztec-nr/aztec/src/deploy.nr b/noir-projects/aztec-nr/aztec/src/deploy.nr index 947a0eb85d8f..d916b384f809 100644 --- a/noir-projects/aztec-nr/aztec/src/deploy.nr +++ b/noir-projects/aztec-nr/aztec/src/deploy.nr @@ -25,7 +25,9 @@ pub fn deploy_contract(context: &mut PrivateContext, target: AztecAddress) { let _call_result = context.call_private_function( DEPLOYER_CONTRACT_ADDRESS, - FunctionSelector::from_field(0x7ebd3690), + comptime { + FunctionSelector::from_signature("deploy(Field,(Field),Field,(Field),bool)") + }, serialized_args ); } From c3bfef9280fab3b9f26ca919ba0198a18469a912 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Sun, 15 Sep 2024 19:48:00 +0000 Subject: [PATCH 11/12] fixes --- .../aztec-nr/aztec/src/encrypted_logs/incoming_body.nr | 2 +- yarn-project/end-to-end/src/e2e_event_logs.test.ts | 2 +- yarn-project/foundation/src/crypto/poseidon/index.test.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/encrypted_logs/incoming_body.nr b/noir-projects/aztec-nr/aztec/src/encrypted_logs/incoming_body.nr index 2ba0ec2a8b76..4ba224c27611 100644 --- a/noir-projects/aztec-nr/aztec/src/encrypted_logs/incoming_body.nr +++ b/noir-projects/aztec-nr/aztec/src/encrypted_logs/incoming_body.nr @@ -273,7 +273,7 @@ mod test { // The following value was generated by `encrypted_event_log_incoming_body.test.ts` // --> Run the test with AZTEC_GENERATE_TEST_DATA=1 flag to update test data. let event_body_ciphertext_from_typescript = [ - 226, 240, 253, 6, 28, 52, 19, 131, 33, 132, 178, 212, 245, 62, 14, 190, 147, 228, 160, 190, 146, 61, 95, 203, 124, 153, 68, 168, 17, 150, 92, 0, 99, 214, 85, 64, 191, 78, 157, 131, 149, 96, 236, 253, 96, 172, 157, 30, 185, 29, 14, 152, 216, 130, 219, 151, 80, 185, 43, 223, 167, 8, 89, 189, 88, 188, 101, 137, 255, 136, 84, 252, 79, 18, 52, 3, 110, 54, 54, 206, 244, 209, 246, 226, 207, 247, 143, 253, 211, 75, 160, 224, 172, 41, 45, 7, 208, 137, 90, 56, 59, 4, 234, 48, 53, 23, 130, 230, 49, 249, 142, 243, 170, 72, 183, 242, 49, 124, 46, 52, 198, 75, 55, 102, 56, 89, 254, 67, 59, 157, 249, 120, 184, 67, 154, 16, 148, 227, 93, 37, 120, 199, 93, 166, 80, 127, 173, 52, 80, 135, 87, 1, 168, 164, 51, 48, 126, 120, 47, 102, 211, 227, 234, 170, 208, 99, 111, 198, 170, 226, 156, 244, 241, 174, 206, 30 + 226, 240, 253, 6, 28, 52, 19, 131, 33, 132, 178, 212, 245, 62, 14, 190, 147, 228, 160, 190, 146, 61, 95, 203, 124, 153, 68, 168, 17, 150, 92, 0, 99, 214, 85, 64, 191, 78, 157, 131, 149, 96, 236, 253, 96, 172, 157, 30, 201, 247, 40, 80, 60, 188, 158, 251, 242, 103, 197, 79, 165, 195, 10, 160, 255, 35, 167, 152, 25, 233, 77, 145, 214, 243, 210, 119, 0, 20, 29, 95, 15, 63, 33, 190, 184, 67, 254, 96, 128, 243, 220, 228, 201, 130, 86, 163, 52, 127, 111, 10, 212, 7, 160, 16, 87, 13, 39, 11, 5, 1, 164, 65, 8, 56, 82, 245, 13, 68, 176, 90, 100, 69, 243, 78, 117, 188, 221, 34, 178, 31, 155, 89, 143, 176, 129, 118, 36, 236, 64, 179, 52, 239, 184, 51, 51, 199, 221, 49, 81, 197, 17, 199, 192, 99, 49, 168, 157, 164, 190, 33, 240, 182, 214, 173, 7, 156, 102, 95, 65, 217, 225, 123, 42, 21, 124, 144 ]; assert_eq(event_body_ciphertext_from_typescript.len(), ciphertext.len()); diff --git a/yarn-project/end-to-end/src/e2e_event_logs.test.ts b/yarn-project/end-to-end/src/e2e_event_logs.test.ts index 576a8f2da170..d1c98b890548 100644 --- a/yarn-project/end-to-end/src/e2e_event_logs.test.ts +++ b/yarn-project/end-to-end/src/e2e_event_logs.test.ts @@ -65,7 +65,7 @@ describe('Logs', () => { expect(decryptedLog0?.payload.contractAddress).toStrictEqual(testLogContract.address); expect(decryptedLog0?.payload.randomness).toStrictEqual(randomness[0]); expect(decryptedLog0?.payload.eventTypeId).toStrictEqual( - EventSelector.fromField(new Fr(0x00000000000000000000000000000000000000000000000000000000aa533f60)), + EventSelector.fromField(new Fr(0x00000000000000000000000000000000000000000000000000000000d45c041b)), ); // We decode our event into the event type diff --git a/yarn-project/foundation/src/crypto/poseidon/index.test.ts b/yarn-project/foundation/src/crypto/poseidon/index.test.ts index 2a28ce1d83a2..a12998a12131 100644 --- a/yarn-project/foundation/src/crypto/poseidon/index.test.ts +++ b/yarn-project/foundation/src/crypto/poseidon/index.test.ts @@ -1,5 +1,5 @@ import { Fr } from '../../fields/fields.js'; -import { poseidon2HashBytes, poseidon2Permutation } from './index.js'; +import { poseidon2Permutation } from './index.js'; describe('poseidon2Permutation', () => { it('test vectors from cpp should match', () => { From d5d82d32655f5767a39d66781d7900a5a040d6a4 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Sun, 15 Sep 2024 20:22:47 +0000 Subject: [PATCH 12/12] add sleep for race condition --- yarn-project/end-to-end/src/e2e_block_building.test.ts | 2 ++ yarn-project/end-to-end/src/e2e_event_logs.test.ts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/yarn-project/end-to-end/src/e2e_block_building.test.ts b/yarn-project/end-to-end/src/e2e_block_building.test.ts index cb4655f55619..f19e5b05136a 100644 --- a/yarn-project/end-to-end/src/e2e_block_building.test.ts +++ b/yarn-project/end-to-end/src/e2e_block_building.test.ts @@ -12,6 +12,7 @@ import { type Wallet, deriveKeys, retryUntil, + sleep, } from '@aztec/aztec.js'; import { times } from '@aztec/foundation/collection'; import { poseidon2HashWithSeparator } from '@aztec/foundation/crypto'; @@ -333,6 +334,7 @@ describe('e2e_block_building', () => { minTxsPerBlock: 0, skipProtocolContracts: true, })); + await sleep(1000); const account = getSchnorrAccount(pxe, Fr.random(), Fq.random(), Fr.random()); await account.waitSetup(); diff --git a/yarn-project/end-to-end/src/e2e_event_logs.test.ts b/yarn-project/end-to-end/src/e2e_event_logs.test.ts index d1c98b890548..416f2af3ce26 100644 --- a/yarn-project/end-to-end/src/e2e_event_logs.test.ts +++ b/yarn-project/end-to-end/src/e2e_event_logs.test.ts @@ -89,7 +89,7 @@ describe('Logs', () => { expect(decryptedLog1?.payload.contractAddress).toStrictEqual(testLogContract.address); expect(decryptedLog1?.payload.randomness).toStrictEqual(randomness[1]); expect(decryptedLog1?.payload.eventTypeId).toStrictEqual( - EventSelector.fromField(new Fr(0x00000000000000000000000000000000000000000000000000000000d1be0447)), + EventSelector.fromField(new Fr(0x00000000000000000000000000000000000000000000000000000000031b1167)), ); // We check our second event, which is a different type