Skip to content

Commit

Permalink
docs: including "real" code in keys docs (#1767)
Browse files Browse the repository at this point in the history
Including "real" code in keys docs + addressed one Noir TODO so that it
doesn't get shown inside the docs.
  • Loading branch information
benesjan authored Aug 23, 2023
1 parent 4207559 commit cd9cadb
Show file tree
Hide file tree
Showing 12 changed files with 1,947 additions and 1,973 deletions.
48 changes: 8 additions & 40 deletions docs/docs/concepts/foundation/accounts/keys.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,11 @@ Typically, each account in Aztec is backed by two separate keys:

Signing keys allow their holder to act as their corresponding account in Aztec, similarly to the keys used for an Ethereum account. If a signing key is leaked, the user can potentially lose all their funds.

Since Aztec implements full [signature abstraction](./main.md), signing keys depend on the account contract implementation for each user. Usually, an account contract will validate a signature of the incoming payload against a known public key.

```noir
fn entrypoint(
inputs: pub PrivateContextInputs,
payload: pub EntrypointPayload,
signature: pub [u8;64],
) -> distinct pub abi::PrivateCircuitPublicInputs {
// Initialize context and load public key
// ...
// Verify payload signature
let payload_bytes: [u8; entrypoint::ENTRYPOINT_PAYLOAD_SIZE_IN_BYTES] = payload.to_be_bytes();
let payload_hash: [u8; 32] = std::hash::sha256(payload_bytes);
// Verify signature of the payload hash
let verification = std::schnorr::verify_signature(public_key.x, public_key.y, signature, payload_hash);
assert(verification == true);
// Execute calls and return
// ...
}
```
Since Aztec implements full [signature abstraction](./main.md), signing keys depend on the account contract implementation for each user. Usually, an account contract will validate a signature of the incoming payload against a known public key.

This is a snippet of our Schnorr Account contract implementation, which uses Schnorr signatures for authentication:

#include_code entrypoint /yarn-project/noir-contracts/src/contracts/schnorr_account_contract/src/main.nr rust

Still, different accounts may use different signing schemes, may require multi-factor authentication, or _may not even use signing keys_ and instead rely on other authentication mechanisms. Read [how to write an account contract](../../../dev_docs/wallets/writing_an_account_contract.md) for a full example of how to manage authentication.

Expand Down Expand Up @@ -89,16 +71,7 @@ In a future version, encryption keys will be differentiated between incoming and

An application in Noir can access the encryption public key for a given address using the oracle call `get_public_key`, which you can then use for calls such as `emit_encrypted_log`:

```noir
let encryption_public_key = get_public_key(recipient);
context = emit_encrypted_log(
context,
application_contract_address,
storage_slot,
encryption_public_key,
note.serialise(),
);
```
#include_code encrypted /yarn-project/noir-libs/value-note/src/utils.nr rust

:::info
In order to be able to provide the public encryption key for a given address, that public key needs to have been registered in advance. At the moment, there is no broadcasting mechanism for public keys, which means that you will need to manually register all addresses you intend to send encrypted notes to. You can do this via the `registerRecipient` method of the Aztec RPC server, callable either via aztec.js or the CLI. Note that any accounts you own that have been added to the RPC server are automatically registered.
Expand All @@ -110,13 +83,8 @@ In addition to deriving encryption keys, the privacy master key is used for deri

An application in Noir can request a nullifier from the current user for computing the nullifier of a note via the `get_secret_key` oracle call:

```noir
fn compute_nullifier(self) -> Field {
let siloed_note_hash = compute_siloed_note_hash(ValueNoteMethods, self);
let secret = get_secret_key(self.owner);
dep::std::hash::pedersen([siloed_note_hash, secret])[0]
}
```
#include_code nullifier /yarn-project/noir-libs/value-note/src/value_note.nr rust

### Scoped keys

:::warning
Expand Down
514 changes: 257 additions & 257 deletions yarn-project/aztec.js/src/abis/ecdsa_account_contract.json

Large diffs are not rendered by default.

3,296 changes: 1,648 additions & 1,648 deletions yarn-project/aztec.js/src/abis/schnorr_account_contract.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use dep::aztec::note::note_interface::NoteInterface;
use dep::aztec::note::note_header::NoteHeader;
use dep::aztec::note::utils::compute_unique_siloed_note_hash;
use dep::aztec::oracle::get_secret_key::get_secret_key;
use dep::aztec::oracle::get_public_key::get_public_key;

global ECDSA_PUBLIC_KEY_NOTE_LEN: Field = 5;

Expand Down Expand Up @@ -54,8 +53,7 @@ impl EcdsaPublicKeyNote {

fn compute_nullifier(self) -> Field {
let unique_siloed_note_hash = compute_unique_siloed_note_hash(EcdsaPublicKeyNoteInterface, self);
let owner_nullifying_public_key = get_public_key(self.owner);
let secret = get_secret_key(owner_nullifying_public_key);
let secret = get_secret_key(self.owner);
dep::std::hash::pedersen([
unique_siloed_note_hash,
secret,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use dep::std::hash::pedersen;
use dep::aztec::note::note_interface::NoteInterface;
use dep::aztec::note::note_header::NoteHeader;
use dep::aztec::oracle::get_secret_key::get_secret_key;
use dep::aztec::oracle::get_public_key::get_public_key;
use dep::aztec::note::utils::compute_siloed_note_hash;

global ADDRESS_NOTE_LEN: Field = 2;
Expand All @@ -29,8 +28,7 @@ impl AddressNote {

fn compute_nullifier(self) -> Field {
let siloed_note_hash = compute_siloed_note_hash(AddressNoteMethods, self);
let owner_nullifying_public_key = get_public_key(self.owner);
let secret = get_secret_key(owner_nullifying_public_key);
let secret = get_secret_key(self.owner);
dep::std::hash::pedersen([
siloed_note_hash,
secret,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use dep::aztec::note::note_interface::NoteInterface;
use dep::aztec::note::note_header::NoteHeader;
use dep::aztec::note::utils::compute_unique_siloed_note_hash;
use dep::aztec::oracle::get_secret_key::get_secret_key;
use dep::aztec::oracle::get_public_key::get_public_key;

global ADDRESS_NOTE_LEN: Field = 1;

Expand All @@ -28,8 +27,7 @@ impl AddressNote {

fn compute_nullifier(self) -> Field {
let unique_siloed_note_hash = compute_unique_siloed_note_hash(AddressNoteMethods, self);
let owner_nullifying_public_key = get_public_key(self.address);
let secret = get_secret_key(owner_nullifying_public_key);
let secret = get_secret_key(self.address);
dep::std::hash::pedersen([
unique_siloed_note_hash,
secret,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ contract SchnorrAccount {
use crate::public_key_note::PublicKeyNoteMethods;
use crate::public_key_note::PUBLIC_KEY_NOTE_LEN;

// docs:start:entrypoint

fn entrypoint(
inputs: pub PrivateContextInputs,
payload: pub EntrypointPayload, // contains a set of arguments, selectors, targets and a nonce
Expand All @@ -53,6 +55,8 @@ contract SchnorrAccount {
let verification = std::schnorr::verify_signature(public_key.x, public_key.y, signature, message_bytes);
assert(verification == true);

// docs:end:entrypoint

// Execute calls
payload.execute_calls(&mut context);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use dep::std::hash::pedersen;
use dep::aztec::note::note_interface::NoteInterface;
use dep::aztec::note::note_header::NoteHeader;
use dep::aztec::oracle::get_secret_key::get_secret_key;
use dep::aztec::oracle::get_public_key::get_public_key;
use dep::aztec::note::utils::compute_unique_siloed_note_hash;

global PUBLIC_KEY_NOTE_LEN: Field = 3;
Expand Down Expand Up @@ -33,8 +32,7 @@ impl PublicKeyNote {

fn compute_nullifier(self) -> Field {
let unique_siloed_note_hash = compute_unique_siloed_note_hash(PublicKeyNoteMethods, self);
let owner_nullifying_public_key = get_public_key(self.owner);
let secret = get_secret_key(owner_nullifying_public_key);
let secret = get_secret_key(self.owner);
dep::std::hash::pedersen([
unique_siloed_note_hash,
secret,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use crate::types::point::Point;
use crate::oracle::get_public_key::get_public_key;

#[oracle(getSecretKey)]
fn get_secret_key_oracle(_owner: Point) -> Field {}

unconstrained fn get_secret_key(owner: Point) -> Field {
get_secret_key_oracle(owner)
unconstrained fn get_secret_key(owner: Field) -> Field {
let owner_nullifying_public_key = get_public_key(owner);
get_secret_key_oracle(owner_nullifying_public_key)
}
14 changes: 11 additions & 3 deletions yarn-project/noir-libs/value-note/src/utils.nr
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,22 @@ fn send_note(
balance.insert(context, &mut note);

// Emit the newly created encrypted note preimages via oracle calls.
// docs:start:encrypted

let application_contract_address = (*context).this_address();
let note_storage_slot = balance.storage_slot;
let encryption_pub_key = get_public_key(recipient);
let encrypted_data = note.serialise();

emit_encrypted_log(
context,
(*context).this_address(),
balance.storage_slot,
application_contract_address,
note_storage_slot,
encryption_pub_key,
note.serialise(),
encrypted_data,
);

// docs:end:encrypted
}

/*
Expand Down
10 changes: 5 additions & 5 deletions yarn-project/noir-libs/value-note/src/value_note.nr
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use dep::aztec::note::{
use dep::aztec::oracle::{
rand::rand,
get_secret_key::get_secret_key,
get_public_key::get_public_key,
};

global VALUE_NOTE_LEN: Field = 3; // 3 plus a header.
Expand Down Expand Up @@ -51,18 +50,19 @@ impl ValueNote {
])[0]
}

// docs:start:nullifier

fn compute_nullifier(self) -> Field {
let note_hash_for_nullify = compute_note_hash_for_read_or_nullify(ValueNoteMethods, self);
let owner_nullifying_public_key = get_public_key(self.owner);
// TODO: get_secret_key should just accept an address
// TODO!
let secret = get_secret_key(owner_nullifying_public_key);
let secret = get_secret_key(self.owner);
dep::std::hash::pedersen([
note_hash_for_nullify,
secret,
])[0]
}

// docs:end:nullifier

fn set_header(&mut self, header: NoteHeader) {
self.header = header;
}
Expand Down

0 comments on commit cd9cadb

Please sign in to comment.