From 8498de32ebd4a121ba7d07660c9cc791c673e0b3 Mon Sep 17 00:00:00 2001 From: Aztec Bot <49558828+AztecBot@users.noreply.github.com> Date: Sun, 1 Sep 2024 17:21:39 -0400 Subject: [PATCH] feat: Sync from noir (#8237) Automated pull of development from the [noir](https://github.com/noir-lang/noir) programming language, a dependency of Aztec. BEGIN_COMMIT_OVERRIDE feat: add `Type::as_string` (https://github.com/noir-lang/noir/pull/5871) feat: add `FunctionDef::has_named_attribute` (https://github.com/noir-lang/noir/pull/5870) chore: introduce the Visitor pattern (https://github.com/noir-lang/noir/pull/5868) fix(nargo): Resolve Brillig assertion payloads (https://github.com/noir-lang/noir/pull/5872) feat(perf): Simplify poseidon2 cache zero-pad (https://github.com/noir-lang/noir/pull/5869) feat: Sync from aztec-packages (https://github.com/noir-lang/noir/pull/5790) feat: add `Expr::resolve` and `TypedExpr::as_function_definition` (https://github.com/noir-lang/noir/pull/5859) feat: LSP signature help for assert and assert_eq (https://github.com/noir-lang/noir/pull/5862) fix(sha256): Add extra checks against message size when constructing msg blocks (https://github.com/noir-lang/noir/pull/5861) feat: show backtrace on comptime assertion failures (https://github.com/noir-lang/noir/pull/5842) feat: add `Expr::as_assert` (https://github.com/noir-lang/noir/pull/5857) chore: underconstrained check in parallel (https://github.com/noir-lang/noir/pull/5848) feat(meta): Comptime keccak (https://github.com/noir-lang/noir/pull/5854) feat(optimization): Avoid merging identical (by ID) arrays (https://github.com/noir-lang/noir/pull/5853) feat: add `FunctionDef::body` (https://github.com/noir-lang/noir/pull/5825) fix(sha256): Fix upper bound when building msg block and delay final block compression under certain cases (https://github.com/noir-lang/noir/pull/5838) feat: remove unnecessary copying of vector size during reversal (https://github.com/noir-lang/noir/pull/5852) chore: Add missing cases to arithmetic generics (https://github.com/noir-lang/noir/pull/5841) feat: warn on unused imports (https://github.com/noir-lang/noir/pull/5847) chore: add documentation to `to_be_bytes`, etc. (https://github.com/noir-lang/noir/pull/5843) feat: simplify constant calls to `poseidon2_permutation`, `schnorr_verify` and `embedded_curve_add` (https://github.com/noir-lang/noir/pull/5140) chore: don't require empty `Prover.toml` for programs with zero arguments but a return value (https://github.com/noir-lang/noir/pull/5845) fix!: Check unused generics are bound (https://github.com/noir-lang/noir/pull/5840) chore(perf): Simplify poseidon2 algorithm (https://github.com/noir-lang/noir/pull/5811) chore: redo typo PR by nnsW3 (https://github.com/noir-lang/noir/pull/5834) fix(sha256): Perform compression per block and utilize ROM instead of RAM when setting up the message block (https://github.com/noir-lang/noir/pull/5760) chore(perf): Update to stdlib keccak for reduced Brillig code size (https://github.com/noir-lang/noir/pull/5827) END_COMMIT_OVERRIDE --------- Co-authored-by: Tom French Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com> Co-authored-by: Maxim Vezenov --- authwit/src/auth.nr | 136 +++++++++--------- .../shared_mutable/shared_mutable.nr | 1 + aztec/src/test/helpers/test_environment.nr | 8 +- 3 files changed, 73 insertions(+), 72 deletions(-) diff --git a/authwit/src/auth.nr b/authwit/src/auth.nr index aff8007f..7e8f33c0 100644 --- a/authwit/src/auth.nr +++ b/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`. @@ -172,31 +172,31 @@ 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? * 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 collision 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()") -/** +/** * 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/aztec/src/state_vars/shared_mutable/shared_mutable.nr b/aztec/src/state_vars/shared_mutable/shared_mutable.nr index 93f6e076..e220c014 100644 --- a/aztec/src/state_vars/shared_mutable/shared_mutable.nr +++ b/aztec/src/state_vars/shared_mutable/shared_mutable.nr @@ -123,6 +123,7 @@ impl SharedMutable SharedMutable where T: ToField + FromField + Eq { + pub fn schedule_value_change(self, new_value: T) { let mut value_change = self.read_value_change(); let delay_change = self.read_delay_change(); diff --git a/aztec/src/test/helpers/test_environment.nr b/aztec/src/test/helpers/test_environment.nr index b9c578f0..13b41096 100644 --- a/aztec/src/test/helpers/test_environment.nr +++ b/aztec/src/test/helpers/test_environment.nr @@ -132,7 +132,7 @@ impl TestEnvironment { PackedReturns::new(public_inputs.returns_hash).unpack_into() } - fn call_private_void( + fn call_private_void( _self: Self, call_interface: C ) where C: CallInterface { @@ -154,7 +154,7 @@ impl TestEnvironment { PackedReturns::new(public_inputs.returns_hash).assert_empty(); } - fn call_public( + fn call_public( _self: Self, call_interface: C ) -> T where C: CallInterface { @@ -179,7 +179,7 @@ impl TestEnvironment { result } - fn assert_public_call_fails( + fn assert_public_call_fails( _self: Self, call_interface: C ) where C: CallInterface { @@ -190,7 +190,7 @@ impl TestEnvironment { ); } - fn assert_private_call_fails( + fn assert_private_call_fails( _self: Self, call_interface: C ) where C: CallInterface {