Skip to content

Commit

Permalink
docs: review of docs, so far (AztecProtocol#4505)
Browse files Browse the repository at this point in the history
  • Loading branch information
iAmMichaelConnor committed Feb 8, 2024
1 parent 808efb8 commit 140c508
Show file tree
Hide file tree
Showing 67 changed files with 3,274 additions and 1,737 deletions.
2 changes: 2 additions & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@
"println",
"productionify",
"protobuf",
"protogalaxy",
"proxied",
"proxified",
"proxify",
Expand Down Expand Up @@ -229,6 +230,7 @@
"unshield",
"unshielding",
"unzipit",
"updateable",
"upperfirst",
"usecase",
"usecases",
Expand Down
49 changes: 49 additions & 0 deletions yellow-paper/docs/addresses-and-keys/address.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
title: Address
---

An address is computed as the hash of the following fields:

<!-- prettier-ignore -->
| Field | Type | Description |
|----------|----------|----------|
| `salt` | `Field` | User-generated pseudorandom value for uniqueness. |
| `deployer` | `AztecAddress` | Optional address of the deployer of the contract. |
| `contract_class_id` | `Field` | Identifier of the contract class for this instance. |
| `initialization_hash` | `Field` | Hash of the selector and arguments to the constructor. |
| `portal_contract_address` | `EthereumAddress` | Address of the L1 portal contract, zero if none. |
| `public_keys_hash` | `Field` | Hash of the struct of public keys used for encryption and nullifying by this contract, zero if no public keys. |

Storing these fields in the address preimage allows any part of the protocol to check them by recomputing the hash and verifying that the address matches. Examples of these checks are:

- Sending an encrypted note to an undeployed account, which requires the sender app to check the recipient's public key given their address. This scenario also requires the recipient to share with the sender their public key and rest of preimage.
- Having the kernel circuit verify that the code executed at a given address matches the one from the class.
- Asserting that the initialization hash matches the function call in the contract constructor.
- Checking the portal contract address when sending a cross-chain message.

:::warning
We may remove the `portal_contract_address` as a first-class citizen.
:::

The hashing scheme for the address should then ensure that checks that are more frequent can be done cheaply, and that data shared out of band is kept manageable. We define the hash to be computed as follows:

```
salted_initialization_hash = pedersen([salt, initialization_hash, deployer as Field, portal_contract_address as Field], GENERATOR__SALTED_INITIALIZATION_HASH)
partial_address = pedersen([contract_class_id, salted_initialization_hash], GENERATOR__CONTRACT_PARTIAL_ADDRESS_V1)
address = pedersen([public_keys_hash, partial_address], GENERATOR__CONTRACT_ADDRESS_V1)
```

The `public_keys` array can vary depending on the format of keys used by the address, but it is suggested it includes the master keys defined in the [keys section](./keys.md).

```
public_keys_hash = pedersen([
nullifier_pubkey.x, nullifier_pubkey.y,
tagging_pubkey.x, tagging_pubkey.y,
incoming_view_pubkey.x, incoming_view_pubkey.y,
outgoing_view_pubkey.x, outgoing_view_pubkey.y
], GENERATOR__PUBLIC_KEYS)
```

This recommended hash format is compatible with the [encryption precompiles](./precompiles.md#encryption-and-tagging-precompiles) initially defined in the protocol and advertised in the canonical [registry](../private-message-delivery/registry.md) for private message delivery. An address that chooses to use a different format for its keys will not be compatible with apps that rely on the registry for note encryption. Nevertheless, new precompiles introduced in future versions of the protocol could use different public keys formats.

<!-- TODO(cryptography): Can we restrict "x" components of public keys to all be the same sign, so we don't need to encode "y"'s signs? -->
14 changes: 12 additions & 2 deletions yellow-paper/docs/addresses-and-keys/diversified-and-stealth.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@
title: Diversified and Stealth Accounts
---

The [keys specification](./specification.md) describes derivation mechanisms for diversified and stealth public keys. However, the protocol requires users to interact with addresses.
The [keys specification](./keys.md) describes derivation mechanisms for diversified and stealth public keys. However, the protocol requires users to interact with addresses.

## Computing Addresses

To support diversified and stealth accounts, a user may compute the deterministic address for a given account contract that is deployed using the diversified or stealth public key, so a sender can interact with the resulting address even before the account contract is deployed.
To support diversified and stealth accounts, a user may compute the deterministic address for a given account contract that is deployed using a diversified or stealth public key, so a sender can interact with the resulting so-called "diversified" or "stealth" address even before the account contract is deployed.

When the user wants to access the notes that were sent to the diversified or stealth address, they can deploy the contract at their address, and control it privately from their main account.

<!--
> they can deploy the contract at their address, and control it privately from their main account.
Why would they need to deploy their main account in order to learn about new notes? Wouldn't it instead be possible to configure the PXE to trial-decrypt notes for the main account _even without deploying the account contract_?
-->

## Account Contract Pseudocode

As an example implementation, account contracts for diversified and stealth accounts can be designed to require no private constructor or state, and delegate entrypoint access control to their master address.
Expand All @@ -32,6 +37,11 @@ contract DiversifiedAccount

Given the contract does not require initialization since it has no constructor, it can be used by its owner without being actually deployed, which reduces the setup cost.

<!-- TODO: The above requires that we implement "using a contract without deploying it if it has no constructor", or "constructor abstraction", both of which are a bit controversial. -->
<!-- I think we're now happy with these previously-controversial things, right? So we can probably get rid of this `TODO`?-->

<!-- In addition to considering the flow of diversifying a user's account contract address, please could we also consider a flow where an app contract wishes to diversify _its_ address when making a call to the public world? The app contract would need to do some clever internal bookkeeping to track all its diversified addresses, and which of the apps users are making use of which diversified addresses, but it would be a worthwhile exploration. I suppose the app contract could simply deploy a new diversified contract whenever it wants to make a public call, and route the call through that diversified account contract. -->

## Discarded Approaches

An alternative approach was to introduce a new type of call, a diversified call, that would allow the caller to impersonate any address they can derive from their own, for an enshrined derivation mechanism. Account contracts could use this opcode, as opposed to a regular call, to issue calls on behalf on their diversified and stealth addresses. However, this approach failed to account for calls made back to the account contracts, in particular authwit checks. It also required protocol changes, introducing a new type of call which could be difficult to reason about, and increased attack surface. The only benefit over the approach chosen is that it would require one less extra function call to hop from the user's main account contract to the diversified or stealth one.
12 changes: 9 additions & 3 deletions yellow-paper/docs/addresses-and-keys/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@
title: Addresses and Keys
---

Aztec has no concept of externally-owned accounts. Every address is meant to identify a smart contract in the network. Addresses are then a commitment to a contract class, a list of constructor arguments, and a set of keys.
<!-- TODO, given rearranging of pages -->

Aztec has no concept of externally-owned accounts. Every address identifies a smart contract in the network.

For end users to interact with the network, they'll most-likely need to [deploy](../contract-deployment/index.md) a so-called "account contract".

Addresses are then a commitment to a contract class, a list of constructor arguments, and a set of keys.

Keys in Aztec are used both for authorization and privacy. Authorization keys are managed by account contracts, and not mandated by the protocol. Each account contract may use different authorization keys, if at all, with different signing mechanisms.

Privacy keys are used for note encryption, tagging, and nullifying. These are also not enforced by the protocol. However, for facilitating composability, the protocol enshrines a set of well-known encryption and tagging mechanisms, that can be leveraged by applications as they interact with accounts.
Privacy keys are used for note encryption, tagging, and nullifying. These are also not enforced by the protocol. However, for facilitating composability, the protocol enshrines a set of enshrined encryption and tagging mechanisms, that can be leveraged by applications as they interact with accounts.

The [specification](./specification.md) covers the main requirements for addresses and keys, along with their specification and derivation mechanisms, while the [precompiles](./precompiles.md) section describes well-known contract addresses, with implementations defined by the protocol, used for note encryption and tagging.
The [requirements](./keys-requirements.md) section outlines the features that were sought when designing Aztec's addresses and keys. We then specify how [addresses](./address.md) are derived, as well as the default way in which [keys](./keys.md) will be derived. The [precompiles](./precompiles.md) section describes enshrined contract addresses, with implementations defined by the protocol, used for note encryption and tagging.

Last, the [diversified and stealth accounts](./diversified-and-stealth.md) sections describe application-level recommendations for diversified and stealth accounts.

Expand Down
Loading

0 comments on commit 140c508

Please sign in to comment.