diff --git a/docs/docs/aztec/concepts/accounts/keys.md b/docs/docs/aztec/concepts/accounts/keys.md index 8024c6bb8d64..b20ae2242273 100644 --- a/docs/docs/aztec/concepts/accounts/keys.md +++ b/docs/docs/aztec/concepts/accounts/keys.md @@ -25,23 +25,13 @@ Instead it's up to the account contract developer to implement it. ## Public keys retrieval -The keys can either be retrieved from a key registry contract or from the [Private eXecution Environment (PXE)](../pxe/index.md). - -:::note -The key registry is a canonical contract used to store user public keys. -Canonical in this context means that it is a contract whose functionality is essential for the protocol. -There is 1 key registry and its address is hardcoded in the protocol code. -::: - -To retrieve them a developer can use one of the getters in Aztec.nr: +The keys can be retrieved from the [Private eXecution Environment (PXE)](../pxe/index.md) using the following getter in Aztec.nr: ``` -fn get_current_public_keys(context: &mut PrivateContext, account: AztecAddress) -> PublicKeys; -fn get_historical_public_keys(historical_header: Header, account: AztecAddress) -> PublicKeys; +fn get_public_keys(account: AztecAddress) -> PublicKeys; ``` -If the keys are registered in the key registry these methods can be called without any setup. -If they are not there, it is necessary to first register the user as a recipient in our PXE. +It is necessary to first register the user as a recipient in our PXE, providing their public keys. First we need to get a hold of recipient's [complete address](#complete-address). Below are some ways how we could instantiate it after getting the information in a string form from a recipient: @@ -54,18 +44,6 @@ Then to register the recipient's [complete address](#complete-address) in PXE we During private function execution these keys are obtained via an oracle call from PXE. -## Key rotation - -To prevent users from needing to migrate all their positions if some of their keys are leaked we allow for key rotation. -Key rotation can be performed by calling the corresponding function on key registry. -E.g. for nullifier key: - -#include_code key-rotation /yarn-project/end-to-end/src/e2e_key_registry.test.ts rust - -Note that the notes directly contain `Npk_m`. -This means that it will be possible to nullify the notes with the same old key after the key rotation and attacker could still potentially steal them if there are no other guardrails in place (like for example account contract auth check). -These guardrails are typically in place so a user should not lose her notes even if this unfortunate accident happens. - ## Scoped keys To minimize damage of potential key leaks the keys are scoped (also called app-siloed) to the contract that requests them. @@ -180,7 +158,7 @@ An example of an escrow contract is a betting contract. In this scenario, both p The escrow would then release the reward only to the party that provides a "proof of winning". Because of the contract address derivation scheme it is possible to check that a given set of public keys corresponds to a given address just by trying to recompute it. -Since this is commonly needed to be done when sending a note to an account whose keys are not yet registered in the key registry contract we coined the term **complete address** for the collection of: +Since this is commonly needed to be done when sending a note to an account we coined the term **complete address** for the collection of: 1. all the user's public keys, 2. partial address, @@ -188,8 +166,3 @@ Since this is commonly needed to be done when sending a note to an account whose Once the complete address is shared with the sender, the sender can check that the address was correctly derived from the public keys and partial address and then send the notes to that address. Because of this it is possible to send a note to an account whose account contract was not yet deployed. - -:::note -Note that since the individual [keys can be rotated](#key-rotation) complete address is used only for non-registered accounts. -For registered accounts key registry is always the source of truth. -::: diff --git a/docs/docs/guides/developer_guides/js_apps/rotate_keys.md b/docs/docs/guides/developer_guides/js_apps/rotate_keys.md deleted file mode 100644 index 55eba15e4ef6..000000000000 --- a/docs/docs/guides/developer_guides/js_apps/rotate_keys.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: How to Rotate Nullifier Keys -tags: [accounts, keys] ---- - -This guide explains how to rotate nullifer secret and public keys using Aztec.js. To learn more about key rotation, read the [concepts section](../../../aztec/concepts/accounts/keys.md#key-rotation) - -## Prerequisites - -You should have a wallet whose keys you want to rotate. You can learn how to create wallets from [this guide](./create_account.md). - -You should also have a PXE initialized. - -## Relevant imports - -You will need to import these from Aztec.js: - -#include_code imports yarn-project/end-to-end/src/e2e_key_rotation.test.ts typescript - -## Create nullifier secret and public key - -`newNskM` = new master nullifier secret key - -`newNpkM` = new master nullifier public key (type `PublicKey`) - -#include_code create_keys yarn-project/end-to-end/src/e2e_key_rotation.test.ts typescript - -## Rotate nullifier secret and public key - -Call `rotateNullifierKeys` on the AccountWallet to rotate the secret key in the PXE and call the key registry with the new derived public key. - -#include_code rotateNullifierKeys yarn-project/end-to-end/src/e2e_key_rotation.test.ts typescript diff --git a/docs/docs/guides/developer_guides/smart_contracts/writing_contracts/common_patterns/key_rotation.md b/docs/docs/guides/developer_guides/smart_contracts/writing_contracts/common_patterns/key_rotation.md deleted file mode 100644 index 5841e5eb3fc8..000000000000 --- a/docs/docs/guides/developer_guides/smart_contracts/writing_contracts/common_patterns/key_rotation.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: Key Rotation -tags: [accounts, keys] ---- - -## Prerequisite reading - -- [Keys Concept](../../../../../aztec/concepts/accounts/keys.md) - -## Introduction - -It is possible for users to rotate their keys, which can be helpful if some of their keys are leaked. Key rotation allows users to continue using the same account without having to create a new one. - -Because of this, notes are often associated with their `nullifier key` (through a nullifier public key hash, often called `npk_m_hash`) rather than any sort of 'owner' address. - -It is still possible to nullify the notes with the old nullifier key even after the key rotation. - -## `TokenNote` example - -See the structure of the `TokenNote` below: - -#include_code TokenNote noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr rust - -In the `TokenNote` type, you can see that the nullifer computation gets the nullifier secret key specific to the contract from the PXE, based on the stored `npk_m_hash`, so a `TokenNote` is not inherently or permanently linked to a specific Aztec account. - -#include_code nullifier noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr rust - -## Things to consider - -- When using the `npk_m_hash`, used to represent ownership, whoever has the nullifier secret can nullify a note. -- Consider how key rotation can affect account contracts, e.g. you can add additional security checks for who or how the key rotation is called - -## Resources - -- End to end tests for key rotation can be found [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/yarn-project/end-to-end/src/e2e_key_rotation.test.ts) - -## Glossary - -- `npk_m_hash`: master nullifying public key hash -- `nsk_app`: app nullifying secret key - the app-specific NSK (learn more about app-scoped keys [here](../../../../../aztec/concepts/accounts/keys.md#scoped-keys)) -- `nsk_hash`: nullifying secret key hash -- `ivpk_m`: incoming view public key (master) (learn more about IVPKs [here](../../../../../aztec/concepts/accounts/keys.md#incoming-viewing-keys)) diff --git a/docs/docs/migration_notes.md b/docs/docs/migration_notes.md index 4d725794a057..85270d9718d8 100644 --- a/docs/docs/migration_notes.md +++ b/docs/docs/migration_notes.md @@ -8,6 +8,15 @@ Aztec is in full-speed development. Literally every version breaks compatibility ## TBD +### Key rotation removed + +The ability to rotate incoming, outgoing, nullifying and tagging keys has been removed - this feature was easy to misuse and not worth the complexity and gate count cost. As part of this, the Key Registry contract has also been deleted. The API for fetching public keys has been adjusted accordingly: + +```diff +- let keys = get_current_public_keys(&mut context, account); ++ let keys = get_public_keys(account); +``` + ### [Aztec.nr] Rework `NoteGetterOptions::select` The `select` function in both `NoteGetterOptions` and `NoteViewerOptions` no longer takes an `Option` of a comparator, but instead requires an explicit comparator to be passed. Additionally, the order of the parameters has been changed so that they are `(lhs, operator, rhs)`. These two changes should make invocations of the function easier to read: diff --git a/docs/docs/tutorials/codealong/contract_tutorials/private_voting_contract.md b/docs/docs/tutorials/codealong/contract_tutorials/private_voting_contract.md index e348f36350d2..f92a9a9ad896 100644 --- a/docs/docs/tutorials/codealong/contract_tutorials/private_voting_contract.md +++ b/docs/docs/tutorials/codealong/contract_tutorials/private_voting_contract.md @@ -128,17 +128,13 @@ The first thing we do here is assert that the vote has not ended. The code after the assertion will only run if the assertion is true. In this snippet, we read the current vote tally at the `candidate`, add 1 to it, and write this new number to the `candidate`. The `Field` element allows us to use `+` to add to an integer. -:::warning -Refer to [common patterns (Guides section)](../../../guides/developer_guides/smart_contracts/writing_contracts/common_patterns/key_rotation.md) for more information about key rotation and considerations. -::: - ## Getting the number of votes We will create a function that anyone can call that will return the number of votes at a given vote Id. Paste this in your contract: #include_code get_vote noir-projects/noir-contracts/contracts/easy_private_voting_contract/src/main.nr rust -We set it as `unconstrained` and do not annotate it because it is only reading from state. +We set it as `unconstrained` and do not annotate it because it is only reading from state. ## Allowing an admin to end a voting period @@ -176,7 +172,7 @@ Follow the crowdfunding contracts tutorial on the [next page](./crowdfunding_con ### Optional: Learn more about concepts mentioned here - - [Unconstrained functions](../../../aztec/smart_contracts/functions/index.md). - - [Oracles](../../../aztec/smart_contracts/oracles/index.md) - - [Nullifier secrets](../../../aztec/concepts/accounts/keys.md#nullifier-secrets). - - [How to deploy a contract to the sandbox](../../../guides/developer_guides/smart_contracts/how_to_deploy_contract.md) +- [Unconstrained functions](../../../aztec/smart_contracts/functions/index.md). +- [Oracles](../../../aztec/smart_contracts/oracles/index.md) +- [Nullifier secrets](../../../aztec/concepts/accounts/keys.md#nullifier-secrets). +- [How to deploy a contract to the sandbox](../../../guides/developer_guides/smart_contracts/how_to_deploy_contract.md) diff --git a/noir-projects/aztec-nr/aztec/src/encrypted_logs/encrypted_event_emission.nr b/noir-projects/aztec-nr/aztec/src/encrypted_logs/encrypted_event_emission.nr index 90752c294679..4030a7a85efd 100644 --- a/noir-projects/aztec-nr/aztec/src/encrypted_logs/encrypted_event_emission.nr +++ b/noir-projects/aztec-nr/aztec/src/encrypted_logs/encrypted_event_emission.nr @@ -1,7 +1,7 @@ use crate::{ context::PrivateContext, event::event_interface::EventInterface, encrypted_logs::payload::compute_encrypted_event_log, - keys::{getters::get_current_public_keys, public_keys::{OvpkM, IvpkM}}, + keys::{getters::get_public_keys, public_keys::{OvpkM, IvpkM}}, oracle::logs_traits::LensForEncryptedEvent, oracle::unsafe_rand::unsafe_rand }; use dep::protocol_types::{address::AztecAddress, hash::sha256_to_field}; @@ -67,10 +67,10 @@ pub fn encode_and_encrypt_event( context: &mut PrivateContext, ov: AztecAddress, iv: AztecAddress -) -> fn[(&mut PrivateContext, AztecAddress, AztecAddress)](Event) -> () where Event: EventInterface, [u8; NB]: LensForEncryptedEvent { +) -> fn[(AztecAddress, AztecAddress, &mut PrivateContext)](Event) -> () where Event: EventInterface, [u8; NB]: LensForEncryptedEvent { | e: Event | { - let ovpk = get_current_public_keys(context, ov).ovpk_m; - let ivpk = get_current_public_keys(context, iv).ivpk_m; + let ovpk = get_public_keys(ov).ovpk_m; + let ivpk = get_public_keys(iv).ivpk_m; let randomness = unsafe_rand(); emit_with_keys(context, randomness, e, ovpk, ivpk, iv, compute); } @@ -80,10 +80,10 @@ pub fn encode_and_encrypt_event_unconstrained fn[(&mut PrivateContext, AztecAddress, AztecAddress)](Event) -> () where Event: EventInterface, [u8; NB]: LensForEncryptedEvent { +) -> fn[(AztecAddress, AztecAddress, &mut PrivateContext)](Event) -> () where Event: EventInterface, [u8; NB]: LensForEncryptedEvent { | e: Event | { - let ovpk = get_current_public_keys(context, ov).ovpk_m; - let ivpk = get_current_public_keys(context, iv).ivpk_m; + let ovpk = get_public_keys(ov).ovpk_m; + let ivpk = get_public_keys(iv).ivpk_m; let randomness = unsafe_rand(); emit_with_keys(context, randomness, e, ovpk, ivpk, iv, compute_unconstrained); } @@ -94,10 +94,10 @@ pub fn encode_and_encrypt_event_with_randomness fn[(&mut PrivateContext, AztecAddress, AztecAddress, Field)](Event) -> () where Event: EventInterface, [u8; NB]: LensForEncryptedEvent { +) -> fn[(AztecAddress, AztecAddress, &mut PrivateContext, Field)](Event) -> () where Event: EventInterface, [u8; NB]: LensForEncryptedEvent { | e: Event | { - let ovpk = get_current_public_keys(context, ov).ovpk_m; - let ivpk = get_current_public_keys(context, iv).ivpk_m; + let ovpk = get_public_keys(ov).ovpk_m; + let ivpk = get_public_keys(iv).ivpk_m; emit_with_keys(context, randomness, e, ovpk, ivpk, iv, compute); } } @@ -107,10 +107,10 @@ pub fn encode_and_encrypt_event_with_randomness_unconstrained fn[(&mut PrivateContext, AztecAddress, AztecAddress, Field)](Event) -> () where Event: EventInterface, [u8; NB]: LensForEncryptedEvent { +) -> fn[(AztecAddress, AztecAddress, &mut PrivateContext, Field)](Event) -> () where Event: EventInterface, [u8; NB]: LensForEncryptedEvent { | e: Event | { - let ovpk = get_current_public_keys(context, ov).ovpk_m; - let ivpk = get_current_public_keys(context, iv).ivpk_m; + let ovpk = get_public_keys(ov).ovpk_m; + let ivpk = get_public_keys(iv).ivpk_m; emit_with_keys(context, randomness, e, ovpk, ivpk, iv, compute_unconstrained); } } diff --git a/noir-projects/aztec-nr/aztec/src/encrypted_logs/encrypted_note_emission.nr b/noir-projects/aztec-nr/aztec/src/encrypted_logs/encrypted_note_emission.nr index 16deb1524832..46be0922eae7 100644 --- a/noir-projects/aztec-nr/aztec/src/encrypted_logs/encrypted_note_emission.nr +++ b/noir-projects/aztec-nr/aztec/src/encrypted_logs/encrypted_note_emission.nr @@ -1,6 +1,6 @@ use crate::{ context::PrivateContext, note::{note_emission::NoteEmission, note_interface::NoteInterface}, - keys::{getters::{get_current_public_keys, get_ovsk_app}, public_keys::{OvpkM, IvpkM}}, + keys::{getters::{get_public_keys, get_ovsk_app}, public_keys::{OvpkM, IvpkM}}, encrypted_logs::payload::compute_encrypted_note_log, oracle::logs_traits::LensForEncryptedLog }; use dep::protocol_types::{hash::sha256_to_field, address::AztecAddress, abis::note_hash::NoteHash}; @@ -52,10 +52,10 @@ pub fn encode_and_encrypt_note( context: &mut PrivateContext, ov: AztecAddress, iv: AztecAddress -) -> fn[(&mut PrivateContext, AztecAddress, AztecAddress)](NoteEmission) -> () where Note: NoteInterface, [Field; N]: LensForEncryptedLog { +) -> fn[(AztecAddress, AztecAddress, &mut PrivateContext)](NoteEmission) -> () where Note: NoteInterface, [Field; N]: LensForEncryptedLog { | e: NoteEmission | { - let ovpk = get_current_public_keys(context, ov).ovpk_m; - let ivpk = get_current_public_keys(context, iv).ivpk_m; + let ovpk = get_public_keys(ov).ovpk_m; + let ivpk = get_public_keys(iv).ivpk_m; let ovsk_app: Field = context.request_ovsk_app(ovpk.hash()); let (note_hash_counter, encrypted_log, log_hash) = compute_raw_note_log(*context, e.note, ovsk_app, ovpk, ivpk, iv); @@ -67,12 +67,12 @@ pub fn encode_and_encrypt_note_unconstrained fn[(&mut PrivateContext, AztecAddress, AztecAddress)](NoteEmission) -> () where Note: NoteInterface, [Field; N]: LensForEncryptedLog { +) -> fn[(AztecAddress, AztecAddress, &mut PrivateContext)](NoteEmission) -> () where Note: NoteInterface, [Field; N]: LensForEncryptedLog { | e: NoteEmission | { // Note: We could save a lot of gates by obtaining the following keys in an unconstrained context but this // function is currently not used anywhere so we are not optimizing it. - let ovpk = get_current_public_keys(context, ov).ovpk_m; - let ivpk = get_current_public_keys(context, iv).ivpk_m; + let ovpk = get_public_keys(ov).ovpk_m; + let ivpk = get_public_keys(iv).ivpk_m; // See the comment in `encode_and_encrypt_note_with_keys_unconstrained` for why having note hash counter // and log hash unconstrained here is fine. diff --git a/noir-projects/aztec-nr/aztec/src/keys/getters/mod.nr b/noir-projects/aztec-nr/aztec/src/keys/getters/mod.nr index 8b6025c073f8..06af9e343744 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/getters/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/getters/mod.nr @@ -1,29 +1,11 @@ -use dep::protocol_types::{ - header::Header, address::AztecAddress, constants::CANONICAL_KEY_REGISTRY_ADDRESS, - storage::map::derive_storage_slot_in_map -}; +use dep::protocol_types::address::AztecAddress; use crate::{ - context::{PrivateContext, UnconstrainedContext}, oracle::{keys::get_public_keys_and_partial_address, key_validation_request::get_key_validation_request}, - keys::{ - public_keys::{PublicKeys, PUBLIC_KEYS_LENGTH}, stored_keys::StoredKeys, - constants::{NULLIFIER_INDEX, OUTGOING_INDEX} -}, - state_vars::{public_mutable::PublicMutable, map::Map} + keys::{public_keys::PublicKeys, constants::{NULLIFIER_INDEX, OUTGOING_INDEX}} }; mod test; -// This is the number of blocks that must pass after a key rotation event until the old keys are fully phased out and -// become invalid. -global KEY_REGISTRY_UPDATE_BLOCKS = 5; - -global KEY_REGISTRY_STORAGE_SLOT = 1; - -// A helper function that gets app-siloed nullifier secret key for a given `npk_m_hash`. This function is used -// in unconstrained contexts only - in Note::compute_nullifier_without_context which in turn is called by -// `compute_note_hash_and_optionally_a_nullifier` function that is used by the NoteProcessor. The safe alternative -// is `request_nsk_app` function define on `PrivateContext`. unconstrained pub fn get_nsk_app(npk_m_hash: Field) -> Field { get_key_validation_request(npk_m_hash, NULLIFIER_INDEX).sk_app } @@ -35,85 +17,16 @@ unconstrained pub fn get_ovsk_app(ovpk_m_hash: Field) -> Field { get_key_validation_request(ovpk_m_hash, OUTGOING_INDEX).sk_app } -// Returns all current public keys for a given account, applying proper constraints to the context. We read all +// Returns all public keys for a given account, applying proper constraints to the context. We read all // keys at once since the constraints for reading them all are actually fewer than if we read them one at a time - any // read keys that are not required by the caller can simply be discarded. -pub fn get_current_public_keys(context: &mut PrivateContext, account: AztecAddress) -> PublicKeys { - // We're going to perform historical reads from public storage, and so need to constrain the caller so that they - // cannot use very old blocks when constructing proofs, and hence e.g. read very old keys. We are lax and allow - // _any_ recent block number to be used, regardless of whether there may have been a recent key rotation. This means - // that multiple sets of keys are valid for a while immediately after rotation, until the old keys become phased - // out. We *must* be lax to prevent denial of service and transaction fingerprinting attacks by accounts that rotate - // their keys frequently. - // Note that we constrain the max block number even if the registry ends up being empty: this ensures that proof of - // an empty registry is also fresh. - let current_header = context.get_header(); - context.set_tx_max_block_number(current_header.global_variables.block_number as u32 + KEY_REGISTRY_UPDATE_BLOCKS); - - get_historical_public_keys(current_header, account) -} - -// Returns historical public keys for a given account at some block determined by a block header. We read all keys at -// once since the constraints for reading them all are actually fewer than if we read them one at a time - any read keys -// that are not required by the caller can simply be discarded. -// WARNING: if called with a historical header created from a fixed block this function will explicitly ignore key -// rotation! This means that callers of this may force a user to use old keys, potentially leaking privacy (e.g. if the -// old keys were leaked). Only call this function with a header from a fixed block if you understand the implications of -// breaking key rotation very well. -pub fn get_historical_public_keys(historical_header: Header, account: AztecAddress) -> PublicKeys { - // TODO: improve this so that we always hint the correct set of keys (either registry or canonical) and hash them - // once instead of having two different hints and twice as many constraints due to the double hashing. - - // The key registry is the primary source of information for keys, as that's where accounts store their new keys - // when they perform rotation. The key registry conveniently stores a hash of each user's keys, so we can read that - // single field and then prove that we know its preimage (i.e. the current set of keys). - let key_registry_hash = key_registry_hash_public_historical_read(historical_header, account); - if key_registry_hash != 0 { - let hinted_registry_public_keys = key_registry_get_stored_keys_hint( - account, - historical_header.global_variables.block_number as u32 - ); - assert_eq(hinted_registry_public_keys.hash().to_field(), key_registry_hash); - - hinted_registry_public_keys - } else { - // If nothing was written to the registry, we may still be able to produce the correct keys if we happen to know - // the canonical set (i.e. the ones that are part of the account's preimage). - let (hinted_canonical_public_keys, partial_address) = get_public_keys_and_partial_address(account); - assert_eq( - account, AztecAddress::compute(hinted_canonical_public_keys.hash(), partial_address), "Invalid public keys hint for address" - ); - - hinted_canonical_public_keys - } -} - -fn key_registry_hash_public_historical_read(historical_header: Header, account: AztecAddress) -> Field { - // The keys are stored in a Map that is keyed with the address of each account, so we first derive the corresponding - // slot for this account. - let keys_storage_slot = derive_storage_slot_in_map(KEY_REGISTRY_STORAGE_SLOT, account); - - // The keys are stored as [ ...serialized_keys, hash ], and since arrays get allocated sequential storage slots - // (prior to siloing!), we simply add the length to the base slot to get the last element. - let hash_storage_slot = keys_storage_slot + PUBLIC_KEYS_LENGTH as Field; - - historical_header.public_storage_historical_read(hash_storage_slot, CANONICAL_KEY_REGISTRY_ADDRESS) -} - -unconstrained fn key_registry_get_stored_keys_hint(account: AztecAddress, block_number: u32) -> PublicKeys { - // This is equivalent to the key registry contract having an unconstrained getter that we call from an oracle, but - // PXE does not yet support that functionality so we do this manually instad. Note that this would be a *historical* - // call! - - // TODO (#7524): call the unconstrained KeyRegistry.get_current_keys() function instead - - let context = UnconstrainedContext::at_historical(CANONICAL_KEY_REGISTRY_ADDRESS, block_number); - let keys_storage = Map::new( - context, - KEY_REGISTRY_STORAGE_SLOT, - |context, slot| { PublicMutable::new(context, slot) } +pub fn get_public_keys(account: AztecAddress) -> PublicKeys { + let (hinted_canonical_public_keys, partial_address) = unsafe { + get_public_keys_and_partial_address(account) + }; + assert_eq( + account, AztecAddress::compute(hinted_canonical_public_keys.hash(), partial_address), "Invalid public keys hint for address" ); - let stored_keys: StoredKeys = keys_storage.at(account).read(); - stored_keys.public_keys + hinted_canonical_public_keys } diff --git a/noir-projects/aztec-nr/aztec/src/keys/getters/test.nr b/noir-projects/aztec-nr/aztec/src/keys/getters/test.nr index f6a54b19a725..273e370658f3 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/getters/test.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/getters/test.nr @@ -1,57 +1,30 @@ -use crate::keys::getters::{get_current_public_keys, get_historical_public_keys, KEY_REGISTRY_UPDATE_BLOCKS}; -use crate::context::PrivateContext; +use crate::keys::getters::get_public_keys; use crate::test::helpers::{cheatcodes, test_environment::TestEnvironment, utils::TestAccount}; use dep::std::test::OracleMock; global KEY_ORACLE_RESPONSE_LENGTH = 13; // 12 fields for the keys, one field for the partial address -fn setup() -> (TestEnvironment, PrivateContext, TestAccount) { - let mut env = TestEnvironment::new(); +unconstrained fn setup() -> TestAccount { + let _ = TestEnvironment::new(); let account = cheatcodes::create_account(); - let historical_block_number = env.block_number(); - let context = env.private_at(historical_block_number); - - (env, context, account) -} - -#[test(should_fail_with="Invalid public keys hint for address")] -fn test_get_current_keys_unknown_unregistered() { - let (_, mut context, account) = setup(); - - let _ = OracleMock::mock("getPublicKeysAndPartialAddress").returns([0; KEY_ORACLE_RESPONSE_LENGTH]).times(1); - let _ = get_current_public_keys(&mut context, account.address); + account } #[test(should_fail_with="Invalid public keys hint for address")] -fn test_get_historical_keys_unknown_unregistered() { - let (_, context, account) = setup(); - let historical_header = context.get_header(); +unconstrained fn test_get_public_keys_unknown() { + let account = setup(); + // Instead of querying for some unknown account, which would result in the oracle erroring out, we mock a bad oracle + // response to check that the circuit properly checks the address derivation. let _ = OracleMock::mock("getPublicKeysAndPartialAddress").returns([0; KEY_ORACLE_RESPONSE_LENGTH]).times(1); - let _ = get_historical_public_keys(historical_header, account.address); + let _ = get_public_keys(account.address); } #[test] -fn test_get_current_keys_known_unregistered() { - let (_, mut context, account) = setup(); - - let current_keys = get_current_public_keys(&mut context, account.address); - - assert_eq(current_keys, account.keys); - assert_eq( - context.max_block_number.unwrap(), context.historical_header.global_variables.block_number as u32 + KEY_REGISTRY_UPDATE_BLOCKS - ); -} - -#[test] -fn test_get_historical_keys_known_unregistered() { - let (_, context, account) = setup(); - - let historical_header = context.get_header(); +unconstrained fn test_get_public_keys_known() { + let account = setup(); - let historical_keys = get_historical_public_keys(historical_header, account.address); - assert_eq(historical_keys, account.keys); - assert(context.max_block_number.is_none()); + assert_eq(get_public_keys(account.address), account.keys); } diff --git a/noir-projects/aztec-nr/aztec/src/keys/mod.nr b/noir-projects/aztec-nr/aztec/src/keys/mod.nr index 12ee77b56f56..828ff12a0ece 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/mod.nr @@ -2,6 +2,5 @@ mod constants; mod getters; mod point_to_symmetric_key; mod public_keys; -mod stored_keys; pub use crate::keys::public_keys::{PublicKeys, PUBLIC_KEYS_LENGTH}; diff --git a/noir-projects/aztec-nr/aztec/src/keys/stored_keys.nr b/noir-projects/aztec-nr/aztec/src/keys/stored_keys.nr deleted file mode 100644 index 20111f6e795d..000000000000 --- a/noir-projects/aztec-nr/aztec/src/keys/stored_keys.nr +++ /dev/null @@ -1,59 +0,0 @@ -use crate::keys::public_keys::{PublicKeys, PUBLIC_KEYS_LENGTH}; -use dep::protocol_types::traits::{Serialize, Deserialize}; - -// This struct represents how public keys are stored in the key registry. We store not just the keys themselves but also -// their hash, so that when reading in private we can perform a historical read for the hash and then show that it -// corresponds to a preimage obtained from an unconstrained hint. We do store the keys keys regardless as they might be -// needed during public execution, and since we need to broadcast and produce hints in some standardized way. -// While it might seem odd to create a struct for what is effectively some data and a pure function called on it, state -// variables rely on serializable structs in order to persist data to storage, so we must use this abstraction. -struct StoredKeys { - public_keys: PublicKeys, - hash: Field, -} - -impl StoredKeys { - // Instances of StoredKeys are expected to only be created by calling this function so that we guarantee that the - // hash field does indeed correspond to the hash of the keys. Ideally we'd forbid direct access to the struct, but - // Noir doesn't yet support private members. - fn new(public_keys: PublicKeys) -> Self { - Self { public_keys, hash: public_keys.hash().inner } - } -} - -// Our serialization is the concatenation of the public keys serialization plush the hash, so we need one extra field. -global STORED_KEYS_LENGTH: u32 = PUBLIC_KEYS_LENGTH + 1; - -impl Serialize for StoredKeys { - fn serialize(self) -> [Field; STORED_KEYS_LENGTH] { - // The code below is equivalent to: - // [ ...self.public_keys.serialize(), self.hash ] - - let mut array = [0; STORED_KEYS_LENGTH]; - - let serialized_keys = self.public_keys.serialize(); - for i in 0..serialized_keys.len() { - array[i] = serialized_keys[i]; - } - - array[PUBLIC_KEYS_LENGTH] = self.hash; - - array - } -} - -impl Deserialize for StoredKeys { - fn deserialize(array: [Field; STORED_KEYS_LENGTH]) -> Self { - // The code below is equivalent to: - // Self { public_keys: PublicKeys::deserialize(array[0 : PUBLIC_KEYS_LENGTH]), hash: array[PUBLIC_KEYS_LENGTH] } - - let mut serialized_keys = [0; PUBLIC_KEYS_LENGTH]; - for i in 0..serialized_keys.len() { - serialized_keys[i] = array[i]; - } - - let hash = array[PUBLIC_KEYS_LENGTH]; - - Self { public_keys: PublicKeys::deserialize(serialized_keys), hash } - } -} diff --git a/noir-projects/aztec-nr/aztec/src/test/helpers/keys.nr b/noir-projects/aztec-nr/aztec/src/test/helpers/keys.nr deleted file mode 100644 index 9226b6e9854c..000000000000 --- a/noir-projects/aztec-nr/aztec/src/test/helpers/keys.nr +++ /dev/null @@ -1,26 +0,0 @@ -use dep::protocol_types::{ - address::AztecAddress, storage::map::derive_storage_slot_in_map, - constants::CANONICAL_KEY_REGISTRY_ADDRESS -}; - -use crate::{test::helpers::cheatcodes, keys::public_keys::ToPoint}; - -pub fn store_master_key(key_index: Field, address: AztecAddress, key: T) where T: ToPoint { - let key_point = key.to_point(); - - let x_coordinate_map_slot = key_index * 2 + 1; - let y_coordinate_map_slot = x_coordinate_map_slot + 1; - let x_coordinate_derived_slot = derive_storage_slot_in_map(x_coordinate_map_slot, address); - let y_coordinate_derived_slot = derive_storage_slot_in_map(y_coordinate_map_slot, address); - - cheatcodes::direct_storage_write( - CANONICAL_KEY_REGISTRY_ADDRESS, - x_coordinate_derived_slot, - [key_point.x] - ); - cheatcodes::direct_storage_write( - CANONICAL_KEY_REGISTRY_ADDRESS, - y_coordinate_derived_slot, - [key_point.y] - ); -} diff --git a/noir-projects/aztec-nr/aztec/src/test/helpers/mod.nr b/noir-projects/aztec-nr/aztec/src/test/helpers/mod.nr index b7164a823595..93eb11040c87 100644 --- a/noir-projects/aztec-nr/aztec/src/test/helpers/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/test/helpers/mod.nr @@ -1,4 +1,3 @@ mod test_environment; mod cheatcodes; mod utils; -mod keys; diff --git a/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr b/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr index 070837c69e15..7f518a4cef5a 100644 --- a/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr +++ b/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr @@ -7,7 +7,7 @@ use crate::context::inputs::{PublicContextInputs, PrivateContextInputs}; use crate::context::{packed_returns::PackedReturns, call_interfaces::CallInterface}; use crate::context::{PrivateContext, PublicContext, UnconstrainedContext}; -use crate::test::helpers::{cheatcodes, utils::{apply_side_effects_private, Deployer}, keys}; +use crate::test::helpers::{cheatcodes, utils::{apply_side_effects_private, Deployer}}; use crate::keys::constants::{NULLIFIER_INDEX, INCOMING_INDEX, OUTGOING_INDEX, TAGGING_INDEX}; use crate::hash::hash_args; @@ -69,14 +69,6 @@ impl TestEnvironment { fn create_account(_self: Self) -> AztecAddress { let test_account = cheatcodes::create_account(); - let address = test_account.address; - let keys = test_account.keys; - - keys::store_master_key(NULLIFIER_INDEX, address, keys.npk_m); - keys::store_master_key(INCOMING_INDEX, address, keys.ivpk_m); - keys::store_master_key(OUTGOING_INDEX, address, keys.ovpk_m); - keys::store_master_key(TAGGING_INDEX, address, keys.tpk_m); - test_account.address } @@ -85,13 +77,6 @@ impl TestEnvironment { let address = test_account.address; cheatcodes::advance_blocks_by(1); - let keys = test_account.keys; - - keys::store_master_key(NULLIFIER_INDEX, address, keys.npk_m); - keys::store_master_key(INCOMING_INDEX, address, keys.ivpk_m); - keys::store_master_key(OUTGOING_INDEX, address, keys.ovpk_m); - keys::store_master_key(TAGGING_INDEX, address, keys.tpk_m); - let selector = FunctionSelector::from_signature("constructor(Field,Field)"); let mut context = self.private_at(get_block_number()); diff --git a/noir-projects/aztec-nr/easy-private-state/src/easy_private_uint.nr b/noir-projects/aztec-nr/easy-private-state/src/easy_private_uint.nr index 944c29603a6a..3ec42149937d 100644 --- a/noir-projects/aztec-nr/easy-private-state/src/easy_private_uint.nr +++ b/noir-projects/aztec-nr/easy-private-state/src/easy_private_uint.nr @@ -2,7 +2,7 @@ use dep::aztec::{ context::PrivateContext, protocol_types::{address::AztecAddress}, note::note_getter_options::NoteGetterOptions, state_vars::PrivateSet, encrypted_logs::encrypted_note_emission::encode_and_encrypt_note_with_keys, - keys::getters::get_current_public_keys + keys::getters::get_public_keys }; use dep::value_note::{filter::filter_notes_min_sum, value_note::ValueNote}; @@ -24,8 +24,8 @@ impl EasyPrivateUint { impl EasyPrivateUint<&mut PrivateContext> { // Very similar to `value_note::utils::increment`. pub fn add(self, addend: u64, owner: AztecAddress, outgoing_viewer: AztecAddress) { - let owner_keys = get_current_public_keys(self.context, owner); - let outgoing_viewer_keys = get_current_public_keys(self.context, outgoing_viewer); + let owner_keys = get_public_keys(owner); + let outgoing_viewer_keys = get_public_keys(outgoing_viewer); // Creates new note for the owner. let mut addend_note = ValueNote::new(addend as Field, owner_keys.npk_m.hash()); @@ -44,8 +44,8 @@ impl EasyPrivateUint<&mut PrivateContext> { // Very similar to `value_note::utils::decrement`. pub fn sub(self, subtrahend: u64, owner: AztecAddress, outgoing_viewer: AztecAddress) { - let owner_keys = get_current_public_keys(self.context, owner); - let outgoing_viewer_keys = get_current_public_keys(self.context, outgoing_viewer); + let owner_keys = get_public_keys(owner); + let outgoing_viewer_keys = get_public_keys(outgoing_viewer); // docs:start:pop_notes let options = NoteGetterOptions::with_filter(filter_notes_min_sum, subtrahend as Field); diff --git a/noir-projects/aztec-nr/value-note/src/utils.nr b/noir-projects/aztec-nr/value-note/src/utils.nr index f4919981818e..2caa06613973 100644 --- a/noir-projects/aztec-nr/value-note/src/utils.nr +++ b/noir-projects/aztec-nr/value-note/src/utils.nr @@ -1,7 +1,7 @@ use dep::aztec::prelude::{AztecAddress, PrivateContext, PrivateSet, NoteGetterOptions}; use dep::aztec::note::note_getter_options::SortOrder; use dep::aztec::encrypted_logs::encrypted_note_emission::encode_and_encrypt_note_with_keys; -use dep::aztec::keys::getters::get_current_public_keys; +use dep::aztec::keys::getters::get_public_keys; use crate::{filter::filter_notes_min_sum, value_note::{ValueNote, VALUE_NOTE_LEN, VALUE_NOTE_BYTES_LEN}}; // Sort the note values (0th field) in descending order. @@ -19,8 +19,8 @@ pub fn increment( recipient: AztecAddress, outgoing_viewer: AztecAddress // docs:end:increment_args ) { - let recipient_keys = get_current_public_keys(balance.context, recipient); - let outgoing_viewer_ovpk_m = get_current_public_keys(balance.context, outgoing_viewer).ovpk_m; + let recipient_keys = get_public_keys(recipient); + let outgoing_viewer_ovpk_m = get_public_keys(outgoing_viewer).ovpk_m; let mut note = ValueNote::new(amount, recipient_keys.npk_m.hash()); // Insert the new note to the owner's set of notes and emit the log if value is non-zero. diff --git a/noir-projects/noir-contracts/Nargo.toml b/noir-projects/noir-contracts/Nargo.toml index 0b468be1c806..2abc3ddb90a6 100644 --- a/noir-projects/noir-contracts/Nargo.toml +++ b/noir-projects/noir-contracts/Nargo.toml @@ -25,7 +25,6 @@ members = [ "contracts/escrow_contract", "contracts/fee_juice_contract", "contracts/import_test_contract", - "contracts/key_registry_contract", "contracts/inclusion_proofs_contract", "contracts/lending_contract", "contracts/nft_contract", diff --git a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr index 7be2b0de5144..f78bd9c53dad 100644 --- a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr @@ -7,7 +7,7 @@ contract AppSubscription { use aztec::{ prelude::{AztecAddress, Map, PrivateMutable, SharedImmutable}, encrypted_logs::encrypted_note_emission::{encode_and_encrypt_note, encode_and_encrypt_note_with_keys}, - keys::getters::get_current_public_keys, protocol_types::constants::MAX_FIELD_VALUE, + keys::getters::get_public_keys, protocol_types::constants::MAX_FIELD_VALUE, utils::comparison::Comparator }; use authwit::auth::assert_current_call_valid_authwit; @@ -94,8 +94,8 @@ contract AppSubscription { &mut context ); - let subscriber_keys = get_current_public_keys(&mut context, subscriber); - let msg_sender_ovpk_m = get_current_public_keys(&mut context, context.msg_sender()).ovpk_m; + let subscriber_keys = get_public_keys(subscriber); + let msg_sender_ovpk_m = get_public_keys(context.msg_sender()).ovpk_m; let mut subscription_note = SubscriptionNote::new(subscriber_keys.npk_m.hash(), expiry_block_number, tx_count); storage.subscriptions.at(subscriber).initialize_or_replace(&mut subscription_note).emit( diff --git a/noir-projects/noir-contracts/contracts/card_game_contract/src/cards.nr b/noir-projects/noir-contracts/contracts/card_game_contract/src/cards.nr index 543e33357d07..69c2bc5eff40 100644 --- a/noir-projects/noir-contracts/contracts/card_game_contract/src/cards.nr +++ b/noir-projects/noir-contracts/contracts/card_game_contract/src/cards.nr @@ -4,7 +4,7 @@ use dep::aztec::{ context::UnconstrainedContext, protocol_types::{traits::{ToField, Serialize, FromField}, constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL}, encrypted_logs::encrypted_note_emission::encode_and_encrypt_note_with_keys, - keys::getters::get_current_public_keys, state_vars::PrivateSet, note::constants::MAX_NOTES_PER_PAGE + keys::getters::get_public_keys, state_vars::PrivateSet, note::constants::MAX_NOTES_PER_PAGE }; use dep::value_note::value_note::ValueNote; @@ -103,10 +103,10 @@ impl Deck { impl Deck<&mut PrivateContext> { pub fn add_cards(&mut self, cards: [Card; N], owner: AztecAddress) -> [CardNote] { - let owner_keys = get_current_public_keys(self.set.context, owner); + let owner_keys = get_public_keys(owner); let owner_ivpk_m = owner_keys.ivpk_m; let owner_npk_m_hash = owner_keys.npk_m.hash(); - let msg_sender_ovpk_m = get_current_public_keys(self.set.context, self.set.context.msg_sender()).ovpk_m; + let msg_sender_ovpk_m = get_public_keys(self.set.context.msg_sender()).ovpk_m; let mut inserted_cards = &[]; for card in cards { @@ -151,7 +151,7 @@ pub fn get_pack_cards( owner: AztecAddress, context: &mut PrivateContext ) -> [Card; PACK_CARDS] { - let owner_npk_m_hash = get_current_public_keys(context, owner).npk_m.hash(); + let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); // generate pseudo randomness deterministically from 'seed' and user secret let secret = context.request_nsk_app(owner_npk_m_hash); diff --git a/noir-projects/noir-contracts/contracts/child_contract/src/main.nr b/noir-projects/noir-contracts/contracts/child_contract/src/main.nr index 50074872b2ae..46f23ea20f37 100644 --- a/noir-projects/noir-contracts/contracts/child_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/child_contract/src/main.nr @@ -6,7 +6,7 @@ contract Child { context::gas::GasOpts, protocol_types::{abis::call_context::CallContext}, note::{note_getter_options::NoteGetterOptions, note_header::NoteHeader}, encrypted_logs::encrypted_note_emission::encode_and_encrypt_note_with_keys, - keys::getters::get_current_public_keys, utils::comparison::Comparator + keys::getters::get_public_keys, utils::comparison::Comparator }; use dep::value_note::value_note::ValueNote; @@ -52,7 +52,7 @@ contract Child { #[aztec(private)] fn private_set_value(new_value: Field, owner: AztecAddress) -> Field { - let owner_keys = get_current_public_keys(&mut context, owner); + let owner_keys = get_public_keys(owner); let mut note = ValueNote::new(new_value, owner_keys.npk_m.hash()); storage.a_map_with_private_values.at(owner).insert(&mut note).emit(encode_and_encrypt_note_with_keys(&mut context, owner_keys.ovpk_m, owner_keys.ivpk_m, owner)); diff --git a/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/main.nr b/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/main.nr index 4e0feeceb05b..504c46216db8 100644 --- a/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/main.nr @@ -5,7 +5,7 @@ contract Crowdfunding { // docs:start:all-deps use dep::aztec::{ encrypted_logs::encrypted_note_emission::encode_and_encrypt_note_with_keys, - keys::getters::get_current_public_keys, prelude::{AztecAddress, PrivateSet, SharedImmutable}, + keys::getters::get_public_keys, prelude::{AztecAddress, PrivateSet, SharedImmutable}, utils::comparison::Comparator }; use dep::aztec::unencrypted_logs::unencrypted_event_emission::encode_event; @@ -70,7 +70,7 @@ contract Crowdfunding { // 3) Create a value note for the donor so that he can later on claim a rewards token in the Claim // contract by proving that the hash of this note exists in the note hash tree. - let donor_keys = get_current_public_keys(&mut context, donor); + let donor_keys = get_public_keys(donor); // docs:start:valuenote_new let mut note = ValueNote::new(amount as Field, donor_keys.npk_m.hash()); // docs:end:valuenote_new diff --git a/noir-projects/noir-contracts/contracts/delegated_on_contract/src/main.nr b/noir-projects/noir-contracts/contracts/delegated_on_contract/src/main.nr index c1ae841fa6ca..11f03378e7cc 100644 --- a/noir-projects/noir-contracts/contracts/delegated_on_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/delegated_on_contract/src/main.nr @@ -6,7 +6,7 @@ contract DelegatedOn { }; use dep::aztec::{ encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, - keys::getters::get_current_public_keys, utils::comparison::Comparator + keys::getters::get_public_keys, utils::comparison::Comparator }; use dep::value_note::value_note::ValueNote; @@ -18,7 +18,7 @@ contract DelegatedOn { #[aztec(private)] fn private_set_value(new_value: Field, owner: AztecAddress) -> Field { - let owner_npk_m_hash = get_current_public_keys(&mut context, owner).npk_m.hash(); + let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); let mut note = ValueNote::new(new_value, owner_npk_m_hash); storage.a_map_with_private_values.at(owner).insert(&mut note).emit(encode_and_encrypt_note(&mut context, context.msg_sender(), owner)); diff --git a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr index 7a84beae36fb..ad002512902e 100644 --- a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr @@ -18,7 +18,7 @@ contract DocsExample { PrivateMutable, PrivateImmutable, PrivateSet, SharedImmutable }; use dep::aztec::encrypted_logs::encrypted_note_emission::{encode_and_encrypt_note, encode_and_encrypt_note_with_keys}; - use dep::aztec::keys::getters::get_current_public_keys; + use dep::aztec::keys::getters::get_public_keys; // how to import methods from other files/folders within your workspace use crate::types::{card_note::CardNote, leader::Leader}; @@ -167,7 +167,7 @@ contract DocsExample { // docs:start:initialize-private-mutable #[aztec(private)] fn initialize_private_immutable(randomness: Field, points: u8) { - let msg_sender_npk_m_hash = get_current_public_keys(&mut context, context.msg_sender()).npk_m.hash(); + let msg_sender_npk_m_hash = get_public_keys(context.msg_sender()).npk_m.hash(); let mut new_card = CardNote::new(points, randomness, msg_sender_npk_m_hash); storage.private_immutable.initialize(&mut new_card).emit(encode_and_encrypt_note(&mut context, context.msg_sender(), context.msg_sender())); @@ -177,7 +177,7 @@ contract DocsExample { #[aztec(private)] // msg_sender() is 0 at deploy time. So created another function fn initialize_private(randomness: Field, points: u8) { - let msg_sender_npk_m_hash = get_current_public_keys(&mut context, context.msg_sender()).npk_m.hash(); + let msg_sender_npk_m_hash = get_public_keys(context.msg_sender()).npk_m.hash(); let mut legendary_card = CardNote::new(points, randomness, msg_sender_npk_m_hash); // create and broadcast note @@ -186,7 +186,7 @@ contract DocsExample { #[aztec(private)] fn insert_notes(amounts: [u8; 3]) { - let sender_keys = get_current_public_keys(&mut context, context.msg_sender()); + let sender_keys = get_public_keys(context.msg_sender()); let sender_npk_m_hash = sender_keys.npk_m.hash(); for i in 0..amounts.len() { @@ -204,7 +204,7 @@ contract DocsExample { #[aztec(private)] fn insert_note(amount: u8, randomness: Field) { - let sender_npk_m_hash = get_current_public_keys(&mut context, context.msg_sender()).npk_m.hash(); + let sender_npk_m_hash = get_public_keys(context.msg_sender()).npk_m.hash(); let mut note = CardNote::new(amount, randomness, sender_npk_m_hash); storage.set.insert(&mut note).emit(encode_and_encrypt_note(&mut context, context.msg_sender(), context.msg_sender())); @@ -219,7 +219,7 @@ contract DocsExample { #[aztec(private)] fn update_legendary_card(randomness: Field, points: u8) { - let sender_npk_m_hash = get_current_public_keys(&mut context, context.msg_sender()).npk_m.hash(); + let sender_npk_m_hash = get_public_keys(context.msg_sender()).npk_m.hash(); let mut new_card = CardNote::new(points, randomness, sender_npk_m_hash); storage.legendary_card.replace(&mut new_card).emit(encode_and_encrypt_note(&mut context, context.msg_sender(), context.msg_sender())); @@ -231,7 +231,7 @@ contract DocsExample { // Ensure `points` > current value // Also serves as a e2e test that you can `get_note()` and then `replace()` - let sender_npk_m_hash = get_current_public_keys(&mut context, context.msg_sender()).npk_m.hash(); + let sender_npk_m_hash = get_public_keys(context.msg_sender()).npk_m.hash(); // docs:start:state_vars-PrivateMutableGet let card = storage.legendary_card.get_note().note; diff --git a/noir-projects/noir-contracts/contracts/easy_private_voting_contract/src/main.nr b/noir-projects/noir-contracts/contracts/easy_private_voting_contract/src/main.nr index 387e6b9fdf98..3bc0c0b687bb 100644 --- a/noir-projects/noir-contracts/contracts/easy_private_voting_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/easy_private_voting_contract/src/main.nr @@ -1,7 +1,7 @@ contract EasyPrivateVoting { // docs:start:imports use dep::aztec::prelude::{AztecAddress, Map, PublicMutable, SharedImmutable}; - use dep::aztec::keys::getters::get_historical_public_keys; + use dep::aztec::keys::getters::get_public_keys; // docs:end:imports // docs:start:storage_struct #[aztec(storage)] @@ -26,10 +26,7 @@ contract EasyPrivateVoting { // docs:start:cast_vote #[aztec(private)] // annotation to mark function as private and expose private context fn cast_vote(candidate: Field) { - // Below, we make sure to get our nullifier public key at a specific block. By pinning the nullifier public key at a specific block, - // rotating keys will have no effect on the nullifier being produced, and voting again after will fail because the same nullifier is computed each time the user votes. - let header_at_active_at_block = context.get_header_at(storage.active_at_block.read_private()); - let msg_sender_npk_m_hash = get_historical_public_keys(header_at_active_at_block, context.msg_sender()).npk_m.hash(); + let msg_sender_npk_m_hash = get_public_keys(context.msg_sender()).npk_m.hash(); let secret = context.request_nsk_app(msg_sender_npk_m_hash); // get secret key of caller of function let nullifier = std::hash::pedersen_hash([context.msg_sender().to_field(), secret]); // derive nullifier from sender and secret @@ -49,7 +46,7 @@ contract EasyPrivateVoting { // docs:end:add_to_tally_public // docs:start:end_vote - #[aztec(public)] + #[aztec(public)] fn end_vote() { assert(storage.admin.read().eq(context.msg_sender()), "Only admin can end votes"); // assert that caller is admin storage.vote_ended.write(true); diff --git a/noir-projects/noir-contracts/contracts/ecdsa_k_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/ecdsa_k_account_contract/src/main.nr index b80c6d00f98e..312805f18020 100644 --- a/noir-projects/noir-contracts/contracts/ecdsa_k_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/ecdsa_k_account_contract/src/main.nr @@ -4,7 +4,7 @@ contract EcdsaKAccount { use dep::aztec::prelude::{PrivateContext, PrivateImmutable}; use dep::aztec::{ encrypted_logs::encrypted_note_emission::encode_and_encrypt_note_with_keys, - keys::getters::get_current_public_keys + keys::getters::get_public_keys }; use dep::authwit::{ @@ -24,7 +24,7 @@ contract EcdsaKAccount { #[aztec(initializer)] fn constructor(signing_pub_key_x: [u8; 32], signing_pub_key_y: [u8; 32]) { let this = context.this_address(); - let this_keys = get_current_public_keys(&mut context, this); + let this_keys = get_public_keys(this); // Not emitting outgoing for msg_sender here to not have to register keys for the contract through which we // deploy this (typically MultiCallEntrypoint). I think it's ok here as I feel the outgoing here is not that // important. diff --git a/noir-projects/noir-contracts/contracts/ecdsa_r_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/ecdsa_r_account_contract/src/main.nr index 9c9ca530495b..f5c7860212d0 100644 --- a/noir-projects/noir-contracts/contracts/ecdsa_r_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/ecdsa_r_account_contract/src/main.nr @@ -3,7 +3,7 @@ contract EcdsaRAccount { use dep::aztec::prelude::{PrivateContext, PrivateImmutable}; use dep::aztec::{ encrypted_logs::encrypted_note_emission::encode_and_encrypt_note_with_keys, - keys::getters::get_current_public_keys + keys::getters::get_public_keys }; use dep::authwit::{ @@ -23,7 +23,7 @@ contract EcdsaRAccount { #[aztec(initializer)] fn constructor(signing_pub_key_x: [u8; 32], signing_pub_key_y: [u8; 32]) { let this = context.this_address(); - let this_keys = get_current_public_keys(&mut context, this); + let this_keys = get_public_keys(this); // Not emitting outgoing for msg_sender here to not have to register keys for the contract through which we // deploy this (typically MultiCallEntrypoint). I think it's ok here as I feel the outgoing here is not that // important. diff --git a/noir-projects/noir-contracts/contracts/escrow_contract/src/main.nr b/noir-projects/noir-contracts/contracts/escrow_contract/src/main.nr index 9d17a6833fae..35a243c02358 100644 --- a/noir-projects/noir-contracts/contracts/escrow_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/escrow_contract/src/main.nr @@ -3,7 +3,7 @@ contract Escrow { use dep::aztec::prelude::{AztecAddress, PrivateImmutable}; use dep::aztec::{ encrypted_logs::encrypted_note_emission::encode_and_encrypt_note_with_keys, - keys::getters::get_current_public_keys + keys::getters::get_public_keys }; // docs:start:addressnote_import @@ -20,8 +20,8 @@ contract Escrow { #[aztec(private)] #[aztec(initializer)] fn constructor(owner: AztecAddress) { - let owner_keys = get_current_public_keys(&mut context, owner); - let msg_sender_keys = get_current_public_keys(&mut context, context.msg_sender()); + let owner_keys = get_public_keys(owner); + let msg_sender_keys = get_public_keys(context.msg_sender()); // docs:start:addressnote_new let mut note = AddressNote::new(owner, owner_keys.npk_m.hash()); // docs:end:addressnote_new diff --git a/noir-projects/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr b/noir-projects/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr index 0d654b91c428..d5d6cfe78c1a 100644 --- a/noir-projects/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr @@ -1,10 +1,7 @@ // A demonstration of inclusion and non-inclusion proofs. contract InclusionProofs { use dep::aztec::prelude::{AztecAddress, NoteGetterOptions, Map, PrivateSet, PublicMutable}; - use dep::aztec::{ - encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, - keys::getters::get_current_public_keys - }; + use dep::aztec::{encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, keys::getters::get_public_keys}; use dep::aztec::{note::note_getter_options::NoteStatus}; // docs:start:value_note_imports @@ -28,7 +25,7 @@ contract InclusionProofs { #[aztec(private)] fn create_note(owner: AztecAddress, value: Field) { let owner_private_values = storage.private_values.at(owner); - let owner_npk_m_hash = get_current_public_keys(&mut context, owner).npk_m.hash(); + let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); let mut note = ValueNote::new(value, owner_npk_m_hash); owner_private_values.insert(&mut note).emit(encode_and_encrypt_note(&mut context, context.msg_sender(), owner)); @@ -72,7 +69,7 @@ contract InclusionProofs { block_number: u32 // The block at which we'll prove that the note exists ) { let header = context.get_header(); - let owner_npk_m_hash = get_current_public_keys(&mut context, owner).npk_m.hash(); + let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); let mut note = ValueNote::new(1, owner_npk_m_hash); let header = if (use_block_number) { diff --git a/noir-projects/noir-contracts/contracts/key_registry_contract/Nargo.toml b/noir-projects/noir-contracts/contracts/key_registry_contract/Nargo.toml deleted file mode 100644 index cae3a7ead7ee..000000000000 --- a/noir-projects/noir-contracts/contracts/key_registry_contract/Nargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "key_registry_contract" -authors = [""] -compiler_version = ">=0.25.0" -type = "contract" - -[dependencies] -aztec = { path = "../../../aztec-nr/aztec" } -authwit = { path = "../../../aztec-nr/authwit" } diff --git a/noir-projects/noir-contracts/contracts/key_registry_contract/src/main.nr b/noir-projects/noir-contracts/contracts/key_registry_contract/src/main.nr deleted file mode 100644 index d4ff344ed17d..000000000000 --- a/noir-projects/noir-contracts/contracts/key_registry_contract/src/main.nr +++ /dev/null @@ -1,63 +0,0 @@ -contract KeyRegistry { - use dep::authwit::auth::assert_current_call_valid_authwit_public; - - use dep::aztec::{ - keys::{PublicKeys, stored_keys::StoredKeys, public_keys::NpkM}, - state_vars::{PublicMutable, Map}, protocol_types::address::{AztecAddress, PartialAddress} - }; - - #[aztec(storage)] - struct Storage { - current_keys: Map>, - } - - impl Storage { - // The init function is typically automatically generated by the macros - here we implement it manually in order - // to have control over which storage slot is assigned to the current_keys state variable. - fn init(context: Context) -> Self { - Storage { - // Ideally we'd do KEY_REGISTRY_STORAGE_SLOT instead of hardcoding the 1 here, but that is currently - // causing compilation errors. - // TODO(#7829): fix this - current_keys: Map::new( - context, - 1, - |context, slot| { PublicMutable::new(context, slot) } - ) - } - } - } - - unconstrained fn get_current_keys(account: AztecAddress) -> pub PublicKeys { - // If #7524 were to be implemented, this function could be called by an oracle from an unconstrained function - // in order to produce the preimage of the stored hash, and hence prove the correctness of the keys. - storage.current_keys.at(account).read().public_keys - } - - #[aztec(public)] - fn register_initial_keys(account: AztecAddress, partial_address: PartialAddress, keys: PublicKeys) { - let computed_address = AztecAddress::compute(keys.hash(), partial_address); - assert(computed_address.eq(account), "Computed address does not match supplied address"); - - storage.current_keys.at(account).write(StoredKeys::new(keys)); - } - - #[aztec(public)] - fn rotate_npk_m(account: AztecAddress, new_npk_m: NpkM, nonce: Field) { - if (!account.eq(context.msg_sender())) { - assert_current_call_valid_authwit_public(&mut context, account); - } else { - assert(nonce == 0, "invalid nonce"); - } - - let account_key_storage = storage.current_keys.at(account); - - // We read all other current keys so that we can compute the new hash - we can't update just the npk. This means - // updating all keys at once costs the same as updating just one (unless setting public storage to its current - // value is cheaper than changing it, e.g. EIP-2200). - let mut current_keys = account_key_storage.read().public_keys; - current_keys.npk_m = new_npk_m; - - account_key_storage.write(StoredKeys::new(current_keys)); - } -} diff --git a/noir-projects/noir-contracts/contracts/nft_contract/src/main.nr b/noir-projects/noir-contracts/contracts/nft_contract/src/main.nr index 2dfa13de5456..02e84a806ecc 100644 --- a/noir-projects/noir-contracts/contracts/nft_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/nft_contract/src/main.nr @@ -8,9 +8,8 @@ contract NFT { use dep::aztec::{ prelude::{NoteGetterOptions, NoteViewerOptions, Map, PublicMutable, SharedImmutable, PrivateSet, AztecAddress}, encrypted_logs::{encrypted_note_emission::encode_and_encrypt_note_with_keys}, - hash::pedersen_hash, keys::getters::get_current_public_keys, - note::constants::MAX_NOTES_PER_PAGE, protocol_types::traits::is_empty, - utils::comparison::Comparator + hash::pedersen_hash, keys::getters::get_public_keys, note::constants::MAX_NOTES_PER_PAGE, + protocol_types::traits::is_empty, utils::comparison::Comparator }; use dep::authwit::auth::{assert_current_call_valid_authwit, assert_current_call_valid_authwit_public, compute_authwit_nullifier}; use crate::types::nft_note::{NFTNote, NFTNoteHidingPoint}; @@ -141,7 +140,7 @@ contract NFT { transient_storage_slot_randomness: Field ) { // We create a partial NFT note hiding point with unpopulated/zero token id for 'to' - let to_npk_m_hash = get_current_public_keys(&mut context, to).npk_m.hash(); + let to_npk_m_hash = get_public_keys(to).npk_m.hash(); let to_note_slot = storage.private_nfts.at(to).storage_slot; let hiding_point = NFTNoteHidingPoint::new(to_npk_m_hash, to_note_slot, note_randomness); @@ -230,8 +229,8 @@ contract NFT { ); assert(notes.len() == 1, "NFT not found when transferring"); - let from_ovpk_m = get_current_public_keys(&mut context, from).ovpk_m; - let to_keys = get_current_public_keys(&mut context, to); + let from_ovpk_m = get_public_keys(from).ovpk_m; + let to_keys = get_public_keys(to); let mut new_note = NFTNote::new(token_id, to_keys.npk_m.hash()); nfts.at(to).insert(&mut new_note).emit(encode_and_encrypt_note_with_keys(&mut context, from_ovpk_m, to_keys.ivpk_m, to)); diff --git a/noir-projects/noir-contracts/contracts/nft_contract/src/test/transfer_to_private.nr b/noir-projects/noir-contracts/contracts/nft_contract/src/test/transfer_to_private.nr index 6b1db2c5f689..63b3c6124604 100644 --- a/noir-projects/noir-contracts/contracts/nft_contract/src/test/transfer_to_private.nr +++ b/noir-projects/noir-contracts/contracts/nft_contract/src/test/transfer_to_private.nr @@ -1,6 +1,6 @@ use crate::test::utils; use dep::aztec::{ - hash::pedersen_hash, keys::getters::get_current_public_keys, prelude::{AztecAddress, NoteHeader}, + hash::pedersen_hash, keys::getters::get_public_keys, prelude::{AztecAddress, NoteHeader}, oracle::unsafe_rand::unsafe_rand, protocol_types::storage::map::derive_storage_slot_in_map }; use crate::{types::nft_note::NFTNote, NFT}; @@ -50,7 +50,7 @@ unconstrained fn transfer_to_private_to_a_different_account() { // Store the finalized note in the cache let mut context = env.private(); - let recipient_npk_m_hash = get_current_public_keys(&mut context, recipient).npk_m.hash(); + let recipient_npk_m_hash = get_public_keys(recipient).npk_m.hash(); let private_nfts_recipient_slot = derive_storage_slot_in_map(NFT::storage().private_nfts.slot, recipient); env.add_note( diff --git a/noir-projects/noir-contracts/contracts/nft_contract/src/test/utils.nr b/noir-projects/noir-contracts/contracts/nft_contract/src/test/utils.nr index 48487f1179f8..c9b7f1254830 100644 --- a/noir-projects/noir-contracts/contracts/nft_contract/src/test/utils.nr +++ b/noir-projects/noir-contracts/contracts/nft_contract/src/test/utils.nr @@ -1,5 +1,5 @@ use dep::aztec::{ - hash::pedersen_hash, keys::getters::get_current_public_keys, prelude::{AztecAddress, NoteHeader}, + hash::pedersen_hash, keys::getters::get_public_keys, prelude::{AztecAddress, NoteHeader}, test::helpers::{cheatcodes, test_environment::TestEnvironment}, protocol_types::storage::map::derive_storage_slot_in_map, oracle::{execution::{get_block_number, get_contract_address}, unsafe_rand::unsafe_rand, storage::storage_read} @@ -72,7 +72,7 @@ pub fn setup_mint_and_transfer_to_private(with_account_contracts: bool) -> (&mut // Store the finalized note in the cache let mut context = env.private(); - let owner_npk_m_hash = get_current_public_keys(&mut context, owner).npk_m.hash(); + let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); let private_nfts_owner_slot = derive_storage_slot_in_map(NFT::storage().private_nfts.slot, owner); env.add_note( diff --git a/noir-projects/noir-contracts/contracts/pending_note_hashes_contract/src/main.nr b/noir-projects/noir-contracts/contracts/pending_note_hashes_contract/src/main.nr index 021c304c75f1..2ea20972cb04 100644 --- a/noir-projects/noir-contracts/contracts/pending_note_hashes_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/pending_note_hashes_contract/src/main.nr @@ -9,7 +9,7 @@ contract PendingNoteHashes { use dep::aztec::protocol_types::constants::{MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, MAX_NOTE_HASHES_PER_CALL}; use dep::aztec::encrypted_logs::encrypted_note_emission::{encode_and_encrypt_note, encode_and_encrypt_note_with_keys}; use dep::aztec::note::note_emission::NoteEmission; - use dep::aztec::keys::getters::get_current_public_keys; + use dep::aztec::keys::getters::get_public_keys; #[aztec(storage)] struct Storage { @@ -30,7 +30,7 @@ contract PendingNoteHashes { ) -> Field { let owner_balance = storage.balances.at(owner); - let owner_npk_m_hash = get_current_public_keys(&mut context, owner).npk_m.hash(); + let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); let mut note = ValueNote::new(amount, owner_npk_m_hash); @@ -59,7 +59,7 @@ contract PendingNoteHashes { assert(notes.len() == 0); - let owner_npk_m_hash = get_current_public_keys(&mut context, owner).npk_m.hash(); + let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); // Insert note let mut note = ValueNote::new(amount, owner_npk_m_hash); @@ -77,7 +77,7 @@ contract PendingNoteHashes { fn insert_note(amount: Field, owner: AztecAddress, outgoing_viewer: AztecAddress) { let owner_balance = storage.balances.at(owner); - let owner_npk_m_hash = get_current_public_keys(&mut context, owner).npk_m.hash(); + let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); let mut note = ValueNote::new(amount, owner_npk_m_hash); @@ -96,7 +96,7 @@ contract PendingNoteHashes { ) { let mut owner_balance = storage.balances.at(owner); - let owner_npk_m_hash = get_current_public_keys(&mut context, owner).npk_m.hash(); + let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); let mut note = ValueNote::new(amount, owner_npk_m_hash); note.randomness = 2; @@ -111,7 +111,7 @@ contract PendingNoteHashes { fn insert_note_extra_emit(amount: Field, owner: AztecAddress, outgoing_viewer: AztecAddress) { let mut owner_balance = storage.balances.at(owner); - let owner_npk_m_hash = get_current_public_keys(&mut context, owner).npk_m.hash(); + let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); let mut note = ValueNote::new(amount, owner_npk_m_hash); @@ -329,10 +329,10 @@ contract PendingNoteHashes { fn test_emit_bad_note_log(owner: AztecAddress, outgoing_viewer: AztecAddress) { let owner_balance = storage.balances.at(owner); - let owner_keys = get_current_public_keys(&mut context, owner); + let owner_keys = get_public_keys(owner); let owner_npk_m_hash = owner_keys.npk_m.hash(); let owner_ivpk_m = owner_keys.ivpk_m; - let outgoing_viewer_ovpk_m = get_current_public_keys(&mut context, outgoing_viewer).ovpk_m; + let outgoing_viewer_ovpk_m = get_public_keys(outgoing_viewer).ovpk_m; let mut good_note = ValueNote::new(10, owner_npk_m_hash); // Insert good note with real log @@ -357,10 +357,10 @@ contract PendingNoteHashes { ) { let owner_balance = storage.balances.at(owner); - let owner_keys = get_current_public_keys(context, owner); + let owner_keys = get_public_keys(owner); let owner_npk_m_hash = owner_keys.npk_m.hash(); let owner_ivpk_m = owner_keys.ivpk_m; - let outgoing_viewer_ovpk_m = get_current_public_keys(context, outgoing_viewer).ovpk_m; + let outgoing_viewer_ovpk_m = get_public_keys(outgoing_viewer).ovpk_m; for i in 0..max_notes_per_call() { let mut note = ValueNote::new(i as Field, owner_npk_m_hash); diff --git a/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/main.nr index 882423aa75a6..7685bc99b3f5 100644 --- a/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/main.nr @@ -11,7 +11,7 @@ contract SchnorrAccount { entrypoint::{app::AppPayload, fee::FeePayload}, account::AccountActions, auth_witness::get_auth_witness, auth::{compute_authwit_nullifier, compute_authwit_message_hash} }; - use dep::aztec::{hash::compute_siloed_nullifier, keys::getters::get_current_public_keys}; + use dep::aztec::{hash::compute_siloed_nullifier, keys::getters::get_public_keys}; use dep::aztec::oracle::get_nullifier_membership_witness::get_low_nullifier_membership_witness; use crate::public_key_note::PublicKeyNote; @@ -26,7 +26,7 @@ contract SchnorrAccount { #[aztec(initializer)] fn constructor(signing_pub_key_x: Field, signing_pub_key_y: Field) { let this = context.this_address(); - let this_keys = get_current_public_keys(&mut context, this); + let this_keys = get_public_keys(this); // Not emitting outgoing for msg_sender here to not have to register keys for the contract through which we // deploy this (typically MultiCallEntrypoint). I think it's ok here as I feel the outgoing here is not that // important. diff --git a/noir-projects/noir-contracts/contracts/spam_contract/src/main.nr b/noir-projects/noir-contracts/contracts/spam_contract/src/main.nr index 9ee7bb6502cb..78d0c5d162ad 100644 --- a/noir-projects/noir-contracts/contracts/spam_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/spam_contract/src/main.nr @@ -6,7 +6,7 @@ contract Spam { use dep::aztec::{ prelude::{Map, AztecAddress, PublicMutable}, encrypted_logs::{encrypted_note_emission::encode_and_encrypt_note_with_keys_unconstrained}, - keys::getters::get_current_public_keys, + keys::getters::get_public_keys, protocol_types::{ hash::poseidon2_hash_with_separator, constants::{ @@ -27,7 +27,7 @@ contract Spam { #[aztec(private)] fn spam(nullifier_seed: Field, nullifier_count: u32, call_public: bool) { let caller = context.msg_sender(); - let caller_keys = get_current_public_keys(&mut context, caller); + let caller_keys = get_public_keys(caller); let amount = U128::from_integer(1); for _ in 0..MAX_NOTE_HASHES_PER_CALL { diff --git a/noir-projects/noir-contracts/contracts/static_child_contract/src/main.nr b/noir-projects/noir-contracts/contracts/static_child_contract/src/main.nr index 828f077d95de..4d6422e14fea 100644 --- a/noir-projects/noir-contracts/contracts/static_child_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/static_child_contract/src/main.nr @@ -6,7 +6,7 @@ contract StaticChild { context::{PublicContext, gas::GasOpts}, protocol_types::{abis::{call_context::CallContext}}, note::{note_getter_options::NoteGetterOptions, note_header::NoteHeader}, encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, - keys::getters::get_current_public_keys, utils::comparison::Comparator + keys::getters::get_public_keys, utils::comparison::Comparator }; use dep::value_note::value_note::ValueNote; @@ -41,7 +41,7 @@ contract StaticChild { #[aztec(private)] #[aztec(view)] fn private_illegal_set_value(new_value: Field, owner: AztecAddress) -> Field { - let owner_npk_m_hash = get_current_public_keys(&mut context, owner).npk_m.hash(); + let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); let mut note = ValueNote::new(new_value, owner_npk_m_hash); storage.a_private_value.insert(&mut note).emit(encode_and_encrypt_note(&mut context, context.msg_sender(), owner)); new_value @@ -54,7 +54,7 @@ contract StaticChild { owner: AztecAddress, outgoing_viewer: AztecAddress ) -> Field { - let owner_npk_m_hash = get_current_public_keys(&mut context, owner).npk_m.hash(); + let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); let mut note = ValueNote::new(new_value, owner_npk_m_hash); storage.a_private_value.insert(&mut note).emit(encode_and_encrypt_note(&mut context, outgoing_viewer, owner)); new_value @@ -64,7 +64,7 @@ contract StaticChild { #[aztec(private)] #[aztec(view)] fn private_get_value(amount: Field, owner: AztecAddress) -> Field { - let owner_npk_m_hash = get_current_public_keys(&mut context, owner).npk_m.hash(); + let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); let mut options = NoteGetterOptions::new(); options = options.select(ValueNote::properties().value, Comparator.EQ, amount).select( ValueNote::properties().npk_m_hash, diff --git a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr index bf982ad90488..462d125c5f25 100644 --- a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr @@ -12,9 +12,8 @@ contract Test { use dep::aztec::protocol_types::{ abis::private_circuit_public_inputs::PrivateCircuitPublicInputs, - constants::{MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, CANONICAL_KEY_REGISTRY_ADDRESS}, - traits::{Serialize, ToField, FromField}, point::Point, scalar::Scalar, - storage::map::derive_storage_slot_in_map + constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, traits::{Serialize, ToField, FromField}, + point::Point, scalar::Scalar, storage::map::derive_storage_slot_in_map }; use dep::aztec::encrypted_logs::header::EncryptedLogHeader; @@ -22,7 +21,7 @@ contract Test { use dep::aztec::encrypted_logs::outgoing_body::EncryptedLogOutgoingBody; use dep::aztec::note::constants::MAX_NOTES_PER_PAGE; - use dep::aztec::keys::getters::get_current_public_keys; + use dep::aztec::keys::getters::get_public_keys; use dep::aztec::state_vars::{shared_mutable::SharedMutablePrivateGetter}; @@ -64,7 +63,7 @@ contract Test { #[aztec(private)] fn get_master_incoming_viewing_public_key(address: AztecAddress) -> [Field; 2] { - let ivpk_m = get_current_public_keys(&mut context, address).ivpk_m; + let ivpk_m = get_public_keys(address).ivpk_m; [ivpk_m.inner.x, ivpk_m.inner.y] } @@ -99,7 +98,7 @@ contract Test { storage_slot != storage.example_constant.get_storage_slot(), "this storage slot is reserved for example_constant" ); - let owner_npk_m_hash = get_current_public_keys(&mut context, owner).npk_m.hash(); + let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); let mut note = ValueNote::new(value, owner_npk_m_hash); create_note(&mut context, storage_slot, &mut note).emit(encode_and_encrypt_note(&mut context, outgoing_viewer, owner)); @@ -267,8 +266,8 @@ contract Test { outgoing_viewer: AztecAddress, nest: bool ) { - let owner_ivpk_m = get_current_public_keys(&mut context, owner).ivpk_m; - let outgoing_viewer_ovpk_m = get_current_public_keys(&mut context, outgoing_viewer).ovpk_m; + let owner_ivpk_m = get_public_keys(owner).ivpk_m; + let outgoing_viewer_ovpk_m = get_public_keys(outgoing_viewer).ovpk_m; let event = ExampleEvent { value0: fields[0], value1: fields[1], value2: fields[2], value3: fields[3], value4: fields[4] }; @@ -309,7 +308,7 @@ contract Test { Test::at(context.this_address()).call_create_note(value, owner, outgoing_viewer, storage_slot).call(&mut context); storage_slot += 1; - let owner_npk_m_hash = get_current_public_keys(&mut context, owner).npk_m.hash(); + let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); let mut note = ValueNote::new(value + 1, owner_npk_m_hash); create_note(&mut context, storage_slot, &mut note).emit(encode_and_encrypt_note(&mut context, context.msg_sender(), owner)); @@ -503,7 +502,7 @@ contract Test { #[aztec(private)] fn test_nullifier_key_freshness(address: AztecAddress, public_nullifying_key: Point) { - assert_eq(get_current_public_keys(&mut context, address).npk_m.inner, public_nullifying_key); + assert_eq(get_public_keys(address).npk_m.inner, public_nullifying_key); } // Purely exists for testing diff --git a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr index d0aeac1b7cfa..01c3ee9a3b14 100644 --- a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr +++ b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr @@ -2,7 +2,7 @@ use dep::aztec::prelude::{AztecAddress, NoteGetterOptions, NoteViewerOptions, No use dep::aztec::{ context::{PrivateContext, UnconstrainedContext}, protocol_types::constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, - note::{note_emission::OuterNoteEmission}, keys::getters::get_current_public_keys + note::{note_emission::OuterNoteEmission}, keys::getters::get_public_keys }; use crate::types::{token_note::OwnedNote}; @@ -66,7 +66,7 @@ impl BalancesMap { let context = self.map.context; // We fetch the nullifier public key hash from the registry / from our PXE - let owner_npk_m_hash = get_current_public_keys(context, owner).npk_m.hash(); + let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); let mut addend_note = T::new(addend, owner_npk_m_hash); // docs:start:insert diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_contract/src/main.nr index a4e556c1b5b7..81cb3a7f8dac 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/main.nr @@ -25,7 +25,7 @@ contract Token { encrypted_note_emission::{encode_and_encrypt_note_with_keys, encode_and_encrypt_note_with_keys_unconstrained}, encrypted_event_emission::encode_and_encrypt_event_with_keys_unconstrained }, - keys::getters::get_current_public_keys, utils::comparison::Comparator + keys::getters::get_public_keys, utils::comparison::Comparator }; // docs:start:import_authwit @@ -222,7 +222,7 @@ contract Token { #[aztec(private)] fn privately_mint_private_note(amount: Field) { let caller = context.msg_sender(); - let caller_keys = get_current_public_keys(&mut context, caller); + let caller_keys = get_public_keys(caller); storage.balances.at(caller).add(caller_keys.npk_m, U128::from_integer(amount)).emit( encode_and_encrypt_note_with_keys(&mut context, caller_keys.ovpk_m, caller_keys.ivpk_m, caller) ); @@ -318,8 +318,8 @@ contract Token { // Note: Using context.msg_sender() as a sender below makes this incompatible with escrows because we send // outgoing logs to that address and to send outgoing logs you need to get a hold of ovsk_m. let from = context.msg_sender(); - let from_keys = get_current_public_keys(&mut context, from); - let to_keys = get_current_public_keys(&mut context, to); + let from_keys = get_public_keys(from); + let to_keys = get_public_keys(to); storage.balances.at(to).add(to_keys.npk_m, U128::from_integer(amount)).emit(encode_and_encrypt_note_with_keys(&mut context, from_keys.ovpk_m, to_keys.ivpk_m, to)); } // docs:end:redeem_shield @@ -333,7 +333,7 @@ contract Token { assert(nonce == 0, "invalid nonce"); } - let from_keys = get_current_public_keys(&mut context, from); + let from_keys = get_public_keys(from); storage.balances.at(from).sub(from_keys.npk_m, U128::from_integer(amount)).emit(encode_and_encrypt_note_with_keys(&mut context, from_keys.ovpk_m, from_keys.ivpk_m, from)); Token::at(context.this_address())._increase_public_balance(to, amount).enqueue(&mut context); @@ -345,8 +345,8 @@ contract Token { fn transfer(to: AztecAddress, amount: Field) { let from = context.msg_sender(); - let from_keys = get_current_public_keys(&mut context, from); - let to_keys = get_current_public_keys(&mut context, to); + let from_keys = get_public_keys(from); + let to_keys = get_public_keys(to); let amount = U128::from_integer(amount); @@ -459,8 +459,8 @@ contract Token { } // docs:end:assert_current_call_valid_authwit - let from_keys = get_current_public_keys(&mut context, from); - let to_keys = get_current_public_keys(&mut context, to); + let from_keys = get_public_keys(from); + let to_keys = get_public_keys(to); let amount = U128::from_integer(amount); // docs:start:increase_private_balance @@ -481,7 +481,7 @@ contract Token { assert(nonce == 0, "invalid nonce"); } - let from_keys = get_current_public_keys(&mut context, from); + let from_keys = get_public_keys(from); storage.balances.at(from).sub(from_keys.npk_m, U128::from_integer(amount)).emit(encode_and_encrypt_note_with_keys(&mut context, from_keys.ovpk_m, from_keys.ivpk_m, from)); Token::at(context.this_address())._reduce_total_supply(amount).enqueue(&mut context); @@ -502,9 +502,9 @@ contract Token { /// a limited set of fee paying contracts will be used and they will be known, searching for fingerprints /// by trying different fee payers is a feasible attack. /// - /// Note 1: fee_payer_npk is publicly available in a key registry contract under a fee_payer address. So if we have - /// a known set of fee payer contract addresses getting fee_payer_npk and fee_payer_slot is trivial (slot - /// is derived in a `Map<...>` as a hash of balances map slot and a fee payer address). + /// Note 1: fee_payer_npk is part of the fee_payer address preimage derivation, and is assumed to be known. So + // if we have a known set of fee payer contract addresses getting fee_payer_npk and fee_payer_slot is + // trivial (slot is derived in a `Map<...>` as a hash of balances map slot and a fee payer address). /// Note 2: fee_payer_point and user_point above are public information because they are passed as args to /// the public `complete_refund(...)` function. // docs:start:setup_refund @@ -521,8 +521,8 @@ contract Token { assert_current_call_valid_authwit(&mut context, user); // 2. Get all the relevant keys - let fee_payer_npk_m_hash = get_current_public_keys(&mut context, fee_payer).npk_m.hash(); - let user_keys = get_current_public_keys(&mut context, user); + let fee_payer_npk_m_hash = get_public_keys(fee_payer).npk_m.hash(); + let user_keys = get_public_keys(user); let user_npk_m_hash = user_keys.npk_m.hash(); // 3. Deduct the funded amount from the user's balance - this is a maximum fee a user is willing to pay diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/test/refunds.nr b/noir-projects/noir-contracts/contracts/token_contract/src/test/refunds.nr index ff307a31cca4..8371269af924 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/test/refunds.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/test/refunds.nr @@ -2,7 +2,7 @@ use crate::{test::utils, Token, types::token_note::TokenNote}; use dep::aztec::{ prelude::NoteHeader, protocol_types::storage::map::derive_storage_slot_in_map, - keys::getters::get_current_public_keys + keys::getters::get_public_keys }; use dep::authwit::cheatcodes as authwit_cheatcodes; @@ -33,8 +33,8 @@ unconstrained fn setup_refund_success() { env.call_private_void(setup_refund_from_call_interface); let mut context = env.private(); - let user_npk_m_hash = get_current_public_keys(&mut context, user).npk_m.hash(); - let fee_payer_npk_m_hash = get_current_public_keys(&mut context, fee_payer).npk_m.hash(); + let user_npk_m_hash = get_public_keys(user).npk_m.hash(); + let fee_payer_npk_m_hash = get_public_keys(fee_payer).npk_m.hash(); let fee_payer_balances_slot = derive_storage_slot_in_map(Token::storage().balances.slot, fee_payer); let user_balances_slot = derive_storage_slot_in_map(Token::storage().balances.slot, user); diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/balance_set.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/balance_set.nr index 25d0407c6bb8..0655c3a3b570 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/types/balance_set.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/balance_set.nr @@ -3,7 +3,7 @@ use dep::aztec::{ context::{PrivateContext, UnconstrainedContext}, protocol_types::constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, note::{note_getter::view_notes, note_emission::{NoteEmission, OuterNoteEmission}}, - keys::{getters::get_current_public_keys, public_keys::NpkM} + keys::{getters::get_public_keys, public_keys::NpkM} }; use crate::types::token_note::OwnedNote; 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 d84713c9e869..20bbbf818506 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -188,7 +188,6 @@ 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(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); diff --git a/yarn-project/aztec-node/src/aztec-node/server.ts b/yarn-project/aztec-node/src/aztec-node/server.ts index eb2a2771a039..ffa1eaf6b3c8 100644 --- a/yarn-project/aztec-node/src/aztec-node/server.ts +++ b/yarn-project/aztec-node/src/aztec-node/server.ts @@ -66,7 +66,6 @@ import { import { getCanonicalClassRegisterer } from '@aztec/protocol-contracts/class-registerer'; import { getCanonicalFeeJuice } from '@aztec/protocol-contracts/fee-juice'; import { getCanonicalInstanceDeployer } from '@aztec/protocol-contracts/instance-deployer'; -import { getCanonicalKeyRegistryAddress } from '@aztec/protocol-contracts/key-registry'; import { getCanonicalMultiCallEntrypointAddress } from '@aztec/protocol-contracts/multi-call-entrypoint'; import { GlobalVariableBuilder, SequencerClient } from '@aztec/sequencer-client'; import { PublicProcessorFactory, WASMSimulator, WorldStateDB, createSimulationProvider } from '@aztec/simulator'; @@ -797,7 +796,6 @@ export class AztecNodeService implements AztecNode { classRegisterer: getCanonicalClassRegisterer().address, feeJuice: getCanonicalFeeJuice().address, instanceDeployer: getCanonicalInstanceDeployer().address, - keyRegistry: getCanonicalKeyRegistryAddress(), multiCallEntrypoint: getCanonicalMultiCallEntrypointAddress(), }); } diff --git a/yarn-project/aztec.js/src/account/interface.ts b/yarn-project/aztec.js/src/account/interface.ts index cafef217f9e1..eb0c093af0e9 100644 --- a/yarn-project/aztec.js/src/account/interface.ts +++ b/yarn-project/aztec.js/src/account/interface.ts @@ -1,6 +1,6 @@ import { type AuthWitness, type CompleteAddress } from '@aztec/circuit-types'; import { type AztecAddress } from '@aztec/circuits.js'; -import { type Fq, type Fr } from '@aztec/foundation/fields'; +import { type Fr } from '@aztec/foundation/fields'; import { type EntrypointInterface } from '../entrypoint/entrypoint.js'; @@ -32,20 +32,4 @@ export interface AccountInterface extends EntrypointInterface, AuthWitnessProvid /** Returns the rollup version for this account */ getVersion(): Fr; } - -/** - * Handler for interfacing with an account's ability to rotate its keys. - */ -export interface AccountKeyRotationInterface { - /** - * Rotates the account master nullifier key pair. - * @param newNskM - The new master nullifier secret key we want to use. - * @remarks - This function also calls the canonical key registry with the account's new derived master nullifier public key. - * We are doing it this way to avoid user error, in the case that a user rotates their keys in the key registry, - * but fails to do so in the key store. This leads to unspendable notes. - * - * This does not hinder our ability to spend notes tied to a previous master nullifier public key, provided we have the master nullifier secret key for it. - */ - rotateNullifierKeys(newNskM: Fq): Promise; -} // docs:end:account-interface diff --git a/yarn-project/aztec.js/src/account/wallet.ts b/yarn-project/aztec.js/src/account/wallet.ts index 5dc257bca01e..3d7a2b7407a4 100644 --- a/yarn-project/aztec.js/src/account/wallet.ts +++ b/yarn-project/aztec.js/src/account/wallet.ts @@ -1,13 +1,12 @@ import { type AuthWitness, type PXE } from '@aztec/circuit-types'; import { type IntentAction, type IntentInnerHash } from '../utils/authwit.js'; -import { type AccountInterface, type AccountKeyRotationInterface } from './interface.js'; +import { type AccountInterface } from './interface.js'; /** * The wallet interface. */ export type Wallet = AccountInterface & - PXE & - AccountKeyRotationInterface & { + PXE & { createAuthWit(intent: IntentInnerHash | IntentAction): Promise; }; diff --git a/yarn-project/aztec.js/src/contract/contract.test.ts b/yarn-project/aztec.js/src/contract/contract.test.ts index 73076d9b4568..ec677ed6ecdf 100644 --- a/yarn-project/aztec.js/src/contract/contract.test.ts +++ b/yarn-project/aztec.js/src/contract/contract.test.ts @@ -39,7 +39,6 @@ describe('Contract Class', () => { classRegisterer: AztecAddress.random(), feeJuice: AztecAddress.random(), instanceDeployer: AztecAddress.random(), - keyRegistry: AztecAddress.random(), multiCallEntrypoint: AztecAddress.random(), }, }; diff --git a/yarn-project/aztec.js/src/wallet/account_wallet.ts b/yarn-project/aztec.js/src/wallet/account_wallet.ts index 9eab8dd9866a..cdf59fb63a43 100644 --- a/yarn-project/aztec.js/src/wallet/account_wallet.ts +++ b/yarn-project/aztec.js/src/wallet/account_wallet.ts @@ -1,5 +1,5 @@ import { type AuthWitness, type PXE, type TxExecutionRequest } from '@aztec/circuit-types'; -import { AztecAddress, CANONICAL_KEY_REGISTRY_ADDRESS, Fq, Fr, derivePublicKeyFromSecretKey } from '@aztec/circuits.js'; +import { type AztecAddress, Fr } from '@aztec/circuits.js'; import { type ABIParameterVisibility, type FunctionAbi, FunctionType } from '@aztec/foundation/abi'; import { AuthRegistryAddress } from '@aztec/protocol-contracts/auth-registry'; @@ -161,30 +161,6 @@ export class AccountWallet extends BaseWallet { return results; } - /** - * Rotates the account master nullifier key pair. - * @param newNskM - The new master nullifier secret key we want to use. - * @remarks - This function also calls the canonical key registry with the account's new derived master nullifier public key. - * We are doing it this way to avoid user error, in the case that a user rotates their keys in the key registry, - * but fails to do so in the key store. This leads to unspendable notes. - * - * This does not hinder our ability to spend notes tied to a previous master nullifier public key, provided we have the master nullifier secret key for it. - */ - public async rotateNullifierKeys(newNskM: Fq = Fq.random()): Promise { - // We rotate our secret key in the keystore first, because if the subsequent interaction fails, there are no bad side-effects. - // If vice versa (the key registry is called first), but the call to the PXE fails, we will end up in a situation with unspendable notes, as we have not committed our - // nullifier secret key to our wallet. - await this.pxe.rotateNskM(this.getAddress(), newNskM); - const interaction = new ContractFunctionInteraction( - this, - AztecAddress.fromBigInt(CANONICAL_KEY_REGISTRY_ADDRESS), - this.getRotateNpkMAbi(), - [this.getAddress(), derivePublicKeyFromSecretKey(newNskM).toWrappedNoirStruct(), Fr.ZERO], - ); - - await interaction.send().wait(); - } - /** Returns the complete address of the account that implements this wallet. */ public getCompleteAddress() { return this.account.getCompleteAddress(); @@ -252,64 +228,4 @@ export class AccountWallet extends BaseWallet { returnTypes: [{ kind: 'boolean' }], }; } - - private getRotateNpkMAbi(): FunctionAbi { - return { - name: 'rotate_npk_m', - isInitializer: false, - functionType: FunctionType.PUBLIC, - isInternal: false, - isStatic: false, - parameters: [ - { - name: 'address', - type: { - fields: [{ name: 'inner', type: { kind: 'field' } }], - kind: 'struct', - path: 'authwit::aztec::protocol_types::address::aztec_address::AztecAddress', - }, - visibility: 'private' as ABIParameterVisibility, - }, - { - name: 'new_npk_m', - type: { - fields: [ - { - name: 'inner', - type: { - fields: [ - { - name: 'x', - type: { - kind: 'field', - }, - }, - { - name: 'y', - type: { - kind: 'field', - }, - }, - { - name: 'is_infinite', - type: { - kind: 'boolean', - }, - }, - ], - kind: 'struct', - path: 'std::embedded_curve_ops::EmbeddedCurvePoint', - }, - }, - ], - kind: 'struct', - path: 'aztec::keys::public_keys::NpkM', - }, - visibility: 'private' as ABIParameterVisibility, - }, - { name: 'nonce', type: { kind: 'field' }, visibility: 'private' as ABIParameterVisibility }, - ], - returnTypes: [], - }; - } } diff --git a/yarn-project/aztec.js/src/wallet/base_wallet.ts b/yarn-project/aztec.js/src/wallet/base_wallet.ts index d9150a87ac99..b6add2cf1189 100644 --- a/yarn-project/aztec.js/src/wallet/base_wallet.ts +++ b/yarn-project/aztec.js/src/wallet/base_wallet.ts @@ -24,7 +24,6 @@ import { type NoteProcessorStats } from '@aztec/circuit-types/stats'; import { type AztecAddress, type CompleteAddress, - type Fq, type Fr, type L1_TO_L2_MSG_TREE_HEIGHT, type PartialAddress, @@ -54,8 +53,6 @@ export abstract class BaseWallet implements Wallet { abstract createAuthWit(intent: Fr | Buffer | IntentInnerHash | IntentAction): Promise; - abstract rotateNullifierKeys(newNskM: Fq): Promise; - setScopes(scopes: AztecAddress[]) { this.scopes = scopes; } @@ -82,9 +79,6 @@ export abstract class BaseWallet implements Wallet { registerAccount(secretKey: Fr, partialAddress: PartialAddress): Promise { return this.pxe.registerAccount(secretKey, partialAddress); } - rotateNskM(address: AztecAddress, secretKey: Fq) { - return this.pxe.rotateNskM(address, secretKey); - } registerRecipient(account: CompleteAddress): Promise { return this.pxe.registerRecipient(account); } diff --git a/yarn-project/aztec.js/src/wallet/signerless_wallet.ts b/yarn-project/aztec.js/src/wallet/signerless_wallet.ts index 2f73cca8c270..0231d79b01ac 100644 --- a/yarn-project/aztec.js/src/wallet/signerless_wallet.ts +++ b/yarn-project/aztec.js/src/wallet/signerless_wallet.ts @@ -1,5 +1,5 @@ import { type AuthWitness, type PXE, type TxExecutionRequest } from '@aztec/circuit-types'; -import { type CompleteAddress, type Fq, type Fr } from '@aztec/circuits.js'; +import { type CompleteAddress, type Fr } from '@aztec/circuits.js'; import { DefaultEntrypoint } from '../entrypoint/default_entrypoint.js'; import { type EntrypointInterface, type ExecutionRequestInit } from '../entrypoint/entrypoint.js'; @@ -42,8 +42,4 @@ export class SignerlessWallet extends BaseWallet { createAuthWit(_intent: Fr | Buffer | IntentInnerHash | IntentAction): Promise { throw new Error('SignerlessWallet: Method createAuthWit not implemented.'); } - - rotateNullifierKeys(_newNskM: Fq): Promise { - throw new Error('SignerlessWallet: Method rotateNullifierKeys not implemented.'); - } } diff --git a/yarn-project/aztec/src/sandbox.ts b/yarn-project/aztec/src/sandbox.ts index f5f9464445c6..30c38f5b3a7a 100644 --- a/yarn-project/aztec/src/sandbox.ts +++ b/yarn-project/aztec/src/sandbox.ts @@ -3,7 +3,7 @@ import { type AztecNodeConfig, AztecNodeService, getConfigEnvVars } from '@aztec import { AnvilTestWatcher, EthCheatCodes, SignerlessWallet } from '@aztec/aztec.js'; import { DefaultMultiCallEntrypoint } from '@aztec/aztec.js/entrypoint'; import { type AztecNode } from '@aztec/circuit-types'; -import { deployCanonicalAuthRegistry, deployCanonicalKeyRegistry, deployCanonicalL2FeeJuice } from '@aztec/cli/misc'; +import { deployCanonicalAuthRegistry, deployCanonicalL2FeeJuice } from '@aztec/cli/misc'; import { type DeployL1Contracts, type L1ContractArtifactsForDeployment, @@ -185,9 +185,6 @@ export async function createSandbox(config: Partial = {}) { const node = await createAztecNode(aztecNodeConfig, client); const pxe = await createAztecPXE(node); - await deployCanonicalKeyRegistry( - new SignerlessWallet(pxe, new DefaultMultiCallEntrypoint(aztecNodeConfig.l1ChainId, aztecNodeConfig.version)), - ); await deployCanonicalAuthRegistry( new SignerlessWallet(pxe, new DefaultMultiCallEntrypoint(aztecNodeConfig.l1ChainId, aztecNodeConfig.version)), ); diff --git a/yarn-project/circuit-types/src/interfaces/pxe.ts b/yarn-project/circuit-types/src/interfaces/pxe.ts index 37f6e0cbfa5e..c494114350ad 100644 --- a/yarn-project/circuit-types/src/interfaces/pxe.ts +++ b/yarn-project/circuit-types/src/interfaces/pxe.ts @@ -1,7 +1,6 @@ import { type AztecAddress, type CompleteAddress, - type Fq, type Fr, type L1_TO_L2_MSG_TREE_HEIGHT, type PartialAddress, @@ -119,18 +118,6 @@ export interface PXE { */ getRecipient(address: AztecAddress): Promise; - /** - * Rotates master nullifier keys. - * @param address - The address of the account we want to rotate our key for. - * @param newNskM - The new master nullifier secret key we want to use. - * @remarks - One should not use this function directly without also calling the canonical key registry to rotate - * the new master nullifier secret key's derived master nullifier public key. - * Therefore, it is preferred to use rotateNullifierKeys on AccountWallet, as that handles the call to the Key Registry as well. - * - * This does not hinder our ability to spend notes tied to a previous master nullifier public key, provided we have the master nullifier secret key for it. - */ - rotateNskM(address: AztecAddress, newNskM: Fq): Promise; - /** * Registers a contract class in the PXE without registering any associated contract instance with it. * diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index 7d751f670a18..18ea558dbba4 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -115,8 +115,6 @@ export const FIXED_AVM_STARTUP_L2_GAS = 1024; 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 = - 6823425185167517386380694778823032861295161686691976789058601691508103815523n; export const CANONICAL_AUTH_REGISTRY_ADDRESS = 19361441716519463065948254497947932755739298943049449145365332870925554042208n; export const DEPLOYER_CONTRACT_ADDRESS = 17119407406465801909352274670277571579675739451008438338071219340964365249977n; diff --git a/yarn-project/circuits.js/src/contract/artifact_hash.ts b/yarn-project/circuits.js/src/contract/artifact_hash.ts index 05fb484ca13f..f5c8bee8ded4 100644 --- a/yarn-project/circuits.js/src/contract/artifact_hash.ts +++ b/yarn-project/circuits.js/src/contract/artifact_hash.ts @@ -68,7 +68,6 @@ export function computeArtifactMetadataHash(artifact: ContractArtifact) { const exceptions: string[] = [ 'AuthRegistry', - 'KeyRegistry', 'FeeJuice', 'ContractInstanceDeployer', 'ContractClassRegisterer', diff --git a/yarn-project/cli/src/cmds/infrastructure/deploy_protocol_contract.ts b/yarn-project/cli/src/cmds/infrastructure/deploy_protocol_contract.ts index 77e8a51a5d40..dae8b36732da 100644 --- a/yarn-project/cli/src/cmds/infrastructure/deploy_protocol_contract.ts +++ b/yarn-project/cli/src/cmds/infrastructure/deploy_protocol_contract.ts @@ -2,11 +2,7 @@ import { SignerlessWallet, type WaitOpts, createPXEClient, makeFetch } from '@az import { DefaultMultiCallEntrypoint } from '@aztec/aztec.js/entrypoint'; import { type LogFn } from '@aztec/foundation/log'; -import { - deployCanonicalAuthRegistry, - deployCanonicalKeyRegistry, - deployCanonicalL2FeeJuice, -} from '../misc/deploy_contracts.js'; +import { deployCanonicalAuthRegistry, deployCanonicalL2FeeJuice } from '../misc/deploy_contracts.js'; const waitOpts: WaitOpts = { timeout: 180, @@ -22,9 +18,6 @@ export async function deployProtocolContracts(rpcUrl: string, l1ChainId: number, const pxe = createPXEClient(rpcUrl, makeFetch([], true)); const deployer = new SignerlessWallet(pxe, new DefaultMultiCallEntrypoint(l1ChainId, 1)); - // Deploy Key Registry - const keyRegistryAddress = await deployCanonicalKeyRegistry(deployer, waitOpts); - // Deploy Auth Registry const authRegistryAddress = await deployCanonicalAuthRegistry(deployer, waitOpts); @@ -36,7 +29,6 @@ export async function deployProtocolContracts(rpcUrl: string, l1ChainId: number, log( JSON.stringify( { - keyRegistryAddress: keyRegistryAddress.toString(), authRegistryAddress: authRegistryAddress.toString(), feeJuiceAddress: feeJuiceAddress.toString(), }, @@ -45,7 +37,6 @@ export async function deployProtocolContracts(rpcUrl: string, l1ChainId: number, ), ); } else { - log(`Key Registry: ${keyRegistryAddress}`); log(`Auth Registry: ${authRegistryAddress}`); log(`Fee Juice: ${feeJuiceAddress}`); } diff --git a/yarn-project/cli/src/cmds/misc/deploy_contracts.ts b/yarn-project/cli/src/cmds/misc/deploy_contracts.ts index 8aeaed0089e8..944503a97128 100644 --- a/yarn-project/cli/src/cmds/misc/deploy_contracts.ts +++ b/yarn-project/cli/src/cmds/misc/deploy_contracts.ts @@ -2,14 +2,12 @@ import { DefaultWaitOpts, type EthAddress, NoFeePaymentMethod, type Wallet } fro import { AztecAddress, CANONICAL_AUTH_REGISTRY_ADDRESS, - CANONICAL_KEY_REGISTRY_ADDRESS, GasSettings, MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS, } from '@aztec/circuits.js'; import { bufferAsFields } from '@aztec/foundation/abi'; import { getCanonicalAuthRegistry } from '@aztec/protocol-contracts/auth-registry'; import { getCanonicalFeeJuice } from '@aztec/protocol-contracts/fee-juice'; -import { getCanonicalKeyRegistry } from '@aztec/protocol-contracts/key-registry'; /** * Deploys the contract to pay for gas on L2. @@ -56,43 +54,6 @@ export async function deployCanonicalL2FeeJuice( return canonicalFeeJuice.address; } -/** - * Deploys the key registry on L2. - */ -export async function deployCanonicalKeyRegistry(deployer: Wallet, waitOpts = DefaultWaitOpts): Promise { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - Importing noir-contracts.js even in devDeps results in a circular dependency error. Need to ignore because this line doesn't cause an error in a dev environment - const { KeyRegistryContract } = await import('@aztec/noir-contracts.js'); - - const canonicalKeyRegistry = getCanonicalKeyRegistry(); - - // We check to see if there exists a contract at the canonical Key Registry address with the same contract class id as we expect. This means that - // the key registry has already been deployed to the correct address. - if ( - (await deployer.getContractInstance(canonicalKeyRegistry.address))?.contractClassId.equals( - canonicalKeyRegistry.contractClass.id, - ) && - (await deployer.isContractClassPubliclyRegistered(canonicalKeyRegistry.contractClass.id)) - ) { - return canonicalKeyRegistry.address; - } - - const keyRegistry = await KeyRegistryContract.deploy(deployer) - .send({ contractAddressSalt: canonicalKeyRegistry.instance.salt, universalDeploy: true }) - .deployed(waitOpts); - - if ( - !keyRegistry.address.equals(canonicalKeyRegistry.address) || - !keyRegistry.address.equals(AztecAddress.fromBigInt(CANONICAL_KEY_REGISTRY_ADDRESS)) - ) { - throw new Error( - `Deployed Key Registry address ${keyRegistry.address} does not match expected address ${canonicalKeyRegistry.address}, or they both do not equal CANONICAL_KEY_REGISTRY_ADDRESS`, - ); - } - - return canonicalKeyRegistry.address; -} - /** * Deploys the auth registry on L2. */ diff --git a/yarn-project/cli/src/cmds/pxe/get_node_info.ts b/yarn-project/cli/src/cmds/pxe/get_node_info.ts index a3347f792d5f..5e4b060259b1 100644 --- a/yarn-project/cli/src/cmds/pxe/get_node_info.ts +++ b/yarn-project/cli/src/cmds/pxe/get_node_info.ts @@ -20,6 +20,5 @@ export async function getNodeInfo(rpcUrl: string, debugLogger: DebugLogger, log: log(` Class Registerer: ${info.protocolContractAddresses.classRegisterer.toString()}`); log(` Fee Juice: ${info.protocolContractAddresses.feeJuice.toString()}`); log(` Instance Deployer: ${info.protocolContractAddresses.instanceDeployer.toString()}`); - log(` Key Registry: ${info.protocolContractAddresses.keyRegistry.toString()}`); log(` MultiCall: ${info.protocolContractAddresses.multiCallEntrypoint.toString()}`); } diff --git a/yarn-project/cli/src/cmds/pxe/get_pxe_info.ts b/yarn-project/cli/src/cmds/pxe/get_pxe_info.ts index c448afa46130..ac10160694b3 100644 --- a/yarn-project/cli/src/cmds/pxe/get_pxe_info.ts +++ b/yarn-project/cli/src/cmds/pxe/get_pxe_info.ts @@ -9,6 +9,5 @@ export async function getPXEInfo(rpcUrl: string, debugLogger: DebugLogger, log: log(` Class Registerer: ${info.protocolContractAddresses.classRegisterer.toString()}`); log(` Fee Juice: ${info.protocolContractAddresses.feeJuice.toString()}`); log(` Instance Deployer: ${info.protocolContractAddresses.instanceDeployer.toString()}`); - log(` Key Registry: ${info.protocolContractAddresses.keyRegistry.toString()}`); log(` Multi Call Entrypoint: ${info.protocolContractAddresses.multiCallEntrypoint.toString()}`); } diff --git a/yarn-project/end-to-end/Earthfile b/yarn-project/end-to-end/Earthfile index 068503e684de..843e7eec2c20 100644 --- a/yarn-project/end-to-end/Earthfile +++ b/yarn-project/end-to-end/Earthfile @@ -164,9 +164,6 @@ e2e-encryption: e2e-escrow-contract: DO +E2E_TEST --test=./src/e2e_escrow_contract.test.ts -e2e-key-registry: - DO +E2E_TEST --test=./src/e2e_key_registry.test.ts - e2e-keys: DO +E2E_TEST --test=./src/e2e_keys.test.ts diff --git a/yarn-project/end-to-end/src/devnet/e2e_smoke.test.ts b/yarn-project/end-to-end/src/devnet/e2e_smoke.test.ts index 4e318b416c46..848f09e9b00f 100644 --- a/yarn-project/end-to-end/src/devnet/e2e_smoke.test.ts +++ b/yarn-project/end-to-end/src/devnet/e2e_smoke.test.ts @@ -101,7 +101,6 @@ describe('End-to-end tests for devnet', () => { pxeInfo.protocolContractAddresses.instanceDeployer, ); expect(nodeInfo.protocolContractAddresses.feeJuice).toEqual(pxeInfo.protocolContractAddresses.feeJuice); - expect(nodeInfo.protocolContractAddresses.keyRegistry).toEqual(pxeInfo.protocolContractAddresses.keyRegistry); expect(nodeInfo.protocolContractAddresses.multiCallEntrypoint).toEqual( pxeInfo.protocolContractAddresses.multiCallEntrypoint, ); diff --git a/yarn-project/end-to-end/src/e2e_key_registry.test.ts b/yarn-project/end-to-end/src/e2e_key_registry.test.ts deleted file mode 100644 index 82bd3303ee7c..000000000000 --- a/yarn-project/end-to-end/src/e2e_key_registry.test.ts +++ /dev/null @@ -1,165 +0,0 @@ -import { type AccountWallet, AztecAddress, Fr, type PXE } from '@aztec/aztec.js'; -import { CompleteAddress, Point, PublicKeys } from '@aztec/circuits.js'; -import { KeyRegistryContract, TestContract } from '@aztec/noir-contracts.js'; -import { getCanonicalKeyRegistryAddress } from '@aztec/protocol-contracts/key-registry'; - -import { jest } from '@jest/globals'; - -import { publicDeployAccounts, setup } from './fixtures/utils.js'; - -const TIMEOUT = 120_000; - -describe('Key Registry', () => { - let keyRegistry: KeyRegistryContract; - - let pxe: PXE; - let testContract: TestContract; - jest.setTimeout(TIMEOUT); - - let wallets: AccountWallet[]; - - let teardown: () => Promise; - - const account = CompleteAddress.random(); - - beforeAll(async () => { - ({ teardown, pxe, wallets } = await setup(2)); - keyRegistry = await KeyRegistryContract.at(getCanonicalKeyRegistryAddress(), wallets[0]); - - testContract = await TestContract.deploy(wallets[0]).send().deployed(); - - await publicDeployAccounts(wallets[0], wallets.slice(0, 2)); - }); - - afterAll(() => teardown()); - - describe('failure cases', () => { - it('throws when address preimage check fails', async () => { - // First we get invalid keys by replacing any of the 8 fields of public keys with a random value - let invalidPublicKeys: PublicKeys; - { - // We call toBuffer and fromBuffer first to ensure that we get a deep copy - const publicKeysFields = PublicKeys.fromBuffer(account.publicKeys.toBuffer()).toFields(); - const nonIsInfiniteIndices = [0, 1, 3, 4, 6, 7, 9, 10]; - const randomIndex = nonIsInfiniteIndices[Math.floor(Math.random() * nonIsInfiniteIndices.length)]; - - publicKeysFields[randomIndex] = Fr.random(); - - invalidPublicKeys = PublicKeys.fromFields(publicKeysFields); - } - - await expect( - keyRegistry - .withWallet(wallets[0]) - .methods.register_initial_keys( - account, - account.partialAddress, - // TODO(#6337): Make calling `toNoirStruct()` unnecessary - invalidPublicKeys.toNoirStruct(), - ) - .send() - .wait(), - ).rejects.toThrow('Computed address does not match supplied address'); - }); - - it('should fail when we try to rotate keys for another address without authwit', async () => { - await expect( - keyRegistry - .withWallet(wallets[0]) - .methods.rotate_npk_m(wallets[1].getAddress(), Point.random().toWrappedNoirStruct(), Fr.ZERO) - .simulate(), - ).rejects.toThrow(/unauthorized/); - }); - - it('fresh key lib fails for non-existent account', async () => { - // Should fail as the contract is not registered in key registry - - const randomAddress = AztecAddress.random(); - const randomMasterNullifierPublicKey = Point.random(); - - await expect( - testContract.methods - .test_nullifier_key_freshness(randomAddress, randomMasterNullifierPublicKey.toNoirStruct()) - .send() - .wait(), - ).rejects.toThrow(/No public key registered for address/); - }); - }); - - it('fresh key lib succeeds for non-registered account available in PXE', async () => { - const newAccountCompleteAddress = CompleteAddress.random(); - await pxe.registerRecipient(newAccountCompleteAddress); - - // Should succeed as the account is now registered as a recipient in PXE - await testContract.methods - .test_nullifier_key_freshness( - newAccountCompleteAddress.address, - newAccountCompleteAddress.publicKeys.masterNullifierPublicKey.toNoirStruct(), - ) - .send() - .wait(); - }); - - describe('key registration flow', () => { - it('registers', async () => { - await keyRegistry - .withWallet(wallets[0]) - .methods.register_initial_keys( - account, - account.partialAddress, - // TODO(#6337): Make calling `toNoirStruct()` unnecessary - account.publicKeys.toNoirStruct(), - ) - .send() - .wait(); - - // Should succeed as the account is registered in key registry from tests before - await testContract.methods - .test_nullifier_key_freshness(account, account.publicKeys.masterNullifierPublicKey.toNoirStruct()) - .send() - .wait(); - }); - }); - - describe('key rotation flows', () => { - const firstNewMasterNullifierPublicKey = Point.random(); - const secondNewMasterNullifierPublicKey = Point.random(); - - it('rotates npk_m', async () => { - // docs:start:key-rotation - await keyRegistry - .withWallet(wallets[0]) - .methods.rotate_npk_m(wallets[0].getAddress(), firstNewMasterNullifierPublicKey.toWrappedNoirStruct(), Fr.ZERO) - .send() - .wait(); - // docs:end:key-rotation - - await testContract.methods - .test_nullifier_key_freshness(wallets[0].getAddress(), firstNewMasterNullifierPublicKey.toNoirStruct()) - .send() - .wait(); - }); - - it(`rotates npk_m with authwit`, async () => { - const action = keyRegistry - .withWallet(wallets[1]) - .methods.rotate_npk_m( - wallets[0].getAddress(), - secondNewMasterNullifierPublicKey.toWrappedNoirStruct(), - Fr.ZERO, - ); - - await wallets[0] - .setPublicAuthWit({ caller: wallets[1].getCompleteAddress().address, action }, true) - .send() - .wait(); - - await action.send().wait(); - - await testContract.methods - .test_nullifier_key_freshness(wallets[0].getAddress(), secondNewMasterNullifierPublicKey.toNoirStruct()) - .send() - .wait(); - }); - }); -}); diff --git a/yarn-project/end-to-end/src/e2e_key_rotation.test.ts b/yarn-project/end-to-end/src/e2e_key_rotation.test.ts deleted file mode 100644 index a6cbf6ad3e71..000000000000 --- a/yarn-project/end-to-end/src/e2e_key_rotation.test.ts +++ /dev/null @@ -1,236 +0,0 @@ -import { createAccounts } from '@aztec/accounts/testing'; -import { - type AztecAddress, - type AztecNode, - type DebugLogger, - ExtendedNote, - Fq, - Fr, - Note, - type PXE, - type TxHash, - type Wallet, - computeSecretHash, - retryUntil, -} from '@aztec/aztec.js'; -// docs:start:imports -import { type PublicKey, derivePublicKeyFromSecretKey } from '@aztec/circuits.js'; -import { TestContract, TokenContract } from '@aztec/noir-contracts.js'; - -// docs:end:imports -import { jest } from '@jest/globals'; - -import { expectsNumOfNoteEncryptedLogsInTheLastBlockToBe, setup, setupPXEService } from './fixtures/utils.js'; - -const TIMEOUT = 120_000; - -const SHARED_MUTABLE_DELAY = 5; - -describe('e2e_key_rotation', () => { - jest.setTimeout(TIMEOUT); - - let aztecNode: AztecNode; - let pxeA: PXE; - let pxeB: PXE; - let walletA: Wallet; - let walletB: Wallet; - let logger: DebugLogger; - let teardownA: () => Promise; - let teardownB: () => Promise; - - let testContract: TestContract; - let contractWithWalletA: TokenContract; - let contractWithWalletB: TokenContract; - - let tokenAddress: AztecAddress; - - const initialBalance = 987n; - - beforeAll(async () => { - ({ - aztecNode, - pxe: pxeA, - wallets: [walletA], - logger, - teardown: teardownA, - } = await setup(1)); - - ({ pxe: pxeB, teardown: teardownB } = await setupPXEService(aztecNode, {}, undefined, true)); - [walletB] = await createAccounts(pxeB, 1); - - // We deploy test and token contracts - testContract = await TestContract.deploy(walletA).send().deployed(); - const tokenInstance = await deployTokenContract(initialBalance, walletA.getAddress(), pxeA); - tokenAddress = tokenInstance.address; - - // Add account B to wallet A - await pxeA.registerRecipient(walletB.getCompleteAddress()); - // Add account A to wallet B - await pxeB.registerRecipient(walletA.getCompleteAddress()); - - // Add token to PXE B (PXE A already has it because it was deployed through it) - await pxeB.registerContract({ - artifact: TokenContract.artifact, - instance: tokenInstance, - }); - - contractWithWalletA = await TokenContract.at(tokenAddress, walletA); - contractWithWalletB = await TokenContract.at(tokenAddress, walletB); - }); - - afterEach(async () => { - await teardownB(); - await teardownA(); - }); - - const awaitUserSynchronized = async (wallet: Wallet, owner: AztecAddress) => { - const isUserSynchronized = async () => { - return await wallet.isAccountStateSynchronized(owner); - }; - await retryUntil(isUserSynchronized, `synch of user ${owner.toString()}`, 10); - }; - - const crossDelay = async () => { - for (let i = 0; i < SHARED_MUTABLE_DELAY; i++) { - // We send arbitrary tx to mine a block - await testContract.methods.emit_unencrypted(0).send().wait(); - } - }; - - const expectTokenBalance = async ( - wallet: Wallet, - tokenAddress: AztecAddress, - owner: AztecAddress, - expectedBalance: bigint, - checkIfSynchronized = true, - ) => { - if (checkIfSynchronized) { - // First wait until the corresponding PXE has synchronized the account - await awaitUserSynchronized(wallet, owner); - } - - // Then check the balance - const contractWithWallet = await TokenContract.at(tokenAddress, wallet); - const balance = await contractWithWallet.methods.balance_of_private(owner).simulate({ from: owner }); - logger.info(`Account ${owner} balance: ${balance}`); - expect(balance).toBe(expectedBalance); - }; - - const deployTokenContract = async (initialAdminBalance: bigint, admin: AztecAddress, pxe: PXE) => { - logger.info(`Deploying Token contract...`); - const contract = await TokenContract.deploy(walletA, admin, 'TokenName', 'TokenSymbol', 18).send().deployed(); - - if (initialAdminBalance > 0n) { - await mintTokens(contract, admin, initialAdminBalance, pxe); - } - - logger.info('L2 contract deployed'); - - return contract.instance; - }; - - const mintTokens = async (contract: TokenContract, recipient: AztecAddress, balance: bigint, pxe: PXE) => { - const secret = Fr.random(); - const secretHash = computeSecretHash(secret); - - const receipt = await contract.methods.mint_private(balance, secretHash).send().wait(); - - const note = new Note([new Fr(balance), secretHash]); - const extendedNote = new ExtendedNote( - note, - recipient, - contract.address, - TokenContract.storage.pending_shields.slot, - TokenContract.notes.TransparentNote.id, - receipt.txHash, - ); - await pxe.addNote(extendedNote); - - await contract.methods.redeem_shield(recipient, balance, secret).send().wait(); - }; - - it(`Rotates keys and uses them`, async () => { - // 1. We check that setup set initial balances as expected - await expectTokenBalance(walletA, tokenAddress, walletA.getAddress(), initialBalance); - await expectTokenBalance(walletB, tokenAddress, walletB.getAddress(), 0n); - - // 2. Transfer funds from A to B via PXE A - let txHashTransfer1: TxHash; - const transfer1Amount = 654n; - { - ({ txHash: txHashTransfer1 } = await contractWithWalletA.methods - .transfer(walletB.getAddress(), transfer1Amount) - .send() - .wait()); - - // Check balances and logs are as expected - await expectTokenBalance(walletA, tokenAddress, walletA.getAddress(), initialBalance - transfer1Amount); - await expectTokenBalance(walletB, tokenAddress, walletB.getAddress(), transfer1Amount); - await expectsNumOfNoteEncryptedLogsInTheLastBlockToBe(aztecNode, 2); - } - - // 3. Rotates B key - let newNpkM: PublicKey; - { - // docs:start:create_keys - const newNskM = Fq.random(); - newNpkM = derivePublicKeyFromSecretKey(newNskM); - // docs:end:create_keys - - // docs:start:rotateNullifierKeys - // This function saves the new nullifier secret key for the account in our PXE, - // and calls the key registry with the derived nullifier public key. - await walletB.rotateNullifierKeys(newNskM); - // docs:end:rotateNullifierKeys - await crossDelay(); - } - - // 4. Transfer funds from A to B via PXE A - let txHashTransfer2: TxHash; - const transfer2Amount = 321n; - { - ({ txHash: txHashTransfer2 } = await contractWithWalletA.methods - .transfer(walletB.getAddress(), transfer2Amount) - .send() - .wait()); - - await expectTokenBalance( - walletA, - tokenAddress, - walletA.getAddress(), - initialBalance - transfer1Amount - transfer2Amount, - ); - await expectTokenBalance(walletB, tokenAddress, walletB.getAddress(), transfer1Amount + transfer2Amount); - } - - // 5. Now we check that a correct nullifier keys were used in both transfers - { - await awaitUserSynchronized(walletB, walletB.getAddress()); - const transfer1Notes = await walletB.getIncomingNotes({ txHash: txHashTransfer1 }); - const transfer2Notes = await walletB.getIncomingNotes({ txHash: txHashTransfer2 }); - expect(transfer1Notes.length).toBe(1); - expect(transfer2Notes.length).toBe(1); - // Second field in the token note is the npk_m_hash - const noteNpkMHashTransfer1 = transfer1Notes[0].note.items[1]; - const noteNpkMHashTransfer2 = transfer2Notes[0].note.items[1]; - - // Now we check the note created in transfer 2 used the new npk_m_hash - expect(noteNpkMHashTransfer2.equals(newNpkM.hash())).toBe(true); - // We sanity check that the note created in transfer 1 had old npk_m_hash by checking it's different from the new - // one - expect(noteNpkMHashTransfer2.equals(noteNpkMHashTransfer1)).toBe(false); - } - - // 6. Finally we check that all the B notes are spendable by transferring full B balance to A - // --> this way we verify that it's possible to obtain both keys via oracles - { - await contractWithWalletB.methods - .transfer(walletA.getAddress(), transfer1Amount + transfer2Amount) - .send() - .wait(); - - await expectTokenBalance(walletA, tokenAddress, walletA.getAddress(), initialBalance); - await expectTokenBalance(walletB, tokenAddress, walletB.getAddress(), 0n); - } - }, 600_000); -}); diff --git a/yarn-project/end-to-end/src/e2e_keys.test.ts b/yarn-project/end-to-end/src/e2e_keys.test.ts index 3cf3a8182f6c..b8962a0d2032 100644 --- a/yarn-project/end-to-end/src/e2e_keys.test.ts +++ b/yarn-project/end-to-end/src/e2e_keys.test.ts @@ -27,7 +27,7 @@ import { setup } from './fixtures/utils.js'; const TIMEOUT = 120_000; -describe('Key Registry', () => { +describe('Keys', () => { jest.setTimeout(TIMEOUT); let aztecNode: AztecNode; diff --git a/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts b/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts index 9345caef70f0..d4f3702c4efc 100644 --- a/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts @@ -1,18 +1,14 @@ import { type AccountWallet, type AztecAddress, type DebugLogger, Fr } from '@aztec/aztec.js'; -import { TestContract } from '@aztec/noir-contracts.js'; import { EasyPrivateVotingContract } from '@aztec/noir-contracts.js/EasyPrivateVoting'; import { setup } from './fixtures/utils.js'; -const SHARED_MUTABLE_DELAY = 5; - describe('e2e_voting_contract', () => { let wallet: AccountWallet; let logger: DebugLogger; let teardown: () => Promise; - let testContract: TestContract; let votingContract: EasyPrivateVotingContract; let owner: AztecAddress; @@ -21,7 +17,6 @@ describe('e2e_voting_contract', () => { ({ teardown, wallet, logger } = await setup(1)); owner = wallet.getAddress(); - testContract = await TestContract.deploy(wallet).send().deployed(); votingContract = await EasyPrivateVotingContract.deploy(wallet, owner).send().deployed(); logger.info(`Counter contract deployed at ${votingContract.address}`); @@ -29,26 +24,13 @@ describe('e2e_voting_contract', () => { afterAll(() => teardown()); - const crossDelay = async () => { - for (let i = 0; i < SHARED_MUTABLE_DELAY; i++) { - // We send arbitrary tx to mine a block - await testContract.methods.emit_unencrypted(0).send().wait(); - } - }; - describe('votes', () => { - it('votes, rotates nullifier keys, then tries to vote again', async () => { + it('votes, then tries to vote again', async () => { const candidate = new Fr(1); await votingContract.methods.cast_vote(candidate).send().wait(); expect(await votingContract.methods.get_vote(candidate).simulate()).toBe(1n); - // We rotate our nullifier keys - this should be ignored by the voting contract, since it should always use the - // same set of keys to prevent double spends. - await wallet.rotateNullifierKeys(); - await crossDelay(); - - // We try voting again, but our TX is dropped due to trying to emit duplicate nullifiers as the voting contract - // ignored our previous key rotation. + // We try voting again, but our TX is dropped due to trying to emit duplicate nullifiers await expect(votingContract.methods.cast_vote(candidate).send().wait()).rejects.toThrow( 'Reason: Tx dropped by P2P node.', ); diff --git a/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts b/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts index 4a5400f53ebc..bb1af6a9da5f 100644 --- a/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts +++ b/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts @@ -39,12 +39,7 @@ import { MNEMONIC } from './fixtures.js'; import { getACVMConfig } from './get_acvm_config.js'; import { getBBConfig } from './get_bb_config.js'; import { setupL1Contracts } from './setup_l1_contracts.js'; -import { - deployCanonicalAuthRegistry, - deployCanonicalKeyRegistry, - deployCanonicalRouter, - getPrivateKeyFromIndex, -} from './utils.js'; +import { deployCanonicalAuthRegistry, deployCanonicalRouter, getPrivateKeyFromIndex } from './utils.js'; export type SubsystemsContext = { anvil: Anvil; @@ -347,10 +342,6 @@ async function setupFromFresh( pxeConfig.dataDirectory = statePath; const pxe = await createPXEService(aztecNode, pxeConfig); - logger.verbose('Deploying key registry...'); - await deployCanonicalKeyRegistry( - new SignerlessWallet(pxe, new DefaultMultiCallEntrypoint(aztecNodeConfig.l1ChainId, aztecNodeConfig.version)), - ); logger.verbose('Deploying auth registry...'); await deployCanonicalAuthRegistry( new SignerlessWallet(pxe, new DefaultMultiCallEntrypoint(aztecNodeConfig.l1ChainId, aztecNodeConfig.version)), diff --git a/yarn-project/end-to-end/src/fixtures/utils.ts b/yarn-project/end-to-end/src/fixtures/utils.ts index 99eaf3faaf2d..c7308bf8826f 100644 --- a/yarn-project/end-to-end/src/fixtures/utils.ts +++ b/yarn-project/end-to-end/src/fixtures/utils.ts @@ -32,7 +32,6 @@ import { DefaultMultiCallEntrypoint } from '@aztec/aztec.js/entrypoint'; import { type BBNativePrivateKernelProver } from '@aztec/bb-prover'; import { CANONICAL_AUTH_REGISTRY_ADDRESS, - CANONICAL_KEY_REGISTRY_ADDRESS, type EthAddress, GasSettings, MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS, @@ -57,12 +56,11 @@ import { RollupAbi, RollupBytecode, } from '@aztec/l1-artifacts'; -import { AuthRegistryContract, KeyRegistryContract, RouterContract } from '@aztec/noir-contracts.js'; +import { AuthRegistryContract, RouterContract } from '@aztec/noir-contracts.js'; import { FeeJuiceContract } from '@aztec/noir-contracts.js/FeeJuice'; import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types'; import { getCanonicalAuthRegistry } from '@aztec/protocol-contracts/auth-registry'; import { FeeJuiceAddress, getCanonicalFeeJuice } from '@aztec/protocol-contracts/fee-juice'; -import { getCanonicalKeyRegistry } from '@aztec/protocol-contracts/key-registry'; import { getCanonicalRouter } from '@aztec/protocol-contracts/router'; import { PXEService, type PXEServiceConfig, createPXEService, getPXEServiceConfig } from '@aztec/pxe'; import { type SequencerClient } from '@aztec/sequencer-client'; @@ -246,9 +244,6 @@ async function setupWithRemoteEnvironment( const { l1ChainId: chainId, protocolVersion } = await pxeClient.getNodeInfo(); // this contract might already have been deployed // the following deploying functions are idempotent - await deployCanonicalKeyRegistry( - new SignerlessWallet(pxeClient, new DefaultMultiCallEntrypoint(chainId, protocolVersion)), - ); await deployCanonicalAuthRegistry( new SignerlessWallet(pxeClient, new DefaultMultiCallEntrypoint(config.l1ChainId, config.version)), ); @@ -445,11 +440,6 @@ export async function setup( const { pxe } = await setupPXEService(aztecNode!, pxeOpts, logger); if (!config.skipProtocolContracts) { - logger.verbose('Deploying key registry...'); - await deployCanonicalKeyRegistry( - new SignerlessWallet(pxe, new DefaultMultiCallEntrypoint(config.l1ChainId, config.version)), - ); - logger.verbose('Deploying auth registry...'); await deployCanonicalAuthRegistry( new SignerlessWallet(pxe, new DefaultMultiCallEntrypoint(config.l1ChainId, config.version)), @@ -731,39 +721,6 @@ export async function deployCanonicalFeeJuice(pxe: PXE) { await expect(pxe.isContractPubliclyDeployed(feeJuice.address)).resolves.toBe(true); } -export async function deployCanonicalKeyRegistry(deployer: Wallet) { - const canonicalKeyRegistry = getCanonicalKeyRegistry(); - - // We check to see if there exists a contract at the canonical Key Registry address with the same contract class id as we expect. This means that - // the key registry has already been deployed to the correct address. - if ( - (await deployer.getContractInstance(canonicalKeyRegistry.address))?.contractClassId.equals( - canonicalKeyRegistry.contractClass.id, - ) && - (await deployer.isContractClassPubliclyRegistered(canonicalKeyRegistry.contractClass.id)) - ) { - return; - } - - const keyRegistry = await KeyRegistryContract.deploy(deployer) - .send({ contractAddressSalt: canonicalKeyRegistry.instance.salt, universalDeploy: true }) - .deployed(); - - if ( - !keyRegistry.address.equals(canonicalKeyRegistry.address) || - !keyRegistry.address.equals(AztecAddress.fromBigInt(CANONICAL_KEY_REGISTRY_ADDRESS)) - ) { - throw new Error( - `Deployed Key Registry address ${keyRegistry.address} does not match expected address ${canonicalKeyRegistry.address}, or they both do not equal CANONICAL_KEY_REGISTRY_ADDRESS`, - ); - } - - expect(computeContractAddressFromInstance(keyRegistry.instance)).toEqual(keyRegistry.address); - expect(getContractClassFromArtifact(keyRegistry.artifact).id).toEqual(keyRegistry.instance.contractClassId); - await expect(deployer.isContractClassPubliclyRegistered(canonicalKeyRegistry.contractClass.id)).resolves.toBe(true); - await expect(deployer.getContractInstance(canonicalKeyRegistry.instance.address)).resolves.toBeDefined(); -} - export async function deployCanonicalAuthRegistry(deployer: Wallet) { const canonicalAuthRegistry = getCanonicalAuthRegistry(); diff --git a/yarn-project/key-store/src/key_store.test.ts b/yarn-project/key-store/src/key_store.test.ts index 218da7ff548a..25fcdea0a559 100644 --- a/yarn-project/key-store/src/key_store.test.ts +++ b/yarn-project/key-store/src/key_store.test.ts @@ -1,11 +1,4 @@ -import { - AztecAddress, - Fq, - Fr, - computeAppNullifierSecretKey, - deriveKeys, - derivePublicKeyFromSecretKey, -} from '@aztec/circuits.js'; +import { AztecAddress, Fr, deriveKeys, derivePublicKeyFromSecretKey } from '@aztec/circuits.js'; import { openTmpStore } from '@aztec/kv-store/utils'; import { KeyStore } from './key_store.js'; @@ -88,83 +81,4 @@ describe('KeyStore', () => { `"0x1d1d920024dd64e019c23de36d27aefe4d9d4d05983b99cf85bea9e85fd60020"`, ); }); - - it('nullifier key rotation tests', async () => { - const keyStore = new KeyStore(openTmpStore()); - - // Arbitrary fixed values - const sk = new Fr(8923n); - const partialAddress = new Fr(243523n); - - const { address: accountAddress } = await keyStore.addAccount(sk, partialAddress); - expect(accountAddress.toString()).toMatchInlineSnapshot( - `"0x2321fcb3bd7447b178138746ee78f6fbb1e2a2aa8ff542f51420b884bab641cc"`, - ); - - // Arbitrary fixed values - const newMasterNullifierSecretKeys = [new Fq(420n), new Fq(69n), new Fq(42069n)]; - const newDerivedMasterNullifierPublicKeys = [ - derivePublicKeyFromSecretKey(newMasterNullifierSecretKeys[0]), - derivePublicKeyFromSecretKey(newMasterNullifierSecretKeys[1]), - derivePublicKeyFromSecretKey(newMasterNullifierSecretKeys[2]), - ]; - - const newComputedMasterNullifierPublicKeyHashes = [ - newDerivedMasterNullifierPublicKeys[0].hash(), - newDerivedMasterNullifierPublicKeys[1].hash(), - newDerivedMasterNullifierPublicKeys[2].hash(), - ]; - - // We rotate our nullifier key - await keyStore.rotateMasterNullifierKey(accountAddress, newMasterNullifierSecretKeys[0]); - await keyStore.rotateMasterNullifierKey(accountAddress, newMasterNullifierSecretKeys[1]); - await keyStore.rotateMasterNullifierKey(accountAddress, newMasterNullifierSecretKeys[2]); - - // We make sure we can get master nullifier public keys with master nullifier public key hashes - const { pkM: masterNullifierPublicKey2 } = await keyStore.getKeyValidationRequest( - newComputedMasterNullifierPublicKeyHashes[2], - AztecAddress.random(), // Address is random because we are not interested in the app secret key here - ); - expect(masterNullifierPublicKey2).toEqual(newDerivedMasterNullifierPublicKeys[2]); - const { pkM: masterNullifierPublicKey1 } = await keyStore.getKeyValidationRequest( - newComputedMasterNullifierPublicKeyHashes[1], - AztecAddress.random(), // Address is random because we are not interested in the app secret key here - ); - expect(masterNullifierPublicKey1).toEqual(newDerivedMasterNullifierPublicKeys[1]); - const { pkM: masterNullifierPublicKey0 } = await keyStore.getKeyValidationRequest( - newComputedMasterNullifierPublicKeyHashes[0], - AztecAddress.random(), // Address is random because we are not interested in the app secret key here - ); - expect(masterNullifierPublicKey0).toEqual(newDerivedMasterNullifierPublicKeys[0]); - - // Arbitrary app contract address - const appAddress = AztecAddress.fromBigInt(624n); - - // We make sure we can get app nullifier secret keys with master nullifier public key hashes - const { skApp: appNullifierSecretKey0 } = await keyStore.getKeyValidationRequest( - newComputedMasterNullifierPublicKeyHashes[0], - appAddress, - ); - expect(appNullifierSecretKey0.toString()).toMatchInlineSnapshot( - `"0x0d03293ba35ee33ac093be75119d9819da11631b3739b0f12788ef66b28834d5"`, - ); - const { skApp: appNullifierSecretKey1 } = await keyStore.getKeyValidationRequest( - newComputedMasterNullifierPublicKeyHashes[1], - appAddress, - ); - expect(appNullifierSecretKey1.toString()).toMatchInlineSnapshot( - `"0x01baec4d9f3d4b98fa883e256917e91e913490d92cd01763dea49337c9d364af"`, - ); - const { skApp: appNullifierSecretKey2 } = await keyStore.getKeyValidationRequest( - newComputedMasterNullifierPublicKeyHashes[2], - appAddress, - ); - expect(appNullifierSecretKey2.toString()).toMatchInlineSnapshot( - `"0x0d1ff3fde73bc14ea0cfa704aed68d72c27bf58e6159e381f23d2951ce3566ec"`, - ); - - expect(appNullifierSecretKey0).toEqual(computeAppNullifierSecretKey(newMasterNullifierSecretKeys[0], appAddress)); - expect(appNullifierSecretKey1).toEqual(computeAppNullifierSecretKey(newMasterNullifierSecretKeys[1], appAddress)); - expect(appNullifierSecretKey2).toEqual(computeAppNullifierSecretKey(newMasterNullifierSecretKeys[2], appAddress)); - }); }); diff --git a/yarn-project/key-store/src/key_store.ts b/yarn-project/key-store/src/key_store.ts index 6914c2fc83df..f535612420ab 100644 --- a/yarn-project/key-store/src/key_store.ts +++ b/yarn-project/key-store/src/key_store.ts @@ -2,7 +2,7 @@ import { type PublicKey } from '@aztec/circuit-types'; import { AztecAddress, CompleteAddress, - Fq, + type Fq, Fr, GeneratorIndex, GrumpkinScalar, @@ -301,31 +301,6 @@ export class KeyStore { return Promise.resolve(skM); } - /** - * Rotates the master nullifier key for the specified account. - * - * @dev This function updates the secret and public keys associated with the account. - * It appends a new secret key to the existing secret keys, derives the - * corresponding public key, and updates the stored keys accordingly. - * - * @param account - The account address for which the master nullifier key is being rotated. - * @param newSecretKey - (Optional) A new secret key of type Fq. If not provided, a random key is generated. - * @throws If the account does not have existing nullifier secret keys or public keys. - * @returns A Promise that resolves when the key rotation is complete. - */ - public async rotateMasterNullifierKey(account: AztecAddress, newSecretKey: Fq = Fq.random()) { - // We append the secret key to the array of secret keys - await this.#appendValue(`${account.toString()}-nsk_m`, newSecretKey); - - // Now we derive the public key from the new secret key and append it to the buffer of original public keys - const newPublicKey = derivePublicKeyFromSecretKey(newSecretKey); - await this.#appendValue(`${account.toString()}-npk_m`, newPublicKey); - - // At last we store npk_m_hash under `account-npk_m_hash` key to be able to obtain address and key prefix - // using the #getKeyPrefixAndAccount function later on - await this.#appendValue(`${account.toString()}-npk_m_hash`, newPublicKey.hash()); - } - /** * Gets the key prefix and account address for a given value. * @returns A tuple containing the key prefix and account address. @@ -349,15 +324,6 @@ export class KeyStore { throw new Error(`Could not find key prefix.`); } - async #appendValue(key: string, value: Bufferable) { - const currentValue = this.#keys.get(key); - if (!currentValue) { - throw new Error(`Could not find current value for key ${key}`); - } - - await this.#keys.set(key, serializeToBuffer([currentValue, value])); - } - #calculateNumKeys(buf: Buffer, T: typeof Point | typeof Fq) { return buf.byteLength / T.SIZE_IN_BYTES; } diff --git a/yarn-project/protocol-contracts/scripts/copy-contracts.sh b/yarn-project/protocol-contracts/scripts/copy-contracts.sh index 3646ec63131e..aca744ef5795 100755 --- a/yarn-project/protocol-contracts/scripts/copy-contracts.sh +++ b/yarn-project/protocol-contracts/scripts/copy-contracts.sh @@ -6,7 +6,6 @@ contracts=( contract_class_registerer_contract-ContractClassRegisterer contract_instance_deployer_contract-ContractInstanceDeployer fee_juice_contract-FeeJuice - key_registry_contract-KeyRegistry auth_registry_contract-AuthRegistry multi_call_entrypoint_contract-MultiCallEntrypoint router_contract-Router diff --git a/yarn-project/protocol-contracts/src/key-registry/artifact.ts b/yarn-project/protocol-contracts/src/key-registry/artifact.ts deleted file mode 100644 index 5feb280a6240..000000000000 --- a/yarn-project/protocol-contracts/src/key-registry/artifact.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { loadContractArtifact } from '@aztec/types/abi'; -import { type NoirCompiledContract } from '@aztec/types/noir'; - -import KeyRegistryJson from '../../artifacts/KeyRegistry.json' assert { type: 'json' }; - -export const KeyRegistryArtifact = loadContractArtifact(KeyRegistryJson as NoirCompiledContract); diff --git a/yarn-project/protocol-contracts/src/key-registry/index.test.ts b/yarn-project/protocol-contracts/src/key-registry/index.test.ts deleted file mode 100644 index 216213556d89..000000000000 --- a/yarn-project/protocol-contracts/src/key-registry/index.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { - AztecAddress, - CANONICAL_KEY_REGISTRY_ADDRESS, - computeContractAddressFromInstance, - getContractClassFromArtifact, -} from '@aztec/circuits.js'; - -import { getCanonicalKeyRegistry } from './index.js'; - -describe('KeyRegistry', () => { - it('returns canonical protocol contract', () => { - const contract = getCanonicalKeyRegistry(); - expect(computeContractAddressFromInstance(contract.instance)).toEqual(contract.address); - expect(getContractClassFromArtifact(contract.artifact).id).toEqual(contract.contractClass.id); - expect(contract.address).toEqual(AztecAddress.fromBigInt(CANONICAL_KEY_REGISTRY_ADDRESS)); - }); -}); diff --git a/yarn-project/protocol-contracts/src/key-registry/index.ts b/yarn-project/protocol-contracts/src/key-registry/index.ts deleted file mode 100644 index dd4bbf31d6b9..000000000000 --- a/yarn-project/protocol-contracts/src/key-registry/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { AztecAddress, CANONICAL_KEY_REGISTRY_ADDRESS } from '@aztec/circuits.js'; - -import { type ProtocolContract, getCanonicalProtocolContract } from '../protocol_contract.js'; -import { KeyRegistryArtifact } from './artifact.js'; - -/** Returns the canonical deployment of the public key registry. */ -export function getCanonicalKeyRegistry(): ProtocolContract { - const contract = getCanonicalProtocolContract(KeyRegistryArtifact, 1); - - if (!contract.address.equals(KeyRegistryAddress)) { - throw new Error( - `Incorrect address for key registry (got ${contract.address.toString()} but expected ${KeyRegistryAddress.toString()}). Check CANONICAL_KEY_REGISTRY_ADDRESS is set to the correct value in the constants files and run the protocol-contracts package tests.`, - ); - } - return contract; -} - -export function getCanonicalKeyRegistryAddress(): AztecAddress { - return getCanonicalKeyRegistry().address; -} - -export const KeyRegistryAddress = AztecAddress.fromBigInt(CANONICAL_KEY_REGISTRY_ADDRESS); diff --git a/yarn-project/pxe/src/pxe_service/create_pxe_service.ts b/yarn-project/pxe/src/pxe_service/create_pxe_service.ts index fd4b1d3a34da..e6042b7e3650 100644 --- a/yarn-project/pxe/src/pxe_service/create_pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/create_pxe_service.ts @@ -8,7 +8,6 @@ import { getCanonicalAuthRegistry } from '@aztec/protocol-contracts/auth-registr import { getCanonicalClassRegisterer } from '@aztec/protocol-contracts/class-registerer'; import { getCanonicalFeeJuice } from '@aztec/protocol-contracts/fee-juice'; import { getCanonicalInstanceDeployer } from '@aztec/protocol-contracts/instance-deployer'; -import { getCanonicalKeyRegistry } from '@aztec/protocol-contracts/key-registry'; import { getCanonicalMultiCallEntrypointContract } from '@aztec/protocol-contracts/multi-call-entrypoint'; import { getCanonicalRouter } from '@aztec/protocol-contracts/router'; @@ -51,7 +50,6 @@ export async function createPXEService( getCanonicalInstanceDeployer(), getCanonicalMultiCallEntrypointContract(), getCanonicalFeeJuice(), - getCanonicalKeyRegistry(), getCanonicalAuthRegistry(), getCanonicalRouter(), ]) { diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index a68ec01823b8..2d7c0cbde1f6 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -48,14 +48,13 @@ import { FunctionSelector, encodeArguments, } from '@aztec/foundation/abi'; -import { type Fq, Fr, type Point } from '@aztec/foundation/fields'; +import { Fr, type Point } from '@aztec/foundation/fields'; import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { SerialQueue } from '@aztec/foundation/queue'; import { type KeyStore } from '@aztec/key-store'; import { ClassRegistererAddress } from '@aztec/protocol-contracts/class-registerer'; import { getCanonicalFeeJuice } from '@aztec/protocol-contracts/fee-juice'; import { getCanonicalInstanceDeployer } from '@aztec/protocol-contracts/instance-deployer'; -import { getCanonicalKeyRegistryAddress } from '@aztec/protocol-contracts/key-registry'; import { getCanonicalMultiCallEntrypointAddress } from '@aztec/protocol-contracts/multi-call-entrypoint'; import { type AcirSimulator, @@ -176,10 +175,6 @@ export class PXEService implements PXE { return this.db.getAuthWitness(messageHash); } - async rotateNskM(account: AztecAddress, secretKey: Fq): Promise { - await this.keyStore.rotateMasterNullifierKey(account, secretKey); - } - public addCapsule(capsule: Fr[]) { return this.db.addCapsule(capsule); } @@ -312,8 +307,6 @@ export class PXEService implements PXE { public async getIncomingNotes(filter: IncomingNotesFilter): Promise { const noteDaos = await this.db.getIncomingNotes(filter); - // TODO(#6531): Refactor --> This type conversion is ugly but I decided to keep it this way for now because - // key rotation will affect this const extendedNotes = noteDaos.map(async dao => { let owner = filter.owner; if (owner === undefined) { @@ -341,8 +334,6 @@ export class PXEService implements PXE { public async getOutgoingNotes(filter: OutgoingNotesFilter): Promise { const noteDaos = await this.db.getOutgoingNotes(filter); - // TODO(#6532): Refactor --> This type conversion is ugly but I decided to keep it this way for now because - // key rotation will affect this const extendedNotes = noteDaos.map(async dao => { let owner = filter.owner; if (owner === undefined) { @@ -667,7 +658,6 @@ export class PXEService implements PXE { classRegisterer: ClassRegistererAddress, feeJuice: getCanonicalFeeJuice().address, instanceDeployer: getCanonicalInstanceDeployer().address, - keyRegistry: getCanonicalKeyRegistryAddress(), multiCallEntrypoint: getCanonicalMultiCallEntrypointAddress(), }, }); diff --git a/yarn-project/simulator/src/client/private_execution.test.ts b/yarn-project/simulator/src/client/private_execution.test.ts index d668a2130a3f..a9ab3d33bb44 100644 --- a/yarn-project/simulator/src/client/private_execution.test.ts +++ b/yarn-project/simulator/src/client/private_execution.test.ts @@ -5,9 +5,7 @@ import { type L2BlockNumber, Note, PackedValues, - PublicDataWitness, PublicExecutionRequest, - SiblingPath, TxExecutionRequest, } from '@aztec/circuit-types'; import { @@ -23,7 +21,6 @@ import { NOTE_HASH_TREE_HEIGHT, PUBLIC_DATA_TREE_HEIGHT, PartialStateReference, - PublicDataTreeLeafPreimage, StateReference, TxContext, computeAppNullifierSecretKey, @@ -55,7 +52,7 @@ import { Fr } from '@aztec/foundation/fields'; import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { type FieldsOf } from '@aztec/foundation/types'; import { openTmpStore } from '@aztec/kv-store/utils'; -import { type AppendOnlyTree, INITIAL_LEAF, Poseidon, StandardTree, newTree } from '@aztec/merkle-tree'; +import { type AppendOnlyTree, Poseidon, StandardTree, newTree } from '@aztec/merkle-tree'; import { ChildContractArtifact, ImportTestContractArtifact, @@ -257,16 +254,6 @@ describe('Private Execution test suite', () => { } throw new Error(`Unknown address: ${address}. Recipient: ${recipient}, Owner: ${owner}`); }); - // This oracle gets called when reading ivpk_m from key registry --> we return zero witness indicating that - // the keys were not registered. This triggers non-registered keys flow in which getCompleteAddress oracle - // gets called and we constrain the result by hashing address preimage and checking it matches. - oracle.getPublicDataTreeWitness.mockResolvedValue( - new PublicDataWitness( - 0n, - PublicDataTreeLeafPreimage.empty(), - SiblingPath.ZERO(PUBLIC_DATA_TREE_HEIGHT, INITIAL_LEAF, new Poseidon()), - ), - ); node = mock(); // eslint-disable-next-line @typescript-eslint/no-unused-vars diff --git a/yarn-project/types/src/contracts/protocol_contract_addresses.ts b/yarn-project/types/src/contracts/protocol_contract_addresses.ts index f031a8658f51..ddc1f67e03df 100644 --- a/yarn-project/types/src/contracts/protocol_contract_addresses.ts +++ b/yarn-project/types/src/contracts/protocol_contract_addresses.ts @@ -4,6 +4,5 @@ export type ProtocolContractAddresses = { classRegisterer: AztecAddress; feeJuice: AztecAddress; instanceDeployer: AztecAddress; - keyRegistry: AztecAddress; multiCallEntrypoint: AztecAddress; };