Skip to content

Commit

Permalink
chore: improve authwit comments/docs (#7180)
Browse files Browse the repository at this point in the history
Extending comments related to the authwit sections of the code to make
it more clear what is going on, and hopefully making it understandable
without leaving the code.

Alters the function names slightly to get rid of the `outer_hash` since
it is only a name we really need internally and can then use
`message_hash` for the actual value.

---------

Co-authored-by: Rahul Kothari <rahul.kothari.201@gmail.com>
  • Loading branch information
LHerskind and rahul-kothari authored Jun 26, 2024
1 parent a8c666e commit 051ab9e
Show file tree
Hide file tree
Showing 10 changed files with 318 additions and 34 deletions.
9 changes: 4 additions & 5 deletions docs/docs/guides/js_apps/authwit.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ These are all the libraries you might need for using authwits in Aztec.js:
import {
computeAuthWitMessageHash,
computeInnerAuthWitHash,
computeOuterAuthWitHash,
} from "@aztec/aztec.js";
```

Expand Down Expand Up @@ -63,9 +62,9 @@ You can hash your own authwit message by creating an inner hash with the data, l

#include_code compute_inner_authwit_hash yarn-project/end-to-end/src/e2e_authwit.test.ts typescript

Then create the outer hash by hashing the inner hash with the authwit receiver address, chainId, and version:
Then create the message hash by hashing the inner hash with the authwit receiver address, chainId, and version:

#include_code compute_outer_authwit_hash yarn-project/end-to-end/src/e2e_authwit.test.ts typescript
#include_code compute_arbitrary_authwit_hash yarn-project/end-to-end/src/e2e_authwit.test.ts typescript

## Create the authwit

Expand All @@ -89,9 +88,9 @@ In this example,
- `wallets[1]` is the authwit reciever and caller of the function
- `action` was [defined previously](#define-the-action)

If you created an artbitrary message, you can create the authwit by replacing these params with the outer hash:
If you created an arbitrary message, you can create the authwit by replacing these params with the outer hash:

#include_code compute_outer_authwit_hash yarn-project/end-to-end/src/e2e_authwit.test.ts typescript
#include_code compute_arbitrary_authwit_hash yarn-project/end-to-end/src/e2e_authwit.test.ts typescript

Then add it to the wallet of the authwit receiver (the caller of the function):

Expand Down
4 changes: 2 additions & 2 deletions docs/docs/guides/smart_contracts/writing_contracts/authwit.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ For our purposes here (not building a wallet), the most important part of the li

### General utilities

The primary general utility is the `compute_call_authwit_hash` function which computes the action hash from its components. This is useful for when you need to generate a hash that is not for the current call, such as when you want to update a public approval state value that is later used for [authentication in public](#updating-approval-state-in-noir). You can view the implementation of this function [here](https://github.com/AztecProtocol/aztec-packages/blob/master/noir-projects/aztec-nr/authwit/src/auth.nr).
The primary general utility is the `compute_authwit_message_hash_from_call` function which computes the action hash from its components. This is useful for when you need to generate a hash that is not for the current call, such as when you want to update a public approval state value that is later used for [authentication in public](#updating-approval-state-in-noir). You can view the implementation of this function [here](https://github.com/AztecProtocol/aztec-packages/blob/master/noir-projects/aztec-nr/authwit/src/auth.nr).

#### TypeScript utilities

Expand Down Expand Up @@ -174,7 +174,7 @@ In the snippet below, this is done as a separate contract call, but can also be

We have cases where we need a non-wallet contract to approve an action to be executed by another contract. One of the cases could be when making more complex defi where funds are passed along. When doing so, we need the intermediate contracts to support approving of actions on their behalf.

This is fairly straight forward to do using the `auth` library which include logic for updating values in the public auth registry. Namely, you can prepare the `message_hash` using `compute_call_authwit_hash` and then simply feed it into the `set_authorized` function (both are in `auth` library) to update the value.
This is fairly straight forward to do using the `auth` library which includes logic for updating values in the public auth registry. Namely, you can prepare the `message_hash` using `compute_authwit_message_hash_from_call` and then simply feed it into the `set_authorized` function (both are in `auth` library) to update the value.

When another contract later is consuming the authwit using `assert_current_call_valid_authwit_public` it will be calling the registry, and spend that authwit.

Expand Down
2 changes: 1 addition & 1 deletion docs/docs/migration_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ const innerHash = computeInnerAuthWitHash([Fr.ZERO, functionSelector.toField(),
- new Fr(this.version),
- innerHash,
-);
+const outerHash = computeAuthWitMessageHash(
+const messageHash = computeAuthWitMessageHash(
+ { consumer: this.dappEntrypointAddress, innerHash },
+ { chainId: new Fr(this.chainId), version: new Fr(this.version) },
+);
Expand Down
29 changes: 27 additions & 2 deletions noir-projects/aztec-nr/authwit/src/account.nr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use dep::aztec::context::{PrivateContext, PublicContext};
use dep::aztec::protocol_types::{address::AztecAddress, abis::function_selector::FunctionSelector, hash::pedersen_hash};

use crate::entrypoint::{app::AppPayload, fee::FeePayload};
use crate::auth::{IS_VALID_SELECTOR, compute_outer_authwit_hash};
use crate::auth::{IS_VALID_SELECTOR, compute_authwit_message_hash};

struct AccountActions<Context> {
context: Context,
Expand All @@ -15,7 +15,22 @@ impl<Context> AccountActions<Context> {
}
}

/**
* An implementation of the Account Action struct for the private context.
*
* Implements logic to verify authorization and execute payloads.
*/
impl AccountActions<&mut PrivateContext> {

/**
* Verifies that the `app_hash` and `fee_hash` are authorized and then executes them.
*
* Executes the `fee_payload` and `app_payload` in sequence.
* Will execute the `fee_payload` as part of the setup, and then enter the app phase.
*
* @param app_payload The payload that contains the calls to be executed in the app phase.
* @param fee_payload The payload that contains the calls to be executed in the setup phase.
*/
// docs:start:entrypoint
pub fn entrypoint(self, app_payload: AppPayload, fee_payload: FeePayload) {
let valid_fn = self.is_valid_impl;
Expand All @@ -31,12 +46,22 @@ impl AccountActions<&mut PrivateContext> {
}
// docs:end:entrypoint

/**
* Verifies that the `msg_sender` is authorized to consume `inner_hash` by the account.
*
* Computes the `message_hash` using the `msg_sender`, `chain_id`, `version` and `inner_hash`.
* Then executes the `is_valid_impl` function to verify that the message is authorized.
*
* Will revert if the message is not authorized.
*
* @param inner_hash The hash of the message that the `msg_sender` is trying to consume.
*/
// docs:start:verify_private_authwit
pub fn verify_private_authwit(self, inner_hash: Field) -> Field {
// The `inner_hash` is "siloed" with the `msg_sender` to ensure that only it can
// consume the message.
// This ensures that contracts cannot consume messages that are not intended for them.
let message_hash = compute_outer_authwit_hash(
let message_hash = compute_authwit_message_hash(
self.context.msg_sender(),
self.context.chain_id(),
self.context.version(),
Expand Down
Loading

0 comments on commit 051ab9e

Please sign in to comment.