From 3acc686698853c8add5af6602411bed798922783 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Mon, 22 Apr 2024 17:11:28 +0000 Subject: [PATCH 01/93] Initial --- noir-projects/aztec-nr/aztec/src/keys.nr | 3 + .../src/keys/assert_public_key_freshness.nr | 90 +++++++++++++++++++ noir-projects/aztec-nr/aztec/src/lib.nr | 1 + noir-projects/aztec-nr/aztec/src/oracle.nr | 1 + .../aztec-nr/aztec/src/oracle/keys.nr | 24 +++++ .../contracts/test_contract/src/main.nr | 2 +- .../pxe/src/simulator_oracle/index.ts | 10 +++ .../simulator/src/acvm/oracle/oracle.ts | 9 ++ .../simulator/src/acvm/oracle/typed_oracle.ts | 8 +- .../simulator/src/client/db_oracle.ts | 4 +- .../simulator/src/client/view_data_oracle.ts | 6 ++ 11 files changed, 155 insertions(+), 3 deletions(-) create mode 100644 noir-projects/aztec-nr/aztec/src/keys.nr create mode 100644 noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr create mode 100644 noir-projects/aztec-nr/aztec/src/oracle/keys.nr diff --git a/noir-projects/aztec-nr/aztec/src/keys.nr b/noir-projects/aztec-nr/aztec/src/keys.nr new file mode 100644 index 00000000000..ae78c653dd0 --- /dev/null +++ b/noir-projects/aztec-nr/aztec/src/keys.nr @@ -0,0 +1,3 @@ +mod assert_public_key_freshness; + +use crate::keys::assert_public_key_freshness::Map; diff --git a/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr b/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr new file mode 100644 index 00000000000..f94806c935d --- /dev/null +++ b/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr @@ -0,0 +1,90 @@ +use dep::protocol_types::{constants::{GENERATOR_INDEX__PUBLIC_KEYS_HASH, GENERATOR_INDEX__CONTRACT_ADDRESS_V1}, address::AztecAddress}; +use crate::context::PrivateContext; +use crate::note::{ + constants::{GET_NOTE_ORACLE_RETURN_LENGTH, MAX_NOTES_PER_PAGE, VIEW_NOTE_ORACLE_RETURN_LENGTH}, + note_getter_options::{NoteGetterOptions, Select, Sort, SortOrder, Comparator, NoteStatus, PropertySelector}, + note_interface::NoteInterface, note_viewer_options::NoteViewerOptions, + utils::compute_note_hash_for_consumption, +}; +use crate::state_vars::shared_mutable::shared_mutable_private_getter::SharedMutablePrivateGetter; +use crate::hash::pedersen_hash; +use dep::std::hash::poseidon2::Poseidon2::hash as poseidon2_hash; +use crate::oracle; + + +fn assert_nullifier_public_key_fresh( + context: &mut PrivateContext, + address: AztecAddress, + nullifier_public_key_to_test: Field +) { + // Canonical Key Registry + let contract_address_to_read = AztecAddress::from_field(123); + let storage_slot_of_nullifier_public_key = 1; + // We have to derive this slot to get the location of the shared mutable inside the Map + let derived_slot = pedersen_hash( + [storage_slot_of_nullifier_public_key, address.to_field()], + 0 + ); + + // It's a bit wonky because we need to know the delay for get_current_value_in_private to work correctly + let registry_private_getter: SharedMutablePrivateGetter = SharedMutablePrivateGetter::new(*context, contract_address_to_read, derived_slot); + let nullifier_public_key = registry_private_getter.get_current_value_in_private(); + + if (nullifier_public_key == 0) { + check_key(address, 1, nullifier_public_key_to_test); + } else { + assert(nullifier_public_key == nullifier_public_key_to_test); + } +} + +fn check_key(address: AztecAddress, key_type: Field, key: Field) { + let mut keys = check_key_internal(address); + + keys[key_type] = key; + + _check_key_constrain_check_key_internal( + address, + keys[0], + keys[1], + keys[2], + keys[3], + keys[4], + ); +} + +unconstrained fn check_key_internal(address: AztecAddress) -> [Field; 5] { + let keys = oracle::keys::get_public_keys_for_address(address); + + keys +} + +fn _check_key_constrain_check_key_internal( + address: AztecAddress, + partial_address: Field, + nullifier_public_key: Field, + incoming_public_key: Field, + outgoing_public_key: Field, + tagging_public_key: Field + ) { + let public_keys_hash = poseidon2_hash([ + nullifier_public_key, + incoming_public_key, + outgoing_public_key, + tagging_public_key, + GENERATOR_INDEX__PUBLIC_KEYS_HASH, + ], + 5 + ); + + let computed_address = AztecAddress::from_field( + poseidon2_hash([ + partial_address.to_field(), + public_keys_hash.to_field(), + GENERATOR_INDEX__CONTRACT_ADDRESS_V1 as Field, + ], + 3 + ) + ); + + assert(computed_address.eq(address), "Computed address does not match supplied address"); +} diff --git a/noir-projects/aztec-nr/aztec/src/lib.nr b/noir-projects/aztec-nr/aztec/src/lib.nr index 81390fb52eb..67a3c8c55b4 100644 --- a/noir-projects/aztec-nr/aztec/src/lib.nr +++ b/noir-projects/aztec-nr/aztec/src/lib.nr @@ -3,6 +3,7 @@ mod deploy; mod hash; mod history; mod initializer; +mod keys; mod log; mod messaging; mod note; diff --git a/noir-projects/aztec-nr/aztec/src/oracle.nr b/noir-projects/aztec-nr/aztec/src/oracle.nr index 57415dc9575..41c6e37adfb 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle.nr @@ -10,6 +10,7 @@ mod get_nullifier_membership_witness; mod get_public_data_witness; mod get_membership_witness; mod get_public_key; +mod keys; mod nullifier_key; mod get_sibling_path; mod unsafe_rand; diff --git a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr new file mode 100644 index 00000000000..6894ccab3b0 --- /dev/null +++ b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr @@ -0,0 +1,24 @@ +use dep::protocol_types::address::AztecAddress; + +#[oracle(getPublicKeysForAddress)] +fn get_public_keys_for_address_oracle( + address: AztecAddress, +) -> [Field; 4] {} + +unconstrained fn get_public_keys_for_address_oracle_wrapper( + address: AztecAddress +) -> [Field; 4] { + get_public_keys_for_address_oracle( + address, + ) +} + +unconstrained pub fn get_public_keys_for_address( + address: AztecAddress, +) -> [Field; 4] { + let public_keys = get_public_keys_for_address_oracle_wrapper( + address, + ); + + public_keys +} 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 43a0d80c528..d03ef87095d 100644 --- a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr @@ -389,7 +389,7 @@ contract Test { 0 ); // It's a bit wonky because we need to know the delay for get_current_value_in_private to work correctly - let registry_private_getter: SharedMutablePrivateGetter = SharedMutablePrivateGetter::new(context, contract_address_to_read, derived_slot); + let registry_private_getter: SharedMutablePrivateGetter = SharedMutablePrivateGetter::new(context, contract_address_to_read, derived_slot); let nullifier_public_key = registry_private_getter.get_current_value_in_private(); context.emit_unencrypted_log(nullifier_public_key); diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index da0891190f6..ea9b08a033e 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -9,6 +9,7 @@ import { type SiblingPath, } from '@aztec/circuit-types'; import { + Point, type AztecAddress, type CompleteAddress, type EthAddress, @@ -78,6 +79,15 @@ export class SimulatorOracle implements DBOracle { return capsule; } + async getPublicKeysForAddress(address: AztecAddress): Promise { + const nullifierPublicKey = await this.keyStore.getMasterNullifierPublicKey(address); + const incomingViewingPublicKey = await this.keyStore.getMasterIncomingViewingPublicKey(address); + const outgoingViewingPublicKey = await this.keyStore.getMasterOutgoingViewingPublicKey(address); + const taggingPublicKey = await this.keyStore.getMasterTaggingPublicKey(address); + + return [nullifierPublicKey, incomingViewingPublicKey, outgoingViewingPublicKey, taggingPublicKey] + } + async getNotes(contractAddress: AztecAddress, storageSlot: Fr, status: NoteStatus) { const noteDaos = await this.db.getNotes({ contractAddress, diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index f1271b791dd..fa0dbc6a149 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -172,6 +172,15 @@ export class Oracle { return capsule.map(toACVMField); } + async getPublicKeysForAddress( + [address]: ACVMField[], + ): Promise { + const keys = await this.typedOracle.getPublicKeysForAddress(AztecAddress.fromField(fromACVMField(address))); + const acvmKeys = keys?.flatMap(key => key.toFields().map(f => toACVMField(f))) ?? Array(8).fill(toACVMField(0)); + + return acvmKeys; + } + async getNotes( [storageSlot]: ACVMField[], [numSelects]: ACVMField[], diff --git a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts index 70f57233af1..28ed6f9d4a1 100644 --- a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts @@ -17,7 +17,7 @@ import { } from '@aztec/circuits.js'; import { type FunctionSelector } from '@aztec/foundation/abi'; import { type AztecAddress } from '@aztec/foundation/aztec-address'; -import { Fr } from '@aztec/foundation/fields'; +import { Fr, Point } from '@aztec/foundation/fields'; import { type ContractInstance } from '@aztec/types/contracts'; /** Nullifier keys which both correspond to the same master nullifier secret key. */ @@ -140,6 +140,12 @@ export abstract class TypedOracle { throw new OracleMethodNotAvailableError('popCapsule'); } + getPublicKeysForAddress( + _address: AztecAddress, + ): Promise { + throw new OracleMethodNotAvailableError('getPublicKeysForAddress'); + } + getNotes( _storageSlot: Fr, _numSelects: number, diff --git a/yarn-project/simulator/src/client/db_oracle.ts b/yarn-project/simulator/src/client/db_oracle.ts index 3c3d5126814..3e193b56472 100644 --- a/yarn-project/simulator/src/client/db_oracle.ts +++ b/yarn-project/simulator/src/client/db_oracle.ts @@ -9,7 +9,7 @@ import { type CompleteAddress, type Header } from '@aztec/circuits.js'; import { type FunctionArtifactWithDebugMetadata, type FunctionSelector } from '@aztec/foundation/abi'; import { type AztecAddress } from '@aztec/foundation/aztec-address'; import { type EthAddress } from '@aztec/foundation/eth-address'; -import { type Fr } from '@aztec/foundation/fields'; +import { Point, type Fr } from '@aztec/foundation/fields'; import { type ContractInstance } from '@aztec/types/contracts'; import { type NoteData, type NullifierKeys } from '../acvm/index.js'; @@ -65,6 +65,8 @@ export interface DBOracle extends CommitmentsDB { */ popCapsule(): Promise; + getPublicKeysForAddress(address: AztecAddress): Promise; + /** * Retrieve nullifier keys associated with a specific account and app/contract address. * diff --git a/yarn-project/simulator/src/client/view_data_oracle.ts b/yarn-project/simulator/src/client/view_data_oracle.ts index b4c02039175..00bb685e8c8 100644 --- a/yarn-project/simulator/src/client/view_data_oracle.ts +++ b/yarn-project/simulator/src/client/view_data_oracle.ts @@ -166,6 +166,12 @@ export class ViewDataOracle extends TypedOracle { return this.db.popCapsule(); } + public override getPublicKeysForAddress( + address: AztecAddress, + ) { + return this.db.getPublicKeysForAddress(address); + } + /** * Gets some notes for a contract address and storage slot. * Returns a flattened array containing filtered notes. From 177445f1b16b6e9d1a0c31c30c9d588b9c1ad62a Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Mon, 22 Apr 2024 19:09:35 +0000 Subject: [PATCH 02/93] fix --- .../src/keys/assert_public_key_freshness.nr | 43 +++++++++++-------- .../aztec-nr/aztec/src/oracle/keys.nr | 31 +++++++++++-- 2 files changed, 51 insertions(+), 23 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr b/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr index f94806c935d..a48175d30ce 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr @@ -1,4 +1,4 @@ -use dep::protocol_types::{constants::{GENERATOR_INDEX__PUBLIC_KEYS_HASH, GENERATOR_INDEX__CONTRACT_ADDRESS_V1}, address::AztecAddress}; +use dep::protocol_types::{constants::{GENERATOR_INDEX__PUBLIC_KEYS_HASH, GENERATOR_INDEX__CONTRACT_ADDRESS_V1}, address::AztecAddress, grumpkin_point::GrumpkinPoint}; use crate::context::PrivateContext; use crate::note::{ constants::{GET_NOTE_ORACLE_RETURN_LENGTH, MAX_NOTES_PER_PAGE, VIEW_NOTE_ORACLE_RETURN_LENGTH}, @@ -15,7 +15,7 @@ use crate::oracle; fn assert_nullifier_public_key_fresh( context: &mut PrivateContext, address: AztecAddress, - nullifier_public_key_to_test: Field + nullifier_public_key_to_test: GrumpkinPoint, ) { // Canonical Key Registry let contract_address_to_read = AztecAddress::from_field(123); @@ -28,52 +28,57 @@ fn assert_nullifier_public_key_fresh( // It's a bit wonky because we need to know the delay for get_current_value_in_private to work correctly let registry_private_getter: SharedMutablePrivateGetter = SharedMutablePrivateGetter::new(*context, contract_address_to_read, derived_slot); - let nullifier_public_key = registry_private_getter.get_current_value_in_private(); + let hashed_nullifier_public_key = registry_private_getter.get_current_value_in_private(); - if (nullifier_public_key == 0) { + if (hashed_nullifier_public_key == 0) { check_key(address, 1, nullifier_public_key_to_test); } else { - assert(nullifier_public_key == nullifier_public_key_to_test); + assert(hashed_nullifier_public_key == pedersen_hash(nullifier_public_key_to_test.serialize(), 0)); } } -fn check_key(address: AztecAddress, key_type: Field, key: Field) { - let mut keys = check_key_internal(address); +fn check_key(address: AztecAddress, key_type: Field, key: GrumpkinPoint) { + let mut (partial_address, keys) = check_key_internal(address); keys[key_type] = key; _check_key_constrain_check_key_internal( address, + partial_address, keys[0], keys[1], keys[2], keys[3], - keys[4], ); } -unconstrained fn check_key_internal(address: AztecAddress) -> [Field; 5] { +unconstrained fn check_key_internal(address: AztecAddress) -> (Field, [GrumpkinPoint; 4]) { let keys = oracle::keys::get_public_keys_for_address(address); + let partial_address = oracle::keys::get_address_metadata(address); - keys + (partial_address, keys) } fn _check_key_constrain_check_key_internal( address: AztecAddress, partial_address: Field, - nullifier_public_key: Field, - incoming_public_key: Field, - outgoing_public_key: Field, - tagging_public_key: Field + nullifier_public_key: GrumpkinPoint, + incoming_public_key: GrumpkinPoint, + outgoing_public_key: GrumpkinPoint, + tagging_public_key: GrumpkinPoint ) { let public_keys_hash = poseidon2_hash([ - nullifier_public_key, - incoming_public_key, - outgoing_public_key, - tagging_public_key, + nullifier_public_key.serialize()[0], + nullifier_public_key.serialize()[1], + incoming_public_key.serialize()[0], + incoming_public_key.serialize()[1], + outgoing_public_key.serialize()[0], + outgoing_public_key.serialize()[1], + tagging_public_key.serialize()[0], + tagging_public_key.serialize()[1], GENERATOR_INDEX__PUBLIC_KEYS_HASH, ], - 5 + 9 ); let computed_address = AztecAddress::from_field( diff --git a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr index 6894ccab3b0..44bb1cf5b96 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr @@ -1,13 +1,13 @@ -use dep::protocol_types::address::AztecAddress; +use dep::protocol_types::{address::AztecAddress, grumpkin_point::GrumpkinPoint}; #[oracle(getPublicKeysForAddress)] fn get_public_keys_for_address_oracle( address: AztecAddress, -) -> [Field; 4] {} +) -> [GrumpkinPoint; 4] {} unconstrained fn get_public_keys_for_address_oracle_wrapper( address: AztecAddress -) -> [Field; 4] { +) -> [GrumpkinPoint; 4] { get_public_keys_for_address_oracle( address, ) @@ -15,10 +15,33 @@ unconstrained fn get_public_keys_for_address_oracle_wrapper( unconstrained pub fn get_public_keys_for_address( address: AztecAddress, -) -> [Field; 4] { +) -> [GrumpkinPoint; 4] { let public_keys = get_public_keys_for_address_oracle_wrapper( address, ); public_keys } + +#[oracle(getAddressMetadata)] +fn get_address_metadata_oracle( + address: AztecAddress, +) -> [Field; 1] {} + +unconstrained fn get_address_metadata_oracle_wrapper( + address: AztecAddress +) -> [Field; 1] { + get_address_metadata_oracle( + address, + ) +} + +unconstrained pub fn get_address_metadata( + address: AztecAddress, +) -> Field { + let partial_address = get_address_metadata_oracle_wrapper( + address, + ); + + partial_address[0] +} From fdbb60a11942d5c8472f73e5e596ef48a5657cc3 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Mon, 22 Apr 2024 20:55:26 +0000 Subject: [PATCH 03/93] good --- noir-projects/aztec-nr/aztec/src/keys.nr | 2 +- .../src/keys/assert_public_key_freshness.nr | 13 ++++--- .../aztec-nr/aztec/src/oracle/keys.nr | 36 +++++++++---------- yarn-project/circuit-types/src/keys/index.ts | 1 + yarn-project/key-store/src/address_book.ts | 25 +++++++++++++ yarn-project/key-store/src/index.ts | 1 + .../pxe/src/simulator_oracle/index.ts | 2 +- .../simulator/src/acvm/oracle/oracle.ts | 15 ++++---- .../simulator/src/acvm/oracle/typed_oracle.ts | 6 ++++ .../simulator/src/client/db_oracle.ts | 2 ++ 10 files changed, 70 insertions(+), 33 deletions(-) create mode 100644 yarn-project/key-store/src/address_book.ts diff --git a/noir-projects/aztec-nr/aztec/src/keys.nr b/noir-projects/aztec-nr/aztec/src/keys.nr index ae78c653dd0..7e83884a099 100644 --- a/noir-projects/aztec-nr/aztec/src/keys.nr +++ b/noir-projects/aztec-nr/aztec/src/keys.nr @@ -1,3 +1,3 @@ mod assert_public_key_freshness; -use crate::keys::assert_public_key_freshness::Map; +use crate::keys::assert_public_key_freshness::assert_nullifier_public_key_fresh; diff --git a/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr b/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr index a48175d30ce..80f218ce3bd 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr @@ -1,4 +1,4 @@ -use dep::protocol_types::{constants::{GENERATOR_INDEX__PUBLIC_KEYS_HASH, GENERATOR_INDEX__CONTRACT_ADDRESS_V1}, address::AztecAddress, grumpkin_point::GrumpkinPoint}; +use dep::protocol_types::{constants::{GENERATOR_INDEX__PUBLIC_KEYS_HASH, GENERATOR_INDEX__CONTRACT_ADDRESS_V1}, address::{AztecAddress, PartialAddress}, grumpkin_point::GrumpkinPoint}; use crate::context::PrivateContext; use crate::note::{ constants::{GET_NOTE_ORACLE_RETURN_LENGTH, MAX_NOTES_PER_PAGE, VIEW_NOTE_ORACLE_RETURN_LENGTH}, @@ -40,7 +40,7 @@ fn assert_nullifier_public_key_fresh( fn check_key(address: AztecAddress, key_type: Field, key: GrumpkinPoint) { let mut (partial_address, keys) = check_key_internal(address); - keys[key_type] = key; + assert(keys[key_type].eq(key)); _check_key_constrain_check_key_internal( address, @@ -52,16 +52,15 @@ fn check_key(address: AztecAddress, key_type: Field, key: GrumpkinPoint) { ); } -unconstrained fn check_key_internal(address: AztecAddress) -> (Field, [GrumpkinPoint; 4]) { - let keys = oracle::keys::get_public_keys_for_address(address); - let partial_address = oracle::keys::get_address_metadata(address); +unconstrained fn check_key_internal(address: AztecAddress) -> (PartialAddress, [GrumpkinPoint; 4]) { + let (partial_address, public_keys) = oracle::keys::get_public_keys_and_partial_address(address); - (partial_address, keys) + (partial_address, public_keys) } fn _check_key_constrain_check_key_internal( address: AztecAddress, - partial_address: Field, + partial_address: PartialAddress, nullifier_public_key: GrumpkinPoint, incoming_public_key: GrumpkinPoint, outgoing_public_key: GrumpkinPoint, diff --git a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr index 44bb1cf5b96..4ff757be4d4 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr @@ -1,4 +1,4 @@ -use dep::protocol_types::{address::AztecAddress, grumpkin_point::GrumpkinPoint}; +use dep::protocol_types::{address::{AztecAddress, PartialAddress, PublicKeysHash}, grumpkin_point::GrumpkinPoint}; #[oracle(getPublicKeysForAddress)] fn get_public_keys_for_address_oracle( @@ -23,25 +23,25 @@ unconstrained pub fn get_public_keys_for_address( public_keys } -#[oracle(getAddressMetadata)] -fn get_address_metadata_oracle( - address: AztecAddress, -) -> [Field; 1] {} -unconstrained fn get_address_metadata_oracle_wrapper( - address: AztecAddress -) -> [Field; 1] { - get_address_metadata_oracle( - address, - ) +#[oracle(getPublicKeysAndPartialAddress)] +fn get_public_keys_and_partial_address_oracle(_address: AztecAddress) -> [Field; 9] {} + +unconstrained fn get_public_keys_and_partial_address_oracle_wrapper(address: AztecAddress) -> [Field; 9] { + get_public_keys_and_partial_address_oracle(address) } -unconstrained pub fn get_address_metadata( - address: AztecAddress, -) -> Field { - let partial_address = get_address_metadata_oracle_wrapper( - address, - ); +pub fn get_public_keys_and_partial_address(address: AztecAddress) -> (PartialAddress, [GrumpkinPoint; 4]) { + let result = get_public_keys_and_partial_address_oracle_wrapper(address); + let partial_address = PartialAddress::from_field(result[0]); + let nullifier_pub_key = GrumpkinPoint::new(result[1], result[2]); + let incoming_pub_key = GrumpkinPoint::new(result[3], result[4]); + let outgoing_pub_key = GrumpkinPoint::new(result[5], result[6]); + let tagging_pub_key = GrumpkinPoint::new(result[7], result[8]); + + // TODO(#5830): disabling the following constraint until we update the oracle according to the new key scheme + // let calculated_address = AztecAddress::compute(PublicKeysHash::compute(pub_key), partial_address); + // assert(calculated_address.eq(address)); - partial_address[0] + (partial_address, [nullifier_pub_key, incoming_pub_key, outgoing_pub_key, tagging_pub_key]) } diff --git a/yarn-project/circuit-types/src/keys/index.ts b/yarn-project/circuit-types/src/keys/index.ts index f137b0d567a..02ea81b3bcc 100644 --- a/yarn-project/circuit-types/src/keys/index.ts +++ b/yarn-project/circuit-types/src/keys/index.ts @@ -1,2 +1,3 @@ export * from './key_pair.js'; export * from './key_store.js'; +export * from './address_book.js'; diff --git a/yarn-project/key-store/src/address_book.ts b/yarn-project/key-store/src/address_book.ts new file mode 100644 index 00000000000..8264007f396 --- /dev/null +++ b/yarn-project/key-store/src/address_book.ts @@ -0,0 +1,25 @@ +import { + Fr, + type AztecAddress, + type PartialAddress, +} from '@aztec/circuits.js'; +import { type AddressBook } from '@aztec/circuit-types'; +import { AztecKVStore, AztecMap } from '@aztec/kv-store'; + + +export class KVAddressBook implements AddressBook { + #addressMetadata: AztecMap; + + constructor(database: AztecKVStore) { + this.#addressMetadata = database.openMap('address_book'); + } + + public async addPartialAddress(partialAddress: PartialAddress, address: AztecAddress) { + await this.#addressMetadata.set(address.toString(), partialAddress.toBuffer()); + } + + getPartialAddress(address: AztecAddress): PartialAddress | undefined { + const partialBuf = this.#addressMetadata.get(address.toString()); + return partialBuf === undefined ? undefined : Fr.fromBuffer(partialBuf); + }; +} \ No newline at end of file diff --git a/yarn-project/key-store/src/index.ts b/yarn-project/key-store/src/index.ts index e4ae5ce271c..4f06a44db34 100644 --- a/yarn-project/key-store/src/index.ts +++ b/yarn-project/key-store/src/index.ts @@ -1 +1,2 @@ export * from './test_key_store.js'; +export * from './address_book.js'; diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index ea9b08a033e..56c53a2d806 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -9,11 +9,11 @@ import { type SiblingPath, } from '@aztec/circuit-types'; import { + Fr, Point, type AztecAddress, type CompleteAddress, type EthAddress, - type Fr, type FunctionSelector, type Header, type L1_TO_L2_MSG_TREE_HEIGHT, diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index fa0dbc6a149..02f820666fd 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -53,6 +53,7 @@ export class Oracle { ]; } + // TODO (ek): Nuke this async getPublicKeyAndPartialAddress([address]: ACVMField[]) { const { publicKey, partialAddress } = await this.typedOracle.getCompleteAddress( AztecAddress.fromField(fromACVMField(address)), @@ -172,13 +173,15 @@ export class Oracle { return capsule.map(toACVMField); } - async getPublicKeysForAddress( - [address]: ACVMField[], - ): Promise { - const keys = await this.typedOracle.getPublicKeysForAddress(AztecAddress.fromField(fromACVMField(address))); - const acvmKeys = keys?.flatMap(key => key.toFields().map(f => toACVMField(f))) ?? Array(8).fill(toACVMField(0)); + async getPublicKeysAndPartialAddress([address]: ACVMField[]): Promise { + const { partialAddress } = await this.typedOracle.getCompleteAddress( + AztecAddress.fromField(fromACVMField(address)), + ); + + const publicKeys = await this.typedOracle.getPublicKeysForAddress(AztecAddress.fromField(fromACVMField(address))); + const acvmKeys = publicKeys?.flatMap(key => key.toFields()) ?? Array(8).fill(toACVMField(0)); - return acvmKeys; + return [partialAddress, ...acvmKeys].map(toACVMField); } async getNotes( diff --git a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts index 28ed6f9d4a1..86b3d5d6439 100644 --- a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts @@ -146,6 +146,12 @@ export abstract class TypedOracle { throw new OracleMethodNotAvailableError('getPublicKeysForAddress'); } + async getAddressMetadata( + _address: AztecAddress, + ): Promise { + throw new OracleMethodNotAvailableError('getAddressMetadata'); + } + getNotes( _storageSlot: Fr, _numSelects: number, diff --git a/yarn-project/simulator/src/client/db_oracle.ts b/yarn-project/simulator/src/client/db_oracle.ts index 3e193b56472..b8d56098703 100644 --- a/yarn-project/simulator/src/client/db_oracle.ts +++ b/yarn-project/simulator/src/client/db_oracle.ts @@ -67,6 +67,8 @@ export interface DBOracle extends CommitmentsDB { getPublicKeysForAddress(address: AztecAddress): Promise; + getAddressMetadata(address: AztecAddress): Promise; + /** * Retrieve nullifier keys associated with a specific account and app/contract address. * From 2d3a95f66de8c88538480f8f1bb1a75223490f90 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Mon, 22 Apr 2024 20:58:38 +0000 Subject: [PATCH 04/93] asdf --- yarn-project/circuit-types/src/keys/index.ts | 1 - yarn-project/key-store/src/address_book.ts | 25 -------------------- yarn-project/key-store/src/index.ts | 1 - 3 files changed, 27 deletions(-) delete mode 100644 yarn-project/key-store/src/address_book.ts diff --git a/yarn-project/circuit-types/src/keys/index.ts b/yarn-project/circuit-types/src/keys/index.ts index 02ea81b3bcc..f137b0d567a 100644 --- a/yarn-project/circuit-types/src/keys/index.ts +++ b/yarn-project/circuit-types/src/keys/index.ts @@ -1,3 +1,2 @@ export * from './key_pair.js'; export * from './key_store.js'; -export * from './address_book.js'; diff --git a/yarn-project/key-store/src/address_book.ts b/yarn-project/key-store/src/address_book.ts deleted file mode 100644 index 8264007f396..00000000000 --- a/yarn-project/key-store/src/address_book.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { - Fr, - type AztecAddress, - type PartialAddress, -} from '@aztec/circuits.js'; -import { type AddressBook } from '@aztec/circuit-types'; -import { AztecKVStore, AztecMap } from '@aztec/kv-store'; - - -export class KVAddressBook implements AddressBook { - #addressMetadata: AztecMap; - - constructor(database: AztecKVStore) { - this.#addressMetadata = database.openMap('address_book'); - } - - public async addPartialAddress(partialAddress: PartialAddress, address: AztecAddress) { - await this.#addressMetadata.set(address.toString(), partialAddress.toBuffer()); - } - - getPartialAddress(address: AztecAddress): PartialAddress | undefined { - const partialBuf = this.#addressMetadata.get(address.toString()); - return partialBuf === undefined ? undefined : Fr.fromBuffer(partialBuf); - }; -} \ No newline at end of file diff --git a/yarn-project/key-store/src/index.ts b/yarn-project/key-store/src/index.ts index 4f06a44db34..e4ae5ce271c 100644 --- a/yarn-project/key-store/src/index.ts +++ b/yarn-project/key-store/src/index.ts @@ -1,2 +1 @@ export * from './test_key_store.js'; -export * from './address_book.js'; From 58f9650f88539f852a1c5e029743e958b42fdd3e Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Tue, 23 Apr 2024 15:13:24 +0000 Subject: [PATCH 05/93] working tests --- .../src/keys/assert_public_key_freshness.nr | 54 ++- .../key_registry_contract/src/main.nr | 46 +- .../contracts/test_contract/src/main.nr | 13 +- .../types/src/address/partial_address.nr | 4 + .../circuit-types/src/interfaces/pxe.ts | 5 +- .../circuit-types/src/keys/key_store.ts | 12 + .../end-to-end/src/e2e_key_registry.test.ts | 417 +++++++++++------- yarn-project/key-store/src/test_key_store.ts | 13 + .../pxe/src/pxe_service/pxe_service.ts | 9 +- .../simulator/src/acvm/oracle/oracle.ts | 26 +- .../simulator/src/acvm/oracle/typed_oracle.ts | 8 +- .../simulator/src/client/db_oracle.ts | 2 - 12 files changed, 382 insertions(+), 227 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr b/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr index 80f218ce3bd..5390a2b7848 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr @@ -1,4 +1,7 @@ -use dep::protocol_types::{constants::{GENERATOR_INDEX__PUBLIC_KEYS_HASH, GENERATOR_INDEX__CONTRACT_ADDRESS_V1}, address::{AztecAddress, PartialAddress}, grumpkin_point::GrumpkinPoint}; +use dep::protocol_types::{ + constants::{ + GENERATOR_INDEX__PUBLIC_KEYS_HASH, GENERATOR_INDEX__CONTRACT_ADDRESS_V1}, + address::{AztecAddress, PartialAddress}, grumpkin_point::GrumpkinPoint}; use crate::context::PrivateContext; use crate::note::{ constants::{GET_NOTE_ORACLE_RETURN_LENGTH, MAX_NOTES_PER_PAGE, VIEW_NOTE_ORACLE_RETURN_LENGTH}, @@ -7,18 +10,28 @@ use crate::note::{ utils::compute_note_hash_for_consumption, }; use crate::state_vars::shared_mutable::shared_mutable_private_getter::SharedMutablePrivateGetter; -use crate::hash::pedersen_hash; -use dep::std::hash::poseidon2::Poseidon2::hash as poseidon2_hash; +use crate::hash::{pedersen_hash, poseidon2_hash}; use crate::oracle; +struct PublicKeyTypeEnum { + NULLIFIER: u8, + INCOMING: u8, +} + +global PublicKeyType = PublicKeyTypeEnum { + NULLIFIER: 0, + INCOMING: 1, +}; -fn assert_nullifier_public_key_fresh( +pub fn assert_nullifier_public_key_fresh( context: &mut PrivateContext, address: AztecAddress, nullifier_public_key_to_test: GrumpkinPoint, + // remove after + registry_contract_address: AztecAddress, ) { // Canonical Key Registry - let contract_address_to_read = AztecAddress::from_field(123); + let contract_address_to_read = registry_contract_address; let storage_slot_of_nullifier_public_key = 1; // We have to derive this slot to get the location of the shared mutable inside the Map let derived_slot = pedersen_hash( @@ -31,15 +44,22 @@ fn assert_nullifier_public_key_fresh( let hashed_nullifier_public_key = registry_private_getter.get_current_value_in_private(); if (hashed_nullifier_public_key == 0) { - check_key(address, 1, nullifier_public_key_to_test); + check_key(address, PublicKeyType.NULLIFIER, nullifier_public_key_to_test); } else { - assert(hashed_nullifier_public_key == pedersen_hash(nullifier_public_key_to_test.serialize(), 0)); + assert(hashed_nullifier_public_key == poseidon2_hash(nullifier_public_key_to_test.serialize())); } } -fn check_key(address: AztecAddress, key_type: Field, key: GrumpkinPoint) { +fn check_key(address: AztecAddress, key_type: u8, key: GrumpkinPoint) { let mut (partial_address, keys) = check_key_internal(address); + crate::oracle::debug_log::debug_log_array_with_prefix("partial", [partial_address]); + crate::oracle::debug_log::debug_log_array_with_prefix("ACTUAL NULLIFIER", key.serialize()); + crate::oracle::debug_log::debug_log_array_with_prefix("nullifier", keys[0].serialize()); + crate::oracle::debug_log::debug_log_array_with_prefix("incoming", keys[1].serialize()); + crate::oracle::debug_log::debug_log_array_with_prefix("outgoing", keys[2].serialize()); + crate::oracle::debug_log::debug_log_array_with_prefix("tagging", keys[3].serialize()); + assert(keys[key_type].eq(key)); _check_key_constrain_check_key_internal( @@ -49,7 +69,7 @@ fn check_key(address: AztecAddress, key_type: Field, key: GrumpkinPoint) { keys[1], keys[2], keys[3], - ); + ) } unconstrained fn check_key_internal(address: AztecAddress) -> (PartialAddress, [GrumpkinPoint; 4]) { @@ -76,19 +96,15 @@ fn _check_key_constrain_check_key_internal( tagging_public_key.serialize()[0], tagging_public_key.serialize()[1], GENERATOR_INDEX__PUBLIC_KEYS_HASH, - ], - 9 - ); + ]); let computed_address = AztecAddress::from_field( poseidon2_hash([ - partial_address.to_field(), - public_keys_hash.to_field(), - GENERATOR_INDEX__CONTRACT_ADDRESS_V1 as Field, - ], - 3 - ) + partial_address.to_field(), + public_keys_hash.to_field(), + GENERATOR_INDEX__CONTRACT_ADDRESS_V1, + ]) ); - assert(computed_address.eq(address), "Computed address does not match supplied address"); + assert(computed_address.eq(address)); } 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 index d4ed6addd03..c0e2ff7e8af 100644 --- a/noir-projects/noir-contracts/contracts/key_registry_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/key_registry_contract/src/main.nr @@ -10,6 +10,7 @@ contract KeyRegistry { protocol_types::{ abis::function_selector::FunctionSelector, contract_class_id::ContractClassId, + grumpkin_point::GrumpkinPoint, address::{ AztecAddress, EthAddress, @@ -34,19 +35,19 @@ contract KeyRegistry { struct Storage { // We are not supporting rotating / changing keys other than the nullifier public in the registry at the moment, but will in the future. // Uncomment lines below to enable that functionality - nullifier_public_key_registry: Map>, + nullifier_public_key_hash_registry: Map>, // incoming_public_key_registry: Map>, // outgoing_public_key_registry: Map>, // tagging_public_key_registry: Map>, } #[aztec(public)] - fn rotate_nullifier_public_key( + fn rotate_nullifier_public_key_hash( address: AztecAddress, - new_nullifier_public_key: Field, + new_nullifier_public_key_hash: Field, ) { assert( - new_nullifier_public_key != 0, + new_nullifier_public_key_hash != 0, "New nullifier public key must be non-zero" ); @@ -54,25 +55,26 @@ contract KeyRegistry { assert_current_call_valid_authwit_public(&mut context, address); } - let nullifier_key_registry = storage.nullifier_public_key_registry.at(address); + let nullifier_key_registry = storage.nullifier_public_key_hash_registry.at(address); - nullifier_key_registry.schedule_value_change(new_nullifier_public_key); + nullifier_key_registry.schedule_value_change(new_nullifier_public_key_hash); } #[aztec(public)] fn register( address: AztecAddress, partial_address: PartialAddress, - nullifier_public_key: Field, - incoming_public_key: Field, - outgoing_public_key: Field, - tagging_public_key: Field, + nullifier_public_key: GrumpkinPoint, + incoming_public_key: GrumpkinPoint, + outgoing_public_key: GrumpkinPoint, + tagging_public_key: GrumpkinPoint, ) { assert( - (nullifier_public_key != 0) & - (incoming_public_key != 0) & - (outgoing_public_key != 0) & - (tagging_public_key != 0), + !partial_address.is_zero() & + !nullifier_public_key.is_zero() & + !incoming_public_key.is_zero() & + !outgoing_public_key.is_zero() & + !tagging_public_key.is_zero(), "All public keys must be non-zero" ); @@ -81,10 +83,14 @@ contract KeyRegistry { // let address = AztecAddress::compute(public_keys_hash, partial_address); // We could also pass in original_public_keys_hash instead of computing it here, if all we need the original one is for being able to prove ownership of address let public_keys_hash = poseidon2_hash([ - nullifier_public_key, - incoming_public_key, - outgoing_public_key, - tagging_public_key, + nullifier_public_key.serialize()[0], + nullifier_public_key.serialize()[1], + incoming_public_key.serialize()[0], + incoming_public_key.serialize()[1], + outgoing_public_key.serialize()[0], + outgoing_public_key.serialize()[1], + tagging_public_key.serialize()[0], + tagging_public_key.serialize()[1], GENERATOR_INDEX__PUBLIC_KEYS_HASH, ] ); @@ -100,14 +106,14 @@ contract KeyRegistry { assert(computed_address.eq(address), "Computed address does not match supplied address"); - let nullifier_key_registry = storage.nullifier_public_key_registry.at(address); + let nullifier_key_hash_registry = storage.nullifier_public_key_hash_registry.at(address); // We are not supporting rotating / changing keys other than the nullifier public in the registry at the moment, but will in the future. // Uncomment lines below to enable that functionality // let incoming_key_registry = storage.incoming_public_key_registry.at(address); // let outgoing_key_registry = storage.outgoing_public_key_registry.at(address); // let tagging_key_registry = storage.taggin_public_key_registry.at(address); - nullifier_key_registry.schedule_value_change(nullifier_public_key); + nullifier_key_hash_registry.schedule_value_change(poseidon2_hash(nullifier_public_key.serialize())); // We are not supporting rotating / changing keys other than the nullifier public in the registry at the moment, but will in the future. // Uncomment lines below to enable that functionality // incoming_key_registry.schedule_value_change(new_incoming_public_key); // outgoing_key_registry.schedule_value_change(new_outgoing_public_key); 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 d03ef87095d..982a6b36e79 100644 --- a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr @@ -7,7 +7,8 @@ contract Test { use dep::aztec::protocol_types::{ abis::private_circuit_public_inputs::PrivateCircuitPublicInputs, - constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, traits::Serialize + constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, traits::Serialize, + grumpkin_point::GrumpkinPoint }; use dep::aztec::note::constants::MAX_NOTES_PER_PAGE; @@ -15,6 +16,7 @@ contract Test { use dep::aztec::state_vars::shared_mutable::SharedMutablePrivateGetter; use dep::aztec::{ + keys::assert_public_key_freshness::assert_nullifier_public_key_fresh, context::{Context, inputs::private_context_inputs::PrivateContextInputs}, hash::{pedersen_hash, compute_secret_hash, ArgsHasher}, note::{ @@ -411,6 +413,15 @@ contract Test { context.emit_unencrypted_log(authorized); } + #[aztec(private)] + fn test_nullifier_key_freshness( + address: AztecAddress, + public_nullifying_key: GrumpkinPoint, + key_registry_contract: AztecAddress, + ) { + assert_nullifier_public_key_fresh(&mut context, address, public_nullifying_key, key_registry_contract); + } + #[aztec(public)] fn delay() { // We use this as a util function to "mine a block" diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/address/partial_address.nr b/noir-projects/noir-protocol-circuits/crates/types/src/address/partial_address.nr index 359fae794ba..b7b6b7caec1 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/address/partial_address.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/address/partial_address.nr @@ -69,6 +69,10 @@ impl PartialAddress { self.inner } + pub fn is_zero(self) -> bool { + self.to_field() == 0 + } + pub fn assert_is_zero(self) { assert(self.to_field() == 0); } diff --git a/yarn-project/circuit-types/src/interfaces/pxe.ts b/yarn-project/circuit-types/src/interfaces/pxe.ts index 0eba3e00512..b1f0fb0327c 100644 --- a/yarn-project/circuit-types/src/interfaces/pxe.ts +++ b/yarn-project/circuit-types/src/interfaces/pxe.ts @@ -1,4 +1,4 @@ -import { type AztecAddress, type CompleteAddress, type Fr, type PartialAddress } from '@aztec/circuits.js'; +import { Point, type AztecAddress, type CompleteAddress, type Fr, type PartialAddress } from '@aztec/circuits.js'; import { type ContractArtifact } from '@aztec/foundation/abi'; import { type ContractClassWithId, type ContractInstanceWithAddress } from '@aztec/types/contracts'; import { type NodeInfo } from '@aztec/types/interfaces'; @@ -73,7 +73,8 @@ export interface PXE { * the recipient's notes. We can send notes to this account because we can encrypt them with the recipient's * public key. */ - registerRecipient(recipient: CompleteAddress): Promise; + // TODO: FIX THIS AFTER THE COMPLETE ADDRESS REFACTOR + registerRecipient(recipient: CompleteAddress, publicKeys?: Point[]): Promise; /** * Retrieves the user accounts registered on this PXE Service. diff --git a/yarn-project/circuit-types/src/keys/key_store.ts b/yarn-project/circuit-types/src/keys/key_store.ts index 55c69f0facb..f670683d905 100644 --- a/yarn-project/circuit-types/src/keys/key_store.ts +++ b/yarn-project/circuit-types/src/keys/key_store.ts @@ -1,4 +1,5 @@ import { + Point, type AztecAddress, type Fr, type GrumpkinPrivateKey, @@ -116,4 +117,15 @@ export interface KeyStore { * @returns A Promise that resolves to the public keys hash. */ getPublicKeysHash(account: AztecAddress): Promise; + + /** + * + */ + addPublicKeysForAccount( + accountAddress: AztecAddress, + masterNullifierPublicKey: Point, + masterIncomingViewingPublicKey: Point, + masterOutgoingViewingPublicKey: Point, + masterTaggingPublicKey: Point, + ): Promise; } 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 index 37f6ac8cea5..6418d9924e1 100644 --- a/yarn-project/end-to-end/src/e2e_key_registry.test.ts +++ b/yarn-project/end-to-end/src/e2e_key_registry.test.ts @@ -1,5 +1,5 @@ import { type AccountWallet, AztecAddress, Fr, type PXE } from '@aztec/aztec.js'; -import { GeneratorIndex } from '@aztec/circuits.js'; +import { CompleteAddress, GeneratorIndex, PartialAddress, Point } from '@aztec/circuits.js'; import { poseidon2Hash } from '@aztec/foundation/crypto'; import { KeyRegistryContract, TestContract } from '@aztec/noir-contracts.js'; @@ -35,102 +35,245 @@ describe('SharedMutablePrivateGetter', () => { afterAll(() => teardown()); - describe('failure cases', () => { - let accountAddedToRegistry: AztecAddress; - - describe('should fail registering with bad input', () => { - const partialAddress = new Fr(69); - - const masterNullifierPublicKey = new Fr(12); - const masterIncomingViewingPublicKey = new Fr(34); - const masterOutgoingViewingPublicKey = new Fr(56); - const masterTaggingPublicKey = new Fr(78); - - // TODO(#5726): use computePublicKeysHash function - const publicKeysHash = poseidon2Hash([ - masterNullifierPublicKey, - masterIncomingViewingPublicKey, - masterOutgoingViewingPublicKey, - masterTaggingPublicKey, - GeneratorIndex.PUBLIC_KEYS_HASH, - ]); - - // We hash the partial address and the public keys hash to get the account address - // TODO(#5726): Move the following line to AztecAddress class? - accountAddedToRegistry = poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1]); - - it('should fail registering with mismatched address', async () => { - const mismatchedAddress = Fr.random(); - - await expect( - keyRegistry - .withWallet(wallets[0]) - .methods.register( - AztecAddress.fromField(mismatchedAddress), - partialAddress, - masterNullifierPublicKey, - masterIncomingViewingPublicKey, - masterOutgoingViewingPublicKey, - masterTaggingPublicKey, - ) - .send() - .wait(), - ).rejects.toThrow('Computed address does not match supplied address'); - }); - - it('should fail registering with mismatched nullifier public key', async () => { - const mismatchedMasterNullifierPublicKey = Fr.random(); - - await expect( - keyRegistry - .withWallet(wallets[0]) - .methods.register( - AztecAddress.fromField(accountAddedToRegistry), - partialAddress, - mismatchedMasterNullifierPublicKey, - masterIncomingViewingPublicKey, - masterOutgoingViewingPublicKey, - masterTaggingPublicKey, - ) - .send() - .wait(), - ).rejects.toThrow('Computed address does not match supplied address'); - }); - }); - - describe('should fail when rotating keys with bad input', () => { - it('should fail when trying to rotate setting a 0 key', async () => { - await expect( - keyRegistry - .withWallet(wallets[0]) - .methods.rotate_nullifier_public_key(wallets[0].getAddress(), new Fr(0)) - .send() - .wait(), - ).rejects.toThrow('New nullifier public key must be non-zero'); - }); - - it('should fail when trying to rotate for another address without authwit', async () => { - await expect( - keyRegistry - .withWallet(wallets[0]) - .methods.rotate_nullifier_public_key(wallets[1].getAddress(), new Fr(2)) - .send() - .wait(), - ).rejects.toThrow('Assertion failed: Message not authorized by account'); - }); - }); - }); + // describe('failure cases', () => { + // let accountAddedToRegistry: AztecAddress; + + // describe('should fail registering with bad input', () => { + // const partialAddress = new Fr(69); + + // const masterNullifierPublicKey = new Fr(12); + // const masterIncomingViewingPublicKey = new Fr(34); + // const masterOutgoingViewingPublicKey = new Fr(56); + // const masterTaggingPublicKey = new Fr(78); + + // // TODO(#5726): use computePublicKeysHash function + // const publicKeysHash = poseidon2Hash([ + // masterNullifierPublicKey, + // masterIncomingViewingPublicKey, + // masterOutgoingViewingPublicKey, + // masterTaggingPublicKey, + // GeneratorIndex.PUBLIC_KEYS_HASH, + // ]); + + // // We hash the partial address and the public keys hash to get the account address + // // TODO(#5726): Move the following line to AztecAddress class? + // accountAddedToRegistry = poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1]); + + // it('should fail registering with mismatched address', async () => { + // const mismatchedAddress = Fr.random(); + + // await expect( + // keyRegistry + // .withWallet(wallets[0]) + // .methods.register( + // AztecAddress.fromField(mismatchedAddress), + // partialAddress, + // masterNullifierPublicKey, + // masterIncomingViewingPublicKey, + // masterOutgoingViewingPublicKey, + // masterTaggingPublicKey, + // ) + // .send() + // .wait(), + // ).rejects.toThrow('Computed address does not match supplied address'); + // }); + + // it('should fail registering with mismatched nullifier public key', async () => { + // const mismatchedMasterNullifierPublicKey = Fr.random(); + + // await expect( + // keyRegistry + // .withWallet(wallets[0]) + // .methods.register( + // AztecAddress.fromField(accountAddedToRegistry), + // partialAddress, + // mismatchedMasterNullifierPublicKey, + // masterIncomingViewingPublicKey, + // masterOutgoingViewingPublicKey, + // masterTaggingPublicKey, + // ) + // .send() + // .wait(), + // ).rejects.toThrow('Computed address does not match supplied address'); + // }); + // }); + + // describe('should fail when rotating keys with bad input', () => { + // it('should fail when trying to rotate setting a 0 key', async () => { + // await expect( + // keyRegistry + // .withWallet(wallets[0]) + // .methods.rotate_nullifier_public_key(wallets[0].getAddress(), new Fr(0)) + // .send() + // .wait(), + // ).rejects.toThrow('New nullifier public key must be non-zero'); + // }); + + // it('should fail when trying to rotate for another address without authwit', async () => { + // await expect( + // keyRegistry + // .withWallet(wallets[0]) + // .methods.rotate_nullifier_public_key(wallets[1].getAddress(), new Fr(2)) + // .send() + // .wait(), + // ).rejects.toThrow('Assertion failed: Message not authorized by account'); + // }); + // }); + // }); + + // describe('key registration flow', () => { + // let accountAddedToRegistry: AztecAddress; + + // it('should generate and register with original keys', async () => { + // const partialAddress = new Fr(69); + + // const masterNullifierPublicKey = new Fr(12); + // const masterIncomingViewingPublicKey = new Fr(34); + // const masterOutgoingViewingPublicKey = new Fr(56); + // const masterTaggingPublicKey = new Fr(78); + + // const publicKeysHash = poseidon2Hash([ + // masterNullifierPublicKey, + // masterIncomingViewingPublicKey, + // masterOutgoingViewingPublicKey, + // masterTaggingPublicKey, + // GeneratorIndex.PUBLIC_KEYS_HASH, + // ]); + + // // We hash the partial address and the public keys hash to get the account address + // // TODO(#5726): Move the following line to AztecAddress class? + // accountAddedToRegistry = poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1]); + + // await keyRegistry + // .withWallet(wallets[0]) + // .methods.register( + // AztecAddress.fromField(accountAddedToRegistry), + // partialAddress, + // masterNullifierPublicKey, + // masterIncomingViewingPublicKey, + // masterOutgoingViewingPublicKey, + // masterTaggingPublicKey, + // ) + // .send() + // .wait(); + // }); + + // it('checks our registry contract from test contract and fails because the address has not been registered yet', async () => { + // const { txHash } = await testContract.methods + // .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, accountAddedToRegistry) + // .send() + // .wait(); + + // const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + // expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(Fr.ZERO); + // }); + + // it('checks our registry contract from test contract and finds the address and associated nullifier public key after a delay', async () => { + // await delay(5); + + // const { txHash } = await testContract.methods + // .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, accountAddedToRegistry) + // .send() + // .wait(); + + // const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + + // expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(12)); + // }); + // }); + + // describe('key rotation flow', () => { + // it('we rotate the nullifier key', async () => { + // // This changes + // const newMasterNullifierPublicKey = new Fr(910); + + // await keyRegistry + // .withWallet(wallets[0]) + // .methods.rotate_nullifier_public_key(wallets[0].getAddress(), newMasterNullifierPublicKey) + // .send() + // .wait(); + // }); + + // it("checks our registry contract from test contract and finds our old public key because the key rotation hasn't been applied yet", async () => { + // const { txHash } = await testContract.methods + // .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) + // .send() + // .wait(); + + // const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + // expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(0)); + // }); + + // it('checks our registry contract from test contract and finds the new nullifier public key that has been rotated', async () => { + // await delay(5); + + // const { txHash } = await testContract.methods + // .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) + // .send() + // .wait(); + + // const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + + // expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(910)); + // }); + // }); + + // describe('key rotation flow with authwit', () => { + // it('wallet 0 lets wallet 1 call rotate_nullifier_public_key on his behalf with a pre-defined new public key', async () => { + // // This changes + // const newMasterNullifierPublicKey = new Fr(420); + + // const action = keyRegistry + // .withWallet(wallets[1]) + // .methods.rotate_nullifier_public_key(wallets[0].getAddress(), newMasterNullifierPublicKey); + + // await wallets[0] + // .setPublicAuthWit({ caller: wallets[1].getCompleteAddress().address, action }, true) + // .send() + // .wait(); + + // await action.send().wait(); + // }); + + // it("checks our registry contract from test contract and finds our old public key because the key rotation hasn't been applied yet", async () => { + // const { txHash } = await testContract.methods + // .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) + // .send() + // .wait(); + + // const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + // expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(910)); + // }); + + // it('checks our registry contract from test contract and finds the new nullifier public key that has been rotated', async () => { + // await delay(5); + + // const { txHash } = await testContract.methods + // .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) + // .send() + // .wait(); + + // const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + + // expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(420)); + // }); + // }); describe('key registration flow', () => { let accountAddedToRegistry: AztecAddress; + let masterNullifierPublicKey: Point; + let masterIncomingViewingPublicKey: Point; + let masterOutgoingViewingPublicKey: Point; + let masterTaggingPublicKey: Point; + let partialAddress: PartialAddress; it('should generate and register with original keys', async () => { - const partialAddress = new Fr(69); + partialAddress = new Fr(69); - const masterNullifierPublicKey = new Fr(12); - const masterIncomingViewingPublicKey = new Fr(34); - const masterOutgoingViewingPublicKey = new Fr(56); - const masterTaggingPublicKey = new Fr(78); + masterNullifierPublicKey = new Point(new Fr(1), new Fr(2)); + masterIncomingViewingPublicKey = new Point(new Fr(3), new Fr(4)); + masterOutgoingViewingPublicKey = new Point(new Fr(5), new Fr(6)); + masterTaggingPublicKey = new Point(new Fr(7), new Fr(8)); const publicKeysHash = poseidon2Hash([ masterNullifierPublicKey, @@ -166,96 +309,34 @@ describe('SharedMutablePrivateGetter', () => { const rawLogs = await pxe.getUnencryptedLogs({ txHash }); expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(Fr.ZERO); - }); - - it('checks our registry contract from test contract and finds the address and associated nullifier public key after a delay', async () => { - await delay(5); - - const { txHash } = await testContract.methods - .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, accountAddedToRegistry) - .send() - .wait(); - - const rawLogs = await pxe.getUnencryptedLogs({ txHash }); - expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(12)); - }); - }); - - describe('key rotation flow', () => { - it('we rotate the nullifier key', async () => { - // This changes - const newMasterNullifierPublicKey = new Fr(910); - - await keyRegistry - .withWallet(wallets[0]) - .methods.rotate_nullifier_public_key(wallets[0].getAddress(), newMasterNullifierPublicKey) - .send() - .wait(); + // Checks freshness of newly added keys, but the change hasn't been affected yet + await expect(testContract.methods.test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey, keyRegistry.address).send().wait()).rejects.toThrow(); }); - it("checks our registry contract from test contract and finds our old public key because the key rotation hasn't been applied yet", async () => { - const { txHash } = await testContract.methods - .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) - .send() - .wait(); - - const rawLogs = await pxe.getUnencryptedLogs({ txHash }); - expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(0)); - }); + it('', async () => { + // FIX THIS + await pxe.registerRecipient(CompleteAddress.create(accountAddedToRegistry, Point.ZERO, partialAddress), [ + masterNullifierPublicKey, + masterIncomingViewingPublicKey, + masterOutgoingViewingPublicKey, + masterTaggingPublicKey]); + await testContract.methods.test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey, keyRegistry.address).send().wait(); + }) - it('checks our registry contract from test contract and finds the new nullifier public key that has been rotated', async () => { + it('checks our registry contract from test contract and finds the address and associated nullifier public key after a delay', async () => { await delay(5); const { txHash } = await testContract.methods - .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) - .send() - .wait(); - - const rawLogs = await pxe.getUnencryptedLogs({ txHash }); - - expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(910)); - }); - }); - - describe('key rotation flow with authwit', () => { - it('wallet 0 lets wallet 1 call rotate_nullifier_public_key on his behalf with a pre-defined new public key', async () => { - // This changes - const newMasterNullifierPublicKey = new Fr(420); - - const action = keyRegistry - .withWallet(wallets[1]) - .methods.rotate_nullifier_public_key(wallets[0].getAddress(), newMasterNullifierPublicKey); - - await wallets[0] - .setPublicAuthWit({ caller: wallets[1].getCompleteAddress().address, action }, true) - .send() - .wait(); - - await action.send().wait(); - }); - - it("checks our registry contract from test contract and finds our old public key because the key rotation hasn't been applied yet", async () => { - const { txHash } = await testContract.methods - .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) + .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, accountAddedToRegistry) .send() .wait(); const rawLogs = await pxe.getUnencryptedLogs({ txHash }); - expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(910)); - }); - it('checks our registry contract from test contract and finds the new nullifier public key that has been rotated', async () => { - await delay(5); - - const { txHash } = await testContract.methods - .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) - .send() - .wait(); - - const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(poseidon2Hash(masterNullifierPublicKey.toFields())); - expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(420)); + await testContract.methods.test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey, keyRegistry.address).send().wait(); }); }); }); diff --git a/yarn-project/key-store/src/test_key_store.ts b/yarn-project/key-store/src/test_key_store.ts index c2755aecf0e..288ffc9430d 100644 --- a/yarn-project/key-store/src/test_key_store.ts +++ b/yarn-project/key-store/src/test_key_store.ts @@ -292,4 +292,17 @@ export class TestKeyStore implements KeyStore { } return Promise.resolve(Fr.fromBuffer(publicKeysHashBuffer)); } + + public async addPublicKeysForAccount( + accountAddress: AztecAddress, + masterNullifierPublicKey: Point, + masterIncomingViewingPublicKey: Point, + masterOutgoingViewingPublicKey: Point, + masterTaggingPublicKey: Point, + ): Promise { + await this.#keys.set(`${accountAddress.toString()}-npk_m`, masterNullifierPublicKey.toBuffer()); + await this.#keys.set(`${accountAddress.toString()}-ivpk_m`, masterIncomingViewingPublicKey.toBuffer()); + await this.#keys.set(`${accountAddress.toString()}-ovpk_m`, masterOutgoingViewingPublicKey.toBuffer()); + await this.#keys.set(`${accountAddress.toString()}-tpk_m`, masterTaggingPublicKey.toBuffer()); + } } diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index 5f90b66be33..3e75a1fe655 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -42,7 +42,7 @@ import { import { computeCommitmentNonce, siloNullifier } from '@aztec/circuits.js/hash'; import { type ContractArtifact, type DecodedReturn, FunctionSelector, encodeArguments } from '@aztec/foundation/abi'; import { arrayNonEmptyLength, padArrayEnd } from '@aztec/foundation/collection'; -import { Fr } from '@aztec/foundation/fields'; +import { Fr, Point } from '@aztec/foundation/fields'; import { SerialQueue } from '@aztec/foundation/fifo'; import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { Timer } from '@aztec/foundation/timer'; @@ -216,8 +216,13 @@ export class PXEService implements PXE { return this.keyStore.getPublicKeysHash(address); } - public async registerRecipient(recipient: CompleteAddress): Promise { + public async registerRecipient(recipient: CompleteAddress, publicKeys: Point[] = []): Promise { const wasAdded = await this.db.addCompleteAddress(recipient); + + if (publicKeys.length !== 0) { + await this.keyStore.addPublicKeysForAccount(recipient.address, publicKeys[0], publicKeys[1], publicKeys[2], publicKeys[3]); + } + if (wasAdded) { this.log.info(`Added recipient:\n ${recipient.toReadableString()}`); } else { diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index 02f820666fd..26a4a677c59 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -1,5 +1,5 @@ import { MerkleTreeId, UnencryptedL2Log } from '@aztec/circuit-types'; -import { acvmFieldMessageToString, oracleDebugCallToFormattedStr } from '@aztec/circuits.js'; +import { type PartialAddress, acvmFieldMessageToString, oracleDebugCallToFormattedStr } from '@aztec/circuits.js'; import { EventSelector, FunctionSelector } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr, Point } from '@aztec/foundation/fields'; @@ -174,12 +174,26 @@ export class Oracle { } async getPublicKeysAndPartialAddress([address]: ACVMField[]): Promise { - const { partialAddress } = await this.typedOracle.getCompleteAddress( - AztecAddress.fromField(fromACVMField(address)), - ); + let partialAddress: PartialAddress; + let publicKeys: Point[] | undefined; + try { + ({ partialAddress } = await this.typedOracle.getCompleteAddress( + AztecAddress.fromField(fromACVMField(address)), + )); + } catch (err) { + partialAddress = Fr.ZERO; + } + + try { + publicKeys = await this.typedOracle.getPublicKeysForAddress(AztecAddress.fromField(fromACVMField(address))); + } catch(err) { + publicKeys = Array(4).fill(Point.ZERO); + } + + console.log('partial address', partialAddress); + console.log('public keys', publicKeys); - const publicKeys = await this.typedOracle.getPublicKeysForAddress(AztecAddress.fromField(fromACVMField(address))); - const acvmKeys = publicKeys?.flatMap(key => key.toFields()) ?? Array(8).fill(toACVMField(0)); + const acvmKeys = publicKeys.flatMap(key => key.toFields()); return [partialAddress, ...acvmKeys].map(toACVMField); } diff --git a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts index 86b3d5d6439..103214d3c98 100644 --- a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts @@ -142,16 +142,10 @@ export abstract class TypedOracle { getPublicKeysForAddress( _address: AztecAddress, - ): Promise { + ): Promise { throw new OracleMethodNotAvailableError('getPublicKeysForAddress'); } - async getAddressMetadata( - _address: AztecAddress, - ): Promise { - throw new OracleMethodNotAvailableError('getAddressMetadata'); - } - getNotes( _storageSlot: Fr, _numSelects: number, diff --git a/yarn-project/simulator/src/client/db_oracle.ts b/yarn-project/simulator/src/client/db_oracle.ts index b8d56098703..3e193b56472 100644 --- a/yarn-project/simulator/src/client/db_oracle.ts +++ b/yarn-project/simulator/src/client/db_oracle.ts @@ -67,8 +67,6 @@ export interface DBOracle extends CommitmentsDB { getPublicKeysForAddress(address: AztecAddress): Promise; - getAddressMetadata(address: AztecAddress): Promise; - /** * Retrieve nullifier keys associated with a specific account and app/contract address. * From 1b13804151dc797e3b376900dc40eeb56b243907 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 26 Apr 2024 15:22:54 +0000 Subject: [PATCH 06/93] cleanup --- .../src/keys/assert_public_key_freshness.nr | 55 +- .../key_registry_contract/src/main.nr | 8 +- .../contracts/test_contract/src/main.nr | 3 +- .../end-to-end/src/e2e_key_registry.test.ts | 549 ++++++++++-------- 4 files changed, 339 insertions(+), 276 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr b/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr index 5390a2b7848..d1961792feb 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr @@ -1,68 +1,65 @@ use dep::protocol_types::{ + address::{ + AztecAddress, + PartialAddress + }, constants::{ - GENERATOR_INDEX__PUBLIC_KEYS_HASH, GENERATOR_INDEX__CONTRACT_ADDRESS_V1}, - address::{AztecAddress, PartialAddress}, grumpkin_point::GrumpkinPoint}; + GENERATOR_INDEX__PUBLIC_KEYS_HASH, + GENERATOR_INDEX__CONTRACT_ADDRESS_V1, + CANONICAL_KEY_REGISTRY_ADDRESS + }, + grumpkin_point::GrumpkinPoint, +}; + use crate::context::PrivateContext; -use crate::note::{ - constants::{GET_NOTE_ORACLE_RETURN_LENGTH, MAX_NOTES_PER_PAGE, VIEW_NOTE_ORACLE_RETURN_LENGTH}, - note_getter_options::{NoteGetterOptions, Select, Sort, SortOrder, Comparator, NoteStatus, PropertySelector}, - note_interface::NoteInterface, note_viewer_options::NoteViewerOptions, - utils::compute_note_hash_for_consumption, +use crate::hash::{ + pedersen_hash, + poseidon2_hash, }; -use crate::state_vars::shared_mutable::shared_mutable_private_getter::SharedMutablePrivateGetter; -use crate::hash::{pedersen_hash, poseidon2_hash}; use crate::oracle; +use crate::state_vars::shared_mutable::shared_mutable_private_getter::SharedMutablePrivateGetter; struct PublicKeyTypeEnum { NULLIFIER: u8, - INCOMING: u8, } global PublicKeyType = PublicKeyTypeEnum { NULLIFIER: 0, - INCOMING: 1, }; pub fn assert_nullifier_public_key_fresh( context: &mut PrivateContext, address: AztecAddress, nullifier_public_key_to_test: GrumpkinPoint, - // remove after - registry_contract_address: AztecAddress, ) { - // Canonical Key Registry - let contract_address_to_read = registry_contract_address; + // This is the storage slot of the nullifier_public_key inside the key registry contract let storage_slot_of_nullifier_public_key = 1; // We have to derive this slot to get the location of the shared mutable inside the Map + // This should mimic how maps derive their slots let derived_slot = pedersen_hash( [storage_slot_of_nullifier_public_key, address.to_field()], 0 ); // It's a bit wonky because we need to know the delay for get_current_value_in_private to work correctly - let registry_private_getter: SharedMutablePrivateGetter = SharedMutablePrivateGetter::new(*context, contract_address_to_read, derived_slot); + // We read from the canonical Key Registry + let registry_private_getter: SharedMutablePrivateGetter = SharedMutablePrivateGetter::new(*context, AztecAddress::from_field(CANONICAL_KEY_REGISTRY_ADDRESS), derived_slot); let hashed_nullifier_public_key = registry_private_getter.get_current_value_in_private(); + // In the case that the value is not found in the registry we need to manually pass in the address preimage if (hashed_nullifier_public_key == 0) { - check_key(address, PublicKeyType.NULLIFIER, nullifier_public_key_to_test); + check_public_key_validity(address, PublicKeyType.NULLIFIER, nullifier_public_key_to_test); } else { assert(hashed_nullifier_public_key == poseidon2_hash(nullifier_public_key_to_test.serialize())); } } -fn check_key(address: AztecAddress, key_type: u8, key: GrumpkinPoint) { - let mut (partial_address, keys) = check_key_internal(address); - - crate::oracle::debug_log::debug_log_array_with_prefix("partial", [partial_address]); - crate::oracle::debug_log::debug_log_array_with_prefix("ACTUAL NULLIFIER", key.serialize()); - crate::oracle::debug_log::debug_log_array_with_prefix("nullifier", keys[0].serialize()); - crate::oracle::debug_log::debug_log_array_with_prefix("incoming", keys[1].serialize()); - crate::oracle::debug_log::debug_log_array_with_prefix("outgoing", keys[2].serialize()); - crate::oracle::debug_log::debug_log_array_with_prefix("tagging", keys[3].serialize()); +fn check_public_key_validity(address: AztecAddress, key_type: u8, key: GrumpkinPoint) { + let (partial_address, keys) = get_public_keys_and_partial_address_internal(address); assert(keys[key_type].eq(key)); - _check_key_constrain_check_key_internal( + _check_public_key_validity_constrain_internal( address, partial_address, keys[0], @@ -72,13 +69,13 @@ fn check_key(address: AztecAddress, key_type: u8, key: GrumpkinPoint) { ) } -unconstrained fn check_key_internal(address: AztecAddress) -> (PartialAddress, [GrumpkinPoint; 4]) { +unconstrained fn get_public_keys_and_partial_address_internal(address: AztecAddress) -> (PartialAddress, [GrumpkinPoint; 4]) { let (partial_address, public_keys) = oracle::keys::get_public_keys_and_partial_address(address); (partial_address, public_keys) } -fn _check_key_constrain_check_key_internal( +fn _check_public_key_validity_constrain_internal( address: AztecAddress, partial_address: PartialAddress, nullifier_public_key: GrumpkinPoint, 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 index ea5b1dd551a..6124253c417 100644 --- a/noir-projects/noir-contracts/contracts/key_registry_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/key_registry_contract/src/main.nr @@ -34,12 +34,12 @@ contract KeyRegistry { } #[aztec(public)] - fn rotate_nullifier_public_key_hash( + fn rotate_nullifier_public_key( address: AztecAddress, - new_nullifier_public_key_hash: Field, + new_nullifier_public_key: GrumpkinPoint, ) { assert( - new_nullifier_public_key_hash != 0, + !new_nullifier_public_key.is_zero(), "New nullifier public key must be non-zero" ); @@ -49,7 +49,7 @@ contract KeyRegistry { let nullifier_key_registry = storage.nullifier_public_key_hash_registry.at(address); - nullifier_key_registry.schedule_value_change(new_nullifier_public_key_hash); + nullifier_key_registry.schedule_value_change(poseidon2_hash(new_nullifier_public_key.serialize())); } #[aztec(public)] 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 d5f5142fd03..68311b75f4f 100644 --- a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr @@ -414,9 +414,8 @@ contract Test { fn test_nullifier_key_freshness( address: AztecAddress, public_nullifying_key: GrumpkinPoint, - key_registry_contract: AztecAddress, ) { - assert_nullifier_public_key_fresh(&mut context, address, public_nullifying_key, key_registry_contract); + assert_nullifier_public_key_fresh(&mut context, address, public_nullifying_key); } #[aztec(public)] 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 index 967d9c1ee4a..a16f3e56ad9 100644 --- a/yarn-project/end-to-end/src/e2e_key_registry.test.ts +++ b/yarn-project/end-to-end/src/e2e_key_registry.test.ts @@ -10,11 +10,11 @@ import { publicDeployAccounts, setup } from './fixtures/utils.js'; const TIMEOUT = 100_000; -describe('SharedMutablePrivateGetter', () => { +describe('Key Registry', () => { let keyRegistry: KeyRegistryContract; + let pxe: PXE; let testContract: TestContract; - let pxe: PXE; jest.setTimeout(TIMEOUT); let wallets: AccountWallet[]; @@ -38,245 +38,102 @@ describe('SharedMutablePrivateGetter', () => { afterAll(() => teardown()); - // describe('failure cases', () => { - // let accountAddedToRegistry: AztecAddress; - - // describe('should fail registering with bad input', () => { - // const partialAddress = new Fr(69); - - // const masterNullifierPublicKey = new Fr(12); - // const masterIncomingViewingPublicKey = new Fr(34); - // const masterOutgoingViewingPublicKey = new Fr(56); - // const masterTaggingPublicKey = new Fr(78); - - // // TODO(#5726): use computePublicKeysHash function - // const publicKeysHash = poseidon2Hash([ - // masterNullifierPublicKey, - // masterIncomingViewingPublicKey, - // masterOutgoingViewingPublicKey, - // masterTaggingPublicKey, - // GeneratorIndex.PUBLIC_KEYS_HASH, - // ]); - - // // We hash the partial address and the public keys hash to get the account address - // // TODO(#5726): Move the following line to AztecAddress class? - // accountAddedToRegistry = poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1]); - - // it('should fail registering with mismatched address', async () => { - // const mismatchedAddress = Fr.random(); - - // await expect( - // keyRegistry - // .withWallet(wallets[0]) - // .methods.register( - // AztecAddress.fromField(mismatchedAddress), - // partialAddress, - // masterNullifierPublicKey, - // masterIncomingViewingPublicKey, - // masterOutgoingViewingPublicKey, - // masterTaggingPublicKey, - // ) - // .send() - // .wait(), - // ).rejects.toThrow('Computed address does not match supplied address'); - // }); - - // it('should fail registering with mismatched nullifier public key', async () => { - // const mismatchedMasterNullifierPublicKey = Fr.random(); - - // await expect( - // keyRegistry - // .withWallet(wallets[0]) - // .methods.register( - // AztecAddress.fromField(accountAddedToRegistry), - // partialAddress, - // mismatchedMasterNullifierPublicKey, - // masterIncomingViewingPublicKey, - // masterOutgoingViewingPublicKey, - // masterTaggingPublicKey, - // ) - // .send() - // .wait(), - // ).rejects.toThrow('Computed address does not match supplied address'); - // }); - // }); - - // describe('should fail when rotating keys with bad input', () => { - // it('should fail when trying to rotate setting a 0 key', async () => { - // await expect( - // keyRegistry - // .withWallet(wallets[0]) - // .methods.rotate_nullifier_public_key(wallets[0].getAddress(), new Fr(0)) - // .send() - // .wait(), - // ).rejects.toThrow('New nullifier public key must be non-zero'); - // }); - - // it('should fail when trying to rotate for another address without authwit', async () => { - // await expect( - // keyRegistry - // .withWallet(wallets[0]) - // .methods.rotate_nullifier_public_key(wallets[1].getAddress(), new Fr(2)) - // .send() - // .wait(), - // ).rejects.toThrow('Assertion failed: Message not authorized by account'); - // }); - // }); - // }); - - // describe('key registration flow', () => { - // let accountAddedToRegistry: AztecAddress; - - // it('should generate and register with original keys', async () => { - // const partialAddress = new Fr(69); - - // const masterNullifierPublicKey = new Fr(12); - // const masterIncomingViewingPublicKey = new Fr(34); - // const masterOutgoingViewingPublicKey = new Fr(56); - // const masterTaggingPublicKey = new Fr(78); - - // const publicKeysHash = poseidon2Hash([ - // masterNullifierPublicKey, - // masterIncomingViewingPublicKey, - // masterOutgoingViewingPublicKey, - // masterTaggingPublicKey, - // GeneratorIndex.PUBLIC_KEYS_HASH, - // ]); - - // // We hash the partial address and the public keys hash to get the account address - // // TODO(#5726): Move the following line to AztecAddress class? - // accountAddedToRegistry = poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1]); - - // await keyRegistry - // .withWallet(wallets[0]) - // .methods.register( - // AztecAddress.fromField(accountAddedToRegistry), - // partialAddress, - // masterNullifierPublicKey, - // masterIncomingViewingPublicKey, - // masterOutgoingViewingPublicKey, - // masterTaggingPublicKey, - // ) - // .send() - // .wait(); - // }); - - // it('checks our registry contract from test contract and fails because the address has not been registered yet', async () => { - // const { txHash } = await testContract.methods - // .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, accountAddedToRegistry) - // .send() - // .wait(); - - // const rawLogs = await pxe.getUnencryptedLogs({ txHash }); - // expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(Fr.ZERO); - // }); - - // it('checks our registry contract from test contract and finds the address and associated nullifier public key after a delay', async () => { - // await delay(5); - - // const { txHash } = await testContract.methods - // .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, accountAddedToRegistry) - // .send() - // .wait(); - - // const rawLogs = await pxe.getUnencryptedLogs({ txHash }); - - // expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(12)); - // }); - // }); - - // describe('key rotation flow', () => { - // it('we rotate the nullifier key', async () => { - // // This changes - // const newMasterNullifierPublicKey = new Fr(910); - - // await keyRegistry - // .withWallet(wallets[0]) - // .methods.rotate_nullifier_public_key(wallets[0].getAddress(), newMasterNullifierPublicKey) - // .send() - // .wait(); - // }); - - // it("checks our registry contract from test contract and finds our old public key because the key rotation hasn't been applied yet", async () => { - // const { txHash } = await testContract.methods - // .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) - // .send() - // .wait(); - - // const rawLogs = await pxe.getUnencryptedLogs({ txHash }); - // expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(0)); - // }); - - // it('checks our registry contract from test contract and finds the new nullifier public key that has been rotated', async () => { - // await delay(5); - - // const { txHash } = await testContract.methods - // .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) - // .send() - // .wait(); - - // const rawLogs = await pxe.getUnencryptedLogs({ txHash }); - - // expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(910)); - // }); - // }); - - // describe('key rotation flow with authwit', () => { - // it('wallet 0 lets wallet 1 call rotate_nullifier_public_key on his behalf with a pre-defined new public key', async () => { - // // This changes - // const newMasterNullifierPublicKey = new Fr(420); - - // const action = keyRegistry - // .withWallet(wallets[1]) - // .methods.rotate_nullifier_public_key(wallets[0].getAddress(), newMasterNullifierPublicKey); - - // await wallets[0] - // .setPublicAuthWit({ caller: wallets[1].getCompleteAddress().address, action }, true) - // .send() - // .wait(); - - // await action.send().wait(); - // }); - - // it("checks our registry contract from test contract and finds our old public key because the key rotation hasn't been applied yet", async () => { - // const { txHash } = await testContract.methods - // .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) - // .send() - // .wait(); - - // const rawLogs = await pxe.getUnencryptedLogs({ txHash }); - // expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(910)); - // }); - - // it('checks our registry contract from test contract and finds the new nullifier public key that has been rotated', async () => { - // await delay(5); - - // const { txHash } = await testContract.methods - // .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) - // .send() - // .wait(); - - // const rawLogs = await pxe.getUnencryptedLogs({ txHash }); - - // expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(420)); - // }); - // }); + describe('failure cases', () => { + let accountAddedToRegistry: AztecAddress; + + describe('should fail registering with bad input', () => { + const partialAddress = new Fr(69); + + const masterNullifierPublicKey = new Fr(12); + const masterIncomingViewingPublicKey = new Fr(34); + const masterOutgoingViewingPublicKey = new Fr(56); + const masterTaggingPublicKey = new Fr(78); + + // TODO(#5726): use computePublicKeysHash function + const publicKeysHash = poseidon2Hash([ + masterNullifierPublicKey, + masterIncomingViewingPublicKey, + masterOutgoingViewingPublicKey, + masterTaggingPublicKey, + GeneratorIndex.PUBLIC_KEYS_HASH, + ]); + + // We hash the partial address and the public keys hash to get the account address + // TODO(#5726): Move the following line to AztecAddress class? + accountAddedToRegistry = poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1]); + + it('should fail registering with mismatched address', async () => { + const mismatchedAddress = Fr.random(); + + await expect( + keyRegistry + .withWallet(wallets[0]) + .methods.register( + AztecAddress.fromField(mismatchedAddress), + partialAddress, + masterNullifierPublicKey, + masterIncomingViewingPublicKey, + masterOutgoingViewingPublicKey, + masterTaggingPublicKey, + ) + .send() + .wait(), + ).rejects.toThrow('Computed address does not match supplied address'); + }); + + it('should fail registering with mismatched nullifier public key', async () => { + const mismatchedMasterNullifierPublicKey = Fr.random(); + + await expect( + keyRegistry + .withWallet(wallets[0]) + .methods.register( + AztecAddress.fromField(accountAddedToRegistry), + partialAddress, + mismatchedMasterNullifierPublicKey, + masterIncomingViewingPublicKey, + masterOutgoingViewingPublicKey, + masterTaggingPublicKey, + ) + .send() + .wait(), + ).rejects.toThrow('Computed address does not match supplied address'); + }); + }); + + describe('should fail when rotating keys with bad input', () => { + it('should fail when trying to rotate setting a 0 key', async () => { + await expect( + keyRegistry + .withWallet(wallets[0]) + .methods.rotate_nullifier_public_key(wallets[0].getAddress(), new Fr(0)) + .send() + .wait(), + ).rejects.toThrow('New nullifier public key must be non-zero'); + }); + + it('should fail when trying to rotate for another address without authwit', async () => { + await expect( + keyRegistry + .withWallet(wallets[0]) + .methods.rotate_nullifier_public_key(wallets[1].getAddress(), new Fr(2)) + .send() + .wait(), + ).rejects.toThrow('Assertion failed: Message not authorized by account'); + }); + }); + }); describe('key registration flow', () => { let accountAddedToRegistry: AztecAddress; - let masterNullifierPublicKey: Point; - let masterIncomingViewingPublicKey: Point; - let masterOutgoingViewingPublicKey: Point; - let masterTaggingPublicKey: Point; - let partialAddress: PartialAddress; it('should generate and register with original keys', async () => { - partialAddress = new Fr(69); + const partialAddress = new Fr(69); - masterNullifierPublicKey = new Point(new Fr(1), new Fr(2)); - masterIncomingViewingPublicKey = new Point(new Fr(3), new Fr(4)); - masterOutgoingViewingPublicKey = new Point(new Fr(5), new Fr(6)); - masterTaggingPublicKey = new Point(new Fr(7), new Fr(8)); + const masterNullifierPublicKey = new Fr(12); + const masterIncomingViewingPublicKey = new Fr(34); + const masterOutgoingViewingPublicKey = new Fr(56); + const masterTaggingPublicKey = new Fr(78); const publicKeysHash = poseidon2Hash([ masterNullifierPublicKey, @@ -312,22 +169,210 @@ describe('SharedMutablePrivateGetter', () => { const rawLogs = await pxe.getUnencryptedLogs({ txHash }); expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(Fr.ZERO); + }); + + it('checks our registry contract from test contract and finds the address and associated nullifier public key after a delay', async () => { + await delay(5); + + const { txHash } = await testContract.methods + .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, accountAddedToRegistry) + .send() + .wait(); + + const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + + expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(12)); + }); + }); + + describe('key rotation flow', () => { + it('we rotate the nullifier key', async () => { + // This changes + const newMasterNullifierPublicKey = new Fr(910); + + await keyRegistry + .withWallet(wallets[0]) + .methods.rotate_nullifier_public_key(wallets[0].getAddress(), newMasterNullifierPublicKey) + .send() + .wait(); + }); + + it("checks our registry contract from test contract and finds our old public key because the key rotation hasn't been applied yet", async () => { + const { txHash } = await testContract.methods + .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) + .send() + .wait(); + + const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(0)); + }); + + it('checks our registry contract from test contract and finds the new nullifier public key that has been rotated', async () => { + await delay(5); + + const { txHash } = await testContract.methods + .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) + .send() + .wait(); + + const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + + expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(910)); + }); + }); + + describe('key rotation flow with authwit', () => { + it('wallet 0 lets wallet 1 call rotate_nullifier_public_key on his behalf with a pre-defined new public key', async () => { + // This changes + const newMasterNullifierPublicKey = new Fr(420); + + const action = keyRegistry + .withWallet(wallets[1]) + .methods.rotate_nullifier_public_key(wallets[0].getAddress(), newMasterNullifierPublicKey); + + await wallets[0] + .setPublicAuthWit({ caller: wallets[1].getCompleteAddress().address, action }, true) + .send() + .wait(); + + await action.send().wait(); + }); + + it("checks our registry contract from test contract and finds our old public key because the key rotation hasn't been applied yet", async () => { + const { txHash } = await testContract.methods + .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) + .send() + .wait(); + + const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(910)); + }); - // Checks freshness of newly added keys, but the change hasn't been affected yet - await expect(testContract.methods.test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey, keyRegistry.address).send().wait()).rejects.toThrow(); + it('checks our registry contract from test contract and finds the new nullifier public key that has been rotated', async () => { + await delay(5); + + const { txHash } = await testContract.methods + .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) + .send() + .wait(); + + const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + + expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(420)); }); + }); - it('', async () => { + describe('key registration flow no PXE', () => { + const masterNullifierPublicKey: Point = new Point(new Fr(9), new Fr(10)); + const masterIncomingViewingPublicKey: Point = new Point(new Fr(11), new Fr(12)); + const masterOutgoingViewingPublicKey: Point = new Point(new Fr(13), new Fr(14)); + const masterTaggingPublicKey: Point = new Point(new Fr(15), new Fr(16)); + const partialAddress: PartialAddress = new Fr(420); + + const publicKeysHash = poseidon2Hash([ + masterNullifierPublicKey, + masterIncomingViewingPublicKey, + masterOutgoingViewingPublicKey, + masterTaggingPublicKey, + GeneratorIndex.PUBLIC_KEYS_HASH, + ]); + + // We hash the partial address and the public keys hash to get the account address + // TODO(#5726): Move the following line to AztecAddress class? + const accountAddedToRegistry = poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1]); + + it('should fail as we have not registered anything to the registry nor have we registered a recipient', async () => { + await expect(testContract.methods.test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey).send().wait()).rejects.toThrow(); + }); + + it('Now we add it to registry', async () => { + await keyRegistry + .withWallet(wallets[0]) + .methods.register( + AztecAddress.fromField(accountAddedToRegistry), + partialAddress, + masterNullifierPublicKey, + masterIncomingViewingPublicKey, + masterOutgoingViewingPublicKey, + masterTaggingPublicKey, + ) + .send() + .wait(); + }); + + it('checks key freshness and fails because the address change has not been applied yet due to lack of delay', async () => { + await expect(testContract.methods.test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey).send().wait()).rejects.toThrow(); + }); + + it('checks key freshness after a delay, and is successful', async () => { + await delay(5); + + await testContract.methods.test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey).send().wait(); + }); + }); + + describe('key registration flow via PXE', () => { + const masterNullifierPublicKey: Point = new Point(new Fr(1), new Fr(2)); + const masterIncomingViewingPublicKey: Point = new Point(new Fr(3), new Fr(4)); + const masterOutgoingViewingPublicKey: Point = new Point(new Fr(5), new Fr(6)); + const masterTaggingPublicKey: Point = new Point(new Fr(7), new Fr(8)); + const partialAddress: PartialAddress = new Fr(69);; + + const publicKeysHash = poseidon2Hash([ + masterNullifierPublicKey, + masterIncomingViewingPublicKey, + masterOutgoingViewingPublicKey, + masterTaggingPublicKey, + GeneratorIndex.PUBLIC_KEYS_HASH, + ]); + + // We hash the partial address and the public keys hash to get the account address + // TODO(#5726): Move the following line to AztecAddress class? + const accountAddedToRegistry = poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1]); + + it('should fail as we have not registered anything to the registry nor have we registered a recipient', async () => { + await expect(testContract.methods.test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey).send().wait()).rejects.toThrow(); + }) + + it('should succeed because we register our recipient manually and the lib checks our pxe', async () => { // FIX THIS await pxe.registerRecipient(CompleteAddress.create(accountAddedToRegistry, Point.ZERO, partialAddress), [ masterNullifierPublicKey, masterIncomingViewingPublicKey, masterOutgoingViewingPublicKey, masterTaggingPublicKey]); - await testContract.methods.test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey, keyRegistry.address).send().wait(); + await testContract.methods.test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey).send().wait(); }) - it('checks our registry contract from test contract and finds the address and associated nullifier public key after a delay', async () => { + it('Now we add it to registry', async () => { + await keyRegistry + .withWallet(wallets[0]) + .methods.register( + AztecAddress.fromField(accountAddedToRegistry), + partialAddress, + masterNullifierPublicKey, + masterIncomingViewingPublicKey, + masterOutgoingViewingPublicKey, + masterTaggingPublicKey, + ) + .send() + .wait(); + }) + + it('we start the change in the registry, it has not been applied yet, but we still see we have a fresh key due to it being added in the pxe', async () => { + const { txHash } = await testContract.methods + .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, accountAddedToRegistry) + .send() + .wait(); + + const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(Fr.ZERO); + + // Checks freshness of newly added keys, but the change hasn't been affected yet, but we have manually added it to our pxe so it should pass + await testContract.methods.test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey).send().wait(); + }); + + it('in the case where the key exists both in the pxe and our registry, we know it works', async () => { await delay(5); const { txHash } = await testContract.methods @@ -339,7 +384,29 @@ describe('SharedMutablePrivateGetter', () => { expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(poseidon2Hash(masterNullifierPublicKey.toFields())); - await testContract.methods.test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey, keyRegistry.address).send().wait(); + await testContract.methods.test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey).send().wait(); + }); + }); + + describe('key rotation flow; assert keys are fresh', () => { + const newMasterNullifierPublicKey = new Point(new Fr(910), new Fr(1112)); + + it('we rotate the nullifier key', async () => { + await keyRegistry + .withWallet(wallets[0]) + .methods.rotate_nullifier_public_key(wallets[0].getAddress(), newMasterNullifierPublicKey) + .send() + .wait(); + }); + + it("checks our registry contract from test contract and fails because the change hasn't been applied yet", async () => { + await expect(testContract.methods.test_nullifier_key_freshness(wallets[0].getAddress(), newMasterNullifierPublicKey).send().wait()).rejects.toThrow(); + }); + + it('checks our registry contract from test contract and succeeds because the change has been applied', async () => { + await delay(5); + + await testContract.methods.test_nullifier_key_freshness(wallets[0].getAddress(), newMasterNullifierPublicKey).send().wait(); }); }); }); From 211a060db0040faad1e34c0219a816021f4bd5db Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 26 Apr 2024 15:26:02 +0000 Subject: [PATCH 07/93] yarn format --- .../circuit-types/src/interfaces/pxe.ts | 2 +- .../circuit-types/src/keys/key_store.ts | 4 +- .../end-to-end/jest.integration.config.json | 2 +- .../end-to-end/src/e2e_key_registry.test.ts | 68 ++++++++++++++----- yarn-project/package.common.json | 2 +- .../pxe/src/pxe_service/pxe_service.ts | 12 +++- .../pxe/src/simulator_oracle/index.ts | 7 +- .../simulator/src/acvm/oracle/oracle.ts | 9 +-- .../simulator/src/acvm/oracle/typed_oracle.ts | 6 +- .../simulator/src/client/db_oracle.ts | 3 +- .../simulator/src/client/view_data_oracle.ts | 4 +- 11 files changed, 75 insertions(+), 44 deletions(-) diff --git a/yarn-project/circuit-types/src/interfaces/pxe.ts b/yarn-project/circuit-types/src/interfaces/pxe.ts index 0fc42af9308..f36958df987 100644 --- a/yarn-project/circuit-types/src/interfaces/pxe.ts +++ b/yarn-project/circuit-types/src/interfaces/pxe.ts @@ -1,4 +1,4 @@ -import { Point, type AztecAddress, type CompleteAddress, type Fr, type PartialAddress } from '@aztec/circuits.js'; +import { type AztecAddress, type CompleteAddress, type Fr, type PartialAddress, type Point } from '@aztec/circuits.js'; import { type ContractArtifact } from '@aztec/foundation/abi'; import { type ContractClassWithId, type ContractInstanceWithAddress } from '@aztec/types/contracts'; import { type NodeInfo } from '@aztec/types/interfaces'; diff --git a/yarn-project/circuit-types/src/keys/key_store.ts b/yarn-project/circuit-types/src/keys/key_store.ts index f670683d905..e5cefbd7bc4 100644 --- a/yarn-project/circuit-types/src/keys/key_store.ts +++ b/yarn-project/circuit-types/src/keys/key_store.ts @@ -1,9 +1,9 @@ import { - Point, type AztecAddress, type Fr, type GrumpkinPrivateKey, type PartialAddress, + type Point, type PublicKey, } from '@aztec/circuits.js'; @@ -119,7 +119,7 @@ export interface KeyStore { getPublicKeysHash(account: AztecAddress): Promise; /** - * + * */ addPublicKeysForAccount( accountAddress: AztecAddress, diff --git a/yarn-project/end-to-end/jest.integration.config.json b/yarn-project/end-to-end/jest.integration.config.json index 84d61df320c..721267ff552 100644 --- a/yarn-project/end-to-end/jest.integration.config.json +++ b/yarn-project/end-to-end/jest.integration.config.json @@ -6,7 +6,7 @@ "moduleNameMapper": { "^(\\.{1,2}/.*)\\.js$": "$1" }, - "reporters": [["default", {"summaryThreshold": 9999}]], + "reporters": [["default", { "summaryThreshold": 9999 }]], "testRegex": "./src/.*\\.test\\.ts$", "rootDir": "./src" } 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 index a16f3e56ad9..2b686e27288 100644 --- a/yarn-project/end-to-end/src/e2e_key_registry.test.ts +++ b/yarn-project/end-to-end/src/e2e_key_registry.test.ts @@ -1,5 +1,5 @@ import { type AccountWallet, AztecAddress, Fr, type PXE } from '@aztec/aztec.js'; -import { CompleteAddress, GeneratorIndex, PartialAddress, Point } from '@aztec/circuits.js'; +import { CompleteAddress, GeneratorIndex, type PartialAddress, Point } from '@aztec/circuits.js'; import { poseidon2Hash } from '@aztec/foundation/crypto'; import { KeyRegistryContract, TestContract } from '@aztec/noir-contracts.js'; import { getCanonicalKeyRegistryAddress } from '@aztec/protocol-contracts/key-registry'; @@ -13,7 +13,7 @@ const TIMEOUT = 100_000; describe('Key Registry', () => { let keyRegistry: KeyRegistryContract; - let pxe: PXE; + let pxe: PXE; let testContract: TestContract; jest.setTimeout(TIMEOUT); @@ -282,7 +282,12 @@ describe('Key Registry', () => { const accountAddedToRegistry = poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1]); it('should fail as we have not registered anything to the registry nor have we registered a recipient', async () => { - await expect(testContract.methods.test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey).send().wait()).rejects.toThrow(); + await expect( + testContract.methods + .test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey) + .send() + .wait(), + ).rejects.toThrow(); }); it('Now we add it to registry', async () => { @@ -301,13 +306,21 @@ describe('Key Registry', () => { }); it('checks key freshness and fails because the address change has not been applied yet due to lack of delay', async () => { - await expect(testContract.methods.test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey).send().wait()).rejects.toThrow(); + await expect( + testContract.methods + .test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey) + .send() + .wait(), + ).rejects.toThrow(); }); it('checks key freshness after a delay, and is successful', async () => { await delay(5); - await testContract.methods.test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey).send().wait(); + await testContract.methods + .test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey) + .send() + .wait(); }); }); @@ -316,7 +329,7 @@ describe('Key Registry', () => { const masterIncomingViewingPublicKey: Point = new Point(new Fr(3), new Fr(4)); const masterOutgoingViewingPublicKey: Point = new Point(new Fr(5), new Fr(6)); const masterTaggingPublicKey: Point = new Point(new Fr(7), new Fr(8)); - const partialAddress: PartialAddress = new Fr(69);; + const partialAddress: PartialAddress = new Fr(69); const publicKeysHash = poseidon2Hash([ masterNullifierPublicKey, @@ -331,8 +344,13 @@ describe('Key Registry', () => { const accountAddedToRegistry = poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1]); it('should fail as we have not registered anything to the registry nor have we registered a recipient', async () => { - await expect(testContract.methods.test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey).send().wait()).rejects.toThrow(); - }) + await expect( + testContract.methods + .test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey) + .send() + .wait(), + ).rejects.toThrow(); + }); it('should succeed because we register our recipient manually and the lib checks our pxe', async () => { // FIX THIS @@ -340,9 +358,13 @@ describe('Key Registry', () => { masterNullifierPublicKey, masterIncomingViewingPublicKey, masterOutgoingViewingPublicKey, - masterTaggingPublicKey]); - await testContract.methods.test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey).send().wait(); - }) + masterTaggingPublicKey, + ]); + await testContract.methods + .test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey) + .send() + .wait(); + }); it('Now we add it to registry', async () => { await keyRegistry @@ -357,7 +379,7 @@ describe('Key Registry', () => { ) .send() .wait(); - }) + }); it('we start the change in the registry, it has not been applied yet, but we still see we have a fresh key due to it being added in the pxe', async () => { const { txHash } = await testContract.methods @@ -369,7 +391,10 @@ describe('Key Registry', () => { expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(Fr.ZERO); // Checks freshness of newly added keys, but the change hasn't been affected yet, but we have manually added it to our pxe so it should pass - await testContract.methods.test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey).send().wait(); + await testContract.methods + .test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey) + .send() + .wait(); }); it('in the case where the key exists both in the pxe and our registry, we know it works', async () => { @@ -384,7 +409,10 @@ describe('Key Registry', () => { expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(poseidon2Hash(masterNullifierPublicKey.toFields())); - await testContract.methods.test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey).send().wait(); + await testContract.methods + .test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey) + .send() + .wait(); }); }); @@ -400,13 +428,21 @@ describe('Key Registry', () => { }); it("checks our registry contract from test contract and fails because the change hasn't been applied yet", async () => { - await expect(testContract.methods.test_nullifier_key_freshness(wallets[0].getAddress(), newMasterNullifierPublicKey).send().wait()).rejects.toThrow(); + await expect( + testContract.methods + .test_nullifier_key_freshness(wallets[0].getAddress(), newMasterNullifierPublicKey) + .send() + .wait(), + ).rejects.toThrow(); }); it('checks our registry contract from test contract and succeeds because the change has been applied', async () => { await delay(5); - await testContract.methods.test_nullifier_key_freshness(wallets[0].getAddress(), newMasterNullifierPublicKey).send().wait(); + await testContract.methods + .test_nullifier_key_freshness(wallets[0].getAddress(), newMasterNullifierPublicKey) + .send() + .wait(); }); }); }); diff --git a/yarn-project/package.common.json b/yarn-project/package.common.json index 80b56a8d697..6fcf1a28315 100644 --- a/yarn-project/package.common.json +++ b/yarn-project/package.common.json @@ -24,7 +24,7 @@ "moduleNameMapper": { "^(\\.{1,2}/.*)\\.[cm]?js$": "$1" }, - "reporters": [["default", {"summaryThreshold": 9999}]], + "reporters": [["default", { "summaryThreshold": 9999 }]], "testRegex": "./src/.*\\.test\\.(js|mjs|ts)$", "rootDir": "./src" } diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index 607f4679940..b9ef265e408 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -42,7 +42,7 @@ import { import { computeCommitmentNonce, siloNullifier } from '@aztec/circuits.js/hash'; import { type ContractArtifact, type DecodedReturn, FunctionSelector, encodeArguments } from '@aztec/foundation/abi'; import { arrayNonEmptyLength, padArrayEnd } from '@aztec/foundation/collection'; -import { Fr, Point } from '@aztec/foundation/fields'; +import { Fr, type Point } from '@aztec/foundation/fields'; import { SerialQueue } from '@aztec/foundation/fifo'; import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { Timer } from '@aztec/foundation/timer'; @@ -218,9 +218,15 @@ export class PXEService implements PXE { public async registerRecipient(recipient: CompleteAddress, publicKeys: Point[] = []): Promise { const wasAdded = await this.db.addCompleteAddress(recipient); - + if (publicKeys.length !== 0) { - await this.keyStore.addPublicKeysForAccount(recipient.address, publicKeys[0], publicKeys[1], publicKeys[2], publicKeys[3]); + await this.keyStore.addPublicKeysForAccount( + recipient.address, + publicKeys[0], + publicKeys[1], + publicKeys[2], + publicKeys[3], + ); } if (wasAdded) { diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index 80b51a611b8..867ca8d0824 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -9,14 +9,13 @@ import { type SiblingPath, } from '@aztec/circuit-types'; import { - Fr, - Point, type AztecAddress, type CompleteAddress, - type EthAddress, + type Fr, type FunctionSelector, type Header, type L1_TO_L2_MSG_TREE_HEIGHT, + type Point, } from '@aztec/circuits.js'; import { computeL1ToL2MessageNullifier } from '@aztec/circuits.js/hash'; import { type FunctionArtifactWithDebugMetadata, getFunctionArtifactWithDebugMetadata } from '@aztec/foundation/abi'; @@ -85,7 +84,7 @@ export class SimulatorOracle implements DBOracle { const outgoingViewingPublicKey = await this.keyStore.getMasterOutgoingViewingPublicKey(address); const taggingPublicKey = await this.keyStore.getMasterTaggingPublicKey(address); - return [nullifierPublicKey, incomingViewingPublicKey, outgoingViewingPublicKey, taggingPublicKey] + return [nullifierPublicKey, incomingViewingPublicKey, outgoingViewingPublicKey, taggingPublicKey]; } async getNotes(contractAddress: AztecAddress, storageSlot: Fr, status: NoteStatus) { diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index 4aca6d5f5e7..8226f58a1bc 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -176,22 +176,17 @@ export class Oracle { let partialAddress: PartialAddress; let publicKeys: Point[] | undefined; try { - ({ partialAddress } = await this.typedOracle.getCompleteAddress( - AztecAddress.fromField(fromACVMField(address)), - )); + ({ partialAddress } = await this.typedOracle.getCompleteAddress(AztecAddress.fromField(fromACVMField(address)))); } catch (err) { partialAddress = Fr.ZERO; } try { publicKeys = await this.typedOracle.getPublicKeysForAddress(AztecAddress.fromField(fromACVMField(address))); - } catch(err) { + } catch (err) { publicKeys = Array(4).fill(Point.ZERO); } - console.log('partial address', partialAddress); - console.log('public keys', publicKeys); - const acvmKeys = publicKeys.flatMap(key => key.toFields()); return [partialAddress, ...acvmKeys].map(toACVMField); diff --git a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts index 568b6c38f6d..de60e6e55e1 100644 --- a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts @@ -17,7 +17,7 @@ import { } from '@aztec/circuits.js'; import { type FunctionSelector } from '@aztec/foundation/abi'; import { type AztecAddress } from '@aztec/foundation/aztec-address'; -import { Fr, Point } from '@aztec/foundation/fields'; +import { Fr, type Point } from '@aztec/foundation/fields'; import { type ContractInstance } from '@aztec/types/contracts'; /** Nullifier keys which both correspond to the same master nullifier secret key. */ @@ -140,9 +140,7 @@ export abstract class TypedOracle { throw new OracleMethodNotAvailableError('popCapsule'); } - getPublicKeysForAddress( - _address: AztecAddress, - ): Promise { + getPublicKeysForAddress(_address: AztecAddress): Promise { throw new OracleMethodNotAvailableError('getPublicKeysForAddress'); } diff --git a/yarn-project/simulator/src/client/db_oracle.ts b/yarn-project/simulator/src/client/db_oracle.ts index 8433ca44d88..9287249f1cf 100644 --- a/yarn-project/simulator/src/client/db_oracle.ts +++ b/yarn-project/simulator/src/client/db_oracle.ts @@ -8,8 +8,7 @@ import { import { type CompleteAddress, type Header } from '@aztec/circuits.js'; import { type FunctionArtifactWithDebugMetadata, type FunctionSelector } from '@aztec/foundation/abi'; import { type AztecAddress } from '@aztec/foundation/aztec-address'; -import { type EthAddress } from '@aztec/foundation/eth-address'; -import { Point, type Fr } from '@aztec/foundation/fields'; +import { type Fr, type Point } from '@aztec/foundation/fields'; import { type ContractInstance } from '@aztec/types/contracts'; import { type NoteData, type NullifierKeys } from '../acvm/index.js'; diff --git a/yarn-project/simulator/src/client/view_data_oracle.ts b/yarn-project/simulator/src/client/view_data_oracle.ts index 00bb685e8c8..d2a85c4a242 100644 --- a/yarn-project/simulator/src/client/view_data_oracle.ts +++ b/yarn-project/simulator/src/client/view_data_oracle.ts @@ -166,9 +166,7 @@ export class ViewDataOracle extends TypedOracle { return this.db.popCapsule(); } - public override getPublicKeysForAddress( - address: AztecAddress, - ) { + public override getPublicKeysForAddress(address: AztecAddress) { return this.db.getPublicKeysForAddress(address); } From 29bfb809d0e84fdeaa90d6ea2da160a884585d10 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 26 Apr 2024 15:28:47 +0000 Subject: [PATCH 08/93] fix --- noir-projects/aztec-nr/aztec/src/keys.nr | 2 +- .../aztec-nr/aztec/src/keys/assert_public_key_freshness.nr | 2 +- .../noir-contracts/contracts/test_contract/src/main.nr | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/keys.nr b/noir-projects/aztec-nr/aztec/src/keys.nr index 7e83884a099..427d30ba671 100644 --- a/noir-projects/aztec-nr/aztec/src/keys.nr +++ b/noir-projects/aztec-nr/aztec/src/keys.nr @@ -1,3 +1,3 @@ mod assert_public_key_freshness; -use crate::keys::assert_public_key_freshness::assert_nullifier_public_key_fresh; +use crate::keys::assert_public_key_freshness::assert_nullifier_public_key_is_fresh; diff --git a/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr b/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr index d1961792feb..a1fffce3ef4 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr @@ -27,7 +27,7 @@ global PublicKeyType = PublicKeyTypeEnum { NULLIFIER: 0, }; -pub fn assert_nullifier_public_key_fresh( +pub fn assert_nullifier_public_key_is_fresh( context: &mut PrivateContext, address: AztecAddress, nullifier_public_key_to_test: GrumpkinPoint, 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 68311b75f4f..5d8fecf96da 100644 --- a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr @@ -19,7 +19,7 @@ contract Test { use dep::aztec::state_vars::shared_mutable::SharedMutablePrivateGetter; use dep::aztec::{ - keys::assert_public_key_freshness::assert_nullifier_public_key_fresh, + keys::assert_public_key_freshness::assert_nullifier_public_key_is_fresh, context::{Context, inputs::private_context_inputs::PrivateContextInputs}, hash::{pedersen_hash, compute_secret_hash, ArgsHasher}, note::{ @@ -415,7 +415,7 @@ contract Test { address: AztecAddress, public_nullifying_key: GrumpkinPoint, ) { - assert_nullifier_public_key_fresh(&mut context, address, public_nullifying_key); + assert_nullifier_public_key_is_fresh(&mut context, address, public_nullifying_key); } #[aztec(public)] From 7d1620d6ca9b6c9bdc147b0fcc878edc5f14c8e1 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 26 Apr 2024 16:47:18 +0000 Subject: [PATCH 09/93] change some stuff --- .../src/keys/assert_public_key_freshness.nr | 48 +---- .../aztec-nr/aztec/src/oracle/keys.nr | 97 +++++---- .../end-to-end/src/e2e_key_registry.test.ts | 192 +++++++++--------- .../pxe/src/simulator_oracle/index.ts | 2 + .../simulator/src/acvm/oracle/oracle.ts | 1 + .../simulator/src/client/db_oracle.ts | 6 + .../simulator/src/client/view_data_oracle.ts | 7 + 7 files changed, 180 insertions(+), 173 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr b/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr index a1fffce3ef4..46a9122dc19 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr @@ -55,53 +55,13 @@ pub fn assert_nullifier_public_key_is_fresh( } fn check_public_key_validity(address: AztecAddress, key_type: u8, key: GrumpkinPoint) { - let (partial_address, keys) = get_public_keys_and_partial_address_internal(address); + let keys = get_public_keys_internal(address); assert(keys[key_type].eq(key)); - - _check_public_key_validity_constrain_internal( - address, - partial_address, - keys[0], - keys[1], - keys[2], - keys[3], - ) -} - -unconstrained fn get_public_keys_and_partial_address_internal(address: AztecAddress) -> (PartialAddress, [GrumpkinPoint; 4]) { - let (partial_address, public_keys) = oracle::keys::get_public_keys_and_partial_address(address); - - (partial_address, public_keys) } -fn _check_public_key_validity_constrain_internal( - address: AztecAddress, - partial_address: PartialAddress, - nullifier_public_key: GrumpkinPoint, - incoming_public_key: GrumpkinPoint, - outgoing_public_key: GrumpkinPoint, - tagging_public_key: GrumpkinPoint - ) { - let public_keys_hash = poseidon2_hash([ - nullifier_public_key.serialize()[0], - nullifier_public_key.serialize()[1], - incoming_public_key.serialize()[0], - incoming_public_key.serialize()[1], - outgoing_public_key.serialize()[0], - outgoing_public_key.serialize()[1], - tagging_public_key.serialize()[0], - tagging_public_key.serialize()[1], - GENERATOR_INDEX__PUBLIC_KEYS_HASH, - ]); - - let computed_address = AztecAddress::from_field( - poseidon2_hash([ - partial_address.to_field(), - public_keys_hash.to_field(), - GENERATOR_INDEX__CONTRACT_ADDRESS_V1, - ]) - ); +fn get_public_keys_internal(address: AztecAddress) -> [GrumpkinPoint; 4] { + let (_, public_keys) = oracle::keys::get_public_keys_and_partial_address(address); - assert(computed_address.eq(address)); + public_keys } diff --git a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr index 4ff757be4d4..ca67986d093 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr @@ -1,47 +1,76 @@ -use dep::protocol_types::{address::{AztecAddress, PartialAddress, PublicKeysHash}, grumpkin_point::GrumpkinPoint}; +use dep::protocol_types::{ + address::{ + AztecAddress, + PartialAddress, + PublicKeysHash, + }, + constants::{ + GENERATOR_INDEX__PUBLIC_KEYS_HASH, + GENERATOR_INDEX__CONTRACT_ADDRESS_V1, + }, + grumpkin_point::GrumpkinPoint, +}; -#[oracle(getPublicKeysForAddress)] -fn get_public_keys_for_address_oracle( - address: AztecAddress, -) -> [GrumpkinPoint; 4] {} +use crate::hash::poseidon2_hash; -unconstrained fn get_public_keys_for_address_oracle_wrapper( - address: AztecAddress -) -> [GrumpkinPoint; 4] { - get_public_keys_for_address_oracle( - address, - ) +#[oracle(getPublicKeysAndPartialAddress)] +fn get_public_keys_and_partial_address_oracle(_address: AztecAddress) -> [Field; 9] {} + +unconstrained fn get_public_keys_and_partial_address_oracle_wrapper(address: AztecAddress) -> [Field; 9] { + get_public_keys_and_partial_address_oracle(address) } -unconstrained pub fn get_public_keys_for_address( - address: AztecAddress, -) -> [GrumpkinPoint; 4] { - let public_keys = get_public_keys_for_address_oracle_wrapper( +pub fn get_public_keys_and_partial_address(address: AztecAddress) -> (PartialAddress, [GrumpkinPoint; 4]) { + let result = get_public_keys_and_partial_address_oracle_wrapper(address); + + let partial_address = PartialAddress::from_field(result[0]); + let nullifier_pub_key = GrumpkinPoint::new(result[1], result[2]); + let incoming_pub_key = GrumpkinPoint::new(result[3], result[4]); + let outgoing_pub_key = GrumpkinPoint::new(result[5], result[6]); + let tagging_pub_key = GrumpkinPoint::new(result[7], result[8]); + + _check_public_key_validity_constrain_oracle( address, + partial_address, + nullifier_pub_key, + incoming_pub_key, + outgoing_pub_key, + tagging_pub_key, ); - public_keys + (partial_address, [nullifier_pub_key, incoming_pub_key, outgoing_pub_key, tagging_pub_key]) } +fn _check_public_key_validity_constrain_oracle( + address: AztecAddress, + partial_address: PartialAddress, + nullifier_public_key: GrumpkinPoint, + incoming_public_key: GrumpkinPoint, + outgoing_public_key: GrumpkinPoint, + tagging_public_key: GrumpkinPoint + ) { + let public_keys_hash = poseidon2_hash([ + nullifier_public_key.serialize()[0], + nullifier_public_key.serialize()[1], + incoming_public_key.serialize()[0], + incoming_public_key.serialize()[1], + outgoing_public_key.serialize()[0], + outgoing_public_key.serialize()[1], + tagging_public_key.serialize()[0], + tagging_public_key.serialize()[1], + GENERATOR_INDEX__PUBLIC_KEYS_HASH, + ]); -#[oracle(getPublicKeysAndPartialAddress)] -fn get_public_keys_and_partial_address_oracle(_address: AztecAddress) -> [Field; 9] {} +// TODO: #5830: we can compute this like below once refactored +// let calculated_address = AztecAddress::compute(PublicKeysHash::compute(pub_key), partial_address); -unconstrained fn get_public_keys_and_partial_address_oracle_wrapper(address: AztecAddress) -> [Field; 9] { - get_public_keys_and_partial_address_oracle(address) -} + let computed_address = AztecAddress::from_field( + poseidon2_hash([ + partial_address.to_field(), + public_keys_hash.to_field(), + GENERATOR_INDEX__CONTRACT_ADDRESS_V1, + ]) + ); -pub fn get_public_keys_and_partial_address(address: AztecAddress) -> (PartialAddress, [GrumpkinPoint; 4]) { - let result = get_public_keys_and_partial_address_oracle_wrapper(address); - let partial_address = PartialAddress::from_field(result[0]); - let nullifier_pub_key = GrumpkinPoint::new(result[1], result[2]); - let incoming_pub_key = GrumpkinPoint::new(result[3], result[4]); - let outgoing_pub_key = GrumpkinPoint::new(result[5], result[6]); - let tagging_pub_key = GrumpkinPoint::new(result[7], result[8]); - - // TODO(#5830): disabling the following constraint until we update the oracle according to the new key scheme - // let calculated_address = AztecAddress::compute(PublicKeysHash::compute(pub_key), partial_address); - // assert(calculated_address.eq(address)); - - (partial_address, [nullifier_pub_key, incoming_pub_key, outgoing_pub_key, tagging_pub_key]) + assert(computed_address.eq(address)); } 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 index 2b686e27288..e11585002cb 100644 --- a/yarn-project/end-to-end/src/e2e_key_registry.test.ts +++ b/yarn-project/end-to-end/src/e2e_key_registry.test.ts @@ -22,7 +22,7 @@ describe('Key Registry', () => { let teardown: () => Promise; beforeAll(async () => { - ({ teardown, pxe, wallets } = await setup(2)); + ({ teardown, pxe, wallets } = await setup(3)); keyRegistry = await KeyRegistryContract.at(getCanonicalKeyRegistryAddress(), wallets[0]); testContract = await TestContract.deploy(wallets[0]).send().deployed(); @@ -42,12 +42,11 @@ describe('Key Registry', () => { let accountAddedToRegistry: AztecAddress; describe('should fail registering with bad input', () => { - const partialAddress = new Fr(69); - - const masterNullifierPublicKey = new Fr(12); - const masterIncomingViewingPublicKey = new Fr(34); - const masterOutgoingViewingPublicKey = new Fr(56); - const masterTaggingPublicKey = new Fr(78); + const masterNullifierPublicKey: Point = new Point(new Fr(1), new Fr(2)); + const masterIncomingViewingPublicKey: Point = new Point(new Fr(3), new Fr(4)); + const masterOutgoingViewingPublicKey: Point = new Point(new Fr(5), new Fr(6)); + const masterTaggingPublicKey: Point = new Point(new Fr(7), new Fr(8)); + const partialAddress: PartialAddress = new Fr(69); // TODO(#5726): use computePublicKeysHash function const publicKeysHash = poseidon2Hash([ @@ -82,7 +81,7 @@ describe('Key Registry', () => { }); it('should fail registering with mismatched nullifier public key', async () => { - const mismatchedMasterNullifierPublicKey = Fr.random(); + const mismatchedMasterNullifierPublicKey = Point.random(); await expect( keyRegistry @@ -106,7 +105,7 @@ describe('Key Registry', () => { await expect( keyRegistry .withWallet(wallets[0]) - .methods.rotate_nullifier_public_key(wallets[0].getAddress(), new Fr(0)) + .methods.rotate_nullifier_public_key(wallets[0].getAddress(), Point.ZERO) .send() .wait(), ).rejects.toThrow('New nullifier public key must be non-zero'); @@ -116,7 +115,7 @@ describe('Key Registry', () => { await expect( keyRegistry .withWallet(wallets[0]) - .methods.rotate_nullifier_public_key(wallets[1].getAddress(), new Fr(2)) + .methods.rotate_nullifier_public_key(wallets[1].getAddress(), Point.random()) .send() .wait(), ).rejects.toThrow('Assertion failed: Message not authorized by account'); @@ -126,14 +125,13 @@ describe('Key Registry', () => { describe('key registration flow', () => { let accountAddedToRegistry: AztecAddress; + const masterNullifierPublicKey: Point = new Point(new Fr(1), new Fr(2)); it('should generate and register with original keys', async () => { - const partialAddress = new Fr(69); - - const masterNullifierPublicKey = new Fr(12); - const masterIncomingViewingPublicKey = new Fr(34); - const masterOutgoingViewingPublicKey = new Fr(56); - const masterTaggingPublicKey = new Fr(78); + const masterIncomingViewingPublicKey: Point = new Point(new Fr(3), new Fr(4)); + const masterOutgoingViewingPublicKey: Point = new Point(new Fr(5), new Fr(6)); + const masterTaggingPublicKey: Point = new Point(new Fr(7), new Fr(8)); + const partialAddress: PartialAddress = new Fr(69); const publicKeysHash = poseidon2Hash([ masterNullifierPublicKey, @@ -181,86 +179,89 @@ describe('Key Registry', () => { const rawLogs = await pxe.getUnencryptedLogs({ txHash }); - expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(12)); + expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(poseidon2Hash(masterNullifierPublicKey.toFields())); }); }); - describe('key rotation flow', () => { - it('we rotate the nullifier key', async () => { - // This changes - const newMasterNullifierPublicKey = new Fr(910); - - await keyRegistry - .withWallet(wallets[0]) - .methods.rotate_nullifier_public_key(wallets[0].getAddress(), newMasterNullifierPublicKey) - .send() - .wait(); - }); - - it("checks our registry contract from test contract and finds our old public key because the key rotation hasn't been applied yet", async () => { - const { txHash } = await testContract.methods - .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) - .send() - .wait(); - - const rawLogs = await pxe.getUnencryptedLogs({ txHash }); - expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(0)); - }); - - it('checks our registry contract from test contract and finds the new nullifier public key that has been rotated', async () => { - await delay(5); - - const { txHash } = await testContract.methods - .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) - .send() - .wait(); + describe('key rotation flows', () => { + const firstNewMasterNullifierPublicKey = Point.random(); - const rawLogs = await pxe.getUnencryptedLogs({ txHash }); - - expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(910)); - }); - }); - - describe('key rotation flow with authwit', () => { - it('wallet 0 lets wallet 1 call rotate_nullifier_public_key on his behalf with a pre-defined new public key', async () => { + describe('normal key rotation flow', () => { // This changes - const newMasterNullifierPublicKey = new Fr(420); - - const action = keyRegistry - .withWallet(wallets[1]) - .methods.rotate_nullifier_public_key(wallets[0].getAddress(), newMasterNullifierPublicKey); - - await wallets[0] - .setPublicAuthWit({ caller: wallets[1].getCompleteAddress().address, action }, true) - .send() - .wait(); - - await action.send().wait(); - }); - - it("checks our registry contract from test contract and finds our old public key because the key rotation hasn't been applied yet", async () => { - const { txHash } = await testContract.methods - .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) - .send() - .wait(); - - const rawLogs = await pxe.getUnencryptedLogs({ txHash }); - expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(910)); + + it('we rotate the nullifier key', async () => { + await keyRegistry + .withWallet(wallets[0]) + .methods.rotate_nullifier_public_key(wallets[0].getAddress(), firstNewMasterNullifierPublicKey) + .send() + .wait(); + }); + + it("checks our registry contract from test contract and finds our old public key because the key rotation hasn't been applied yet", async () => { + const { txHash } = await testContract.methods + .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) + .send() + .wait(); + + const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(0)); + }); + + it('checks our registry contract from test contract and finds the new nullifier public key that has been rotated', async () => { + await delay(5); + + const { txHash } = await testContract.methods + .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) + .send() + .wait(); + + const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + + expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(poseidon2Hash(firstNewMasterNullifierPublicKey.toFields())); + }); }); - - it('checks our registry contract from test contract and finds the new nullifier public key that has been rotated', async () => { - await delay(5); - - const { txHash } = await testContract.methods - .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) - .send() - .wait(); - - const rawLogs = await pxe.getUnencryptedLogs({ txHash }); - - expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(420)); + + describe('key rotation flow with authwit', () => { + // This changes + const secondNewMasterNullifierPublicKey = Point.random(); + + it('wallet 0 lets wallet 1 call rotate_nullifier_public_key on his behalf with a pre-defined new public key', async () => { + const action = keyRegistry + .withWallet(wallets[1]) + .methods.rotate_nullifier_public_key(wallets[0].getAddress(), secondNewMasterNullifierPublicKey); + + await wallets[0] + .setPublicAuthWit({ caller: wallets[1].getCompleteAddress().address, action }, true) + .send() + .wait(); + + await action.send().wait(); + }); + + it("checks our registry contract from test contract and finds our old public key because the key rotation hasn't been applied yet", async () => { + const { txHash } = await testContract.methods + .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) + .send() + .wait(); + + const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(poseidon2Hash(firstNewMasterNullifierPublicKey.toFields())); + }); + + it('checks our registry contract from test contract and finds the new nullifier public key that has been rotated', async () => { + await delay(5); + + const { txHash } = await testContract.methods + .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) + .send() + .wait(); + + const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + + expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(poseidon2Hash(secondNewMasterNullifierPublicKey.toFields())); + }); }); - }); + }) describe('key registration flow no PXE', () => { const masterNullifierPublicKey: Point = new Point(new Fr(9), new Fr(10)); @@ -325,11 +326,12 @@ describe('Key Registry', () => { }); describe('key registration flow via PXE', () => { - const masterNullifierPublicKey: Point = new Point(new Fr(1), new Fr(2)); - const masterIncomingViewingPublicKey: Point = new Point(new Fr(3), new Fr(4)); - const masterOutgoingViewingPublicKey: Point = new Point(new Fr(5), new Fr(6)); - const masterTaggingPublicKey: Point = new Point(new Fr(7), new Fr(8)); - const partialAddress: PartialAddress = new Fr(69); + const masterNullifierPublicKey: Point = new Point(new Fr(17), new Fr(18)); + const masterIncomingViewingPublicKey: Point = new Point(new Fr(19), new Fr(20)); + const masterOutgoingViewingPublicKey: Point = new Point(new Fr(21), new Fr(22)); + const masterTaggingPublicKey: Point = new Point(new Fr(23), new Fr(24)); + + const partialAddress: PartialAddress = new Fr(69420); const publicKeysHash = poseidon2Hash([ masterNullifierPublicKey, @@ -397,7 +399,7 @@ describe('Key Registry', () => { .wait(); }); - it('in the case where the key exists both in the pxe and our registry, we know it works', async () => { + it('in the case where the key exists both in the pxe and our registry, we know nothing weird will happen', async () => { await delay(5); const { txHash } = await testContract.methods diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index 867ca8d0824..0a81cc5b1d6 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -44,6 +44,7 @@ export class SimulatorOracle implements DBOracle { return { masterNullifierPublicKey, appNullifierSecretKey }; } + // TODO: #5834 async getCompleteAddress(address: AztecAddress): Promise { const completeAddress = await this.db.getCompleteAddress(address); if (!completeAddress) { @@ -78,6 +79,7 @@ export class SimulatorOracle implements DBOracle { return capsule; } + // TODO: #5834 async getPublicKeysForAddress(address: AztecAddress): Promise { const nullifierPublicKey = await this.keyStore.getMasterNullifierPublicKey(address); const incomingViewingPublicKey = await this.keyStore.getMasterIncomingViewingPublicKey(address); diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index 8226f58a1bc..3eaf7f9411f 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -175,6 +175,7 @@ export class Oracle { async getPublicKeysAndPartialAddress([address]: ACVMField[]): Promise { let partialAddress: PartialAddress; let publicKeys: Point[] | undefined; + // TODO #5834: This should be reworked to return the public keys as well try { ({ partialAddress } = await this.typedOracle.getCompleteAddress(AztecAddress.fromField(fromACVMField(address)))); } catch (err) { diff --git a/yarn-project/simulator/src/client/db_oracle.ts b/yarn-project/simulator/src/client/db_oracle.ts index 9287249f1cf..2646898a612 100644 --- a/yarn-project/simulator/src/client/db_oracle.ts +++ b/yarn-project/simulator/src/client/db_oracle.ts @@ -64,6 +64,12 @@ export interface DBOracle extends CommitmentsDB { */ popCapsule(): Promise; + /** + * Gets public keys for an address, getCompleteAddress should be modified to include this + * @param The address to look up + * @returns The public keys for a specific address + * TODO: #5834 + */ getPublicKeysForAddress(address: AztecAddress): Promise; /** diff --git a/yarn-project/simulator/src/client/view_data_oracle.ts b/yarn-project/simulator/src/client/view_data_oracle.ts index d2a85c4a242..48c4adc873f 100644 --- a/yarn-project/simulator/src/client/view_data_oracle.ts +++ b/yarn-project/simulator/src/client/view_data_oracle.ts @@ -166,6 +166,13 @@ export class ViewDataOracle extends TypedOracle { return this.db.popCapsule(); } + + /** + * Gets public keys for an address, getCompleteAddress should be modified to include this + * @param The address to look up + * @returns The public keys for a specific address + * TODO: #5834 + */ public override getPublicKeysForAddress(address: AztecAddress) { return this.db.getPublicKeysForAddress(address); } From f0ece6935a48d79059db942134574bfb483d8345 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 26 Apr 2024 16:49:51 +0000 Subject: [PATCH 10/93] fix --- yarn-project/simulator/src/acvm/oracle/oracle.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index 3eaf7f9411f..900a99558f9 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -53,7 +53,7 @@ export class Oracle { ]; } - // TODO (ek): Nuke this + // TODO: #5830 Nuke this async getPublicKeyAndPartialAddress([address]: ACVMField[]) { const { publicKey, partialAddress } = await this.typedOracle.getCompleteAddress( AztecAddress.fromField(fromACVMField(address)), From 046100659ec34f09dd36ba7a180485c1ca75e339 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 26 Apr 2024 16:50:55 +0000 Subject: [PATCH 11/93] fix --- yarn-project/simulator/src/acvm/oracle/oracle.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index 900a99558f9..0aaca5464f9 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -53,7 +53,7 @@ export class Oracle { ]; } - // TODO: #5830 Nuke this + // TODO: #5834 Nuke this async getPublicKeyAndPartialAddress([address]: ACVMField[]) { const { publicKey, partialAddress } = await this.typedOracle.getCompleteAddress( AztecAddress.fromField(fromACVMField(address)), From e4f6d15b5c4d0ca3d209f2e77fbbc0aefc47d871 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 26 Apr 2024 16:52:15 +0000 Subject: [PATCH 12/93] asdf --- yarn-project/pxe/src/pxe_service/pxe_service.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index b9ef265e408..b302acf598d 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -219,6 +219,7 @@ export class PXEService implements PXE { public async registerRecipient(recipient: CompleteAddress, publicKeys: Point[] = []): Promise { const wasAdded = await this.db.addCompleteAddress(recipient); + // #5834 if (publicKeys.length !== 0) { await this.keyStore.addPublicKeysForAccount( recipient.address, From f9a844b701c4fd7410343171728917fba335e535 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 26 Apr 2024 16:58:13 +0000 Subject: [PATCH 13/93] fix --- yarn-project/circuit-types/src/interfaces/pxe.ts | 2 +- yarn-project/circuit-types/src/keys/key_store.ts | 7 ++++++- yarn-project/pxe/src/pxe_service/pxe_service.ts | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/yarn-project/circuit-types/src/interfaces/pxe.ts b/yarn-project/circuit-types/src/interfaces/pxe.ts index f36958df987..eab85b46980 100644 --- a/yarn-project/circuit-types/src/interfaces/pxe.ts +++ b/yarn-project/circuit-types/src/interfaces/pxe.ts @@ -73,7 +73,7 @@ export interface PXE { * the recipient's notes. We can send notes to this account because we can encrypt them with the recipient's * public key. */ - // TODO: FIX THIS AFTER THE COMPLETE ADDRESS REFACTOR + // TODO: #5834: FIX THIS AFTER THE COMPLETE ADDRESS REFACTOR registerRecipient(recipient: CompleteAddress, publicKeys?: Point[]): Promise; /** diff --git a/yarn-project/circuit-types/src/keys/key_store.ts b/yarn-project/circuit-types/src/keys/key_store.ts index e5cefbd7bc4..dd77bde64ed 100644 --- a/yarn-project/circuit-types/src/keys/key_store.ts +++ b/yarn-project/circuit-types/src/keys/key_store.ts @@ -119,7 +119,12 @@ export interface KeyStore { getPublicKeysHash(account: AztecAddress): Promise; /** - * + * This is used to register a recipient / for storing public keys of an address + * @param accountAddress - The account address to store keys for. + * @param masterNullifierPublicKey - The stored master nullifier public key + * @param masterIncomingViewingPublicKey - The stored incoming viewing public key + * @param masterOutgoingViewingPublicKey - The stored outgoing viewing public key + * @param masterTaggingPublicKey - The stored master tagging public key */ addPublicKeysForAccount( accountAddress: AztecAddress, diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index b302acf598d..c1747a2d6c4 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -219,7 +219,7 @@ export class PXEService implements PXE { public async registerRecipient(recipient: CompleteAddress, publicKeys: Point[] = []): Promise { const wasAdded = await this.db.addCompleteAddress(recipient); - // #5834 + // TODO #5834: This should be refactored to be okay with only adding complete address if (publicKeys.length !== 0) { await this.keyStore.addPublicKeysForAccount( recipient.address, From 0e0b63e3fe7c8c4907c0bfa7c1fce615b818b4c4 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 26 Apr 2024 18:51:05 +0000 Subject: [PATCH 14/93] fix --- .../src/keys/assert_public_key_freshness.nr | 6 +- .../aztec-nr/aztec/src/oracle/keys.nr | 6 +- .../end-to-end/src/e2e_key_registry.test.ts | 90 +++++++++++++------ 3 files changed, 69 insertions(+), 33 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr b/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr index 46a9122dc19..dc0915b92e4 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr @@ -44,13 +44,13 @@ pub fn assert_nullifier_public_key_is_fresh( // It's a bit wonky because we need to know the delay for get_current_value_in_private to work correctly // We read from the canonical Key Registry let registry_private_getter: SharedMutablePrivateGetter = SharedMutablePrivateGetter::new(*context, AztecAddress::from_field(CANONICAL_KEY_REGISTRY_ADDRESS), derived_slot); - let hashed_nullifier_public_key = registry_private_getter.get_current_value_in_private(); + let hashed_nullifier_public_key_in_registry = registry_private_getter.get_current_value_in_private(); // In the case that the value is not found in the registry we need to manually pass in the address preimage - if (hashed_nullifier_public_key == 0) { + if (hashed_nullifier_public_key_in_registry == 0) { check_public_key_validity(address, PublicKeyType.NULLIFIER, nullifier_public_key_to_test); } else { - assert(hashed_nullifier_public_key == poseidon2_hash(nullifier_public_key_to_test.serialize())); + assert(hashed_nullifier_public_key_in_registry == poseidon2_hash(nullifier_public_key_to_test.serialize())); } } diff --git a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr index ca67986d093..2a7fd4a41ee 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr @@ -66,9 +66,9 @@ fn _check_public_key_validity_constrain_oracle( let computed_address = AztecAddress::from_field( poseidon2_hash([ - partial_address.to_field(), - public_keys_hash.to_field(), - GENERATOR_INDEX__CONTRACT_ADDRESS_V1, + partial_address.to_field(), + public_keys_hash.to_field(), + GENERATOR_INDEX__CONTRACT_ADDRESS_V1, ]) ); 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 index e11585002cb..6ca01a15d1e 100644 --- a/yarn-project/end-to-end/src/e2e_key_registry.test.ts +++ b/yarn-project/end-to-end/src/e2e_key_registry.test.ts @@ -42,11 +42,11 @@ describe('Key Registry', () => { let accountAddedToRegistry: AztecAddress; describe('should fail registering with bad input', () => { - const masterNullifierPublicKey: Point = new Point(new Fr(1), new Fr(2)); - const masterIncomingViewingPublicKey: Point = new Point(new Fr(3), new Fr(4)); - const masterOutgoingViewingPublicKey: Point = new Point(new Fr(5), new Fr(6)); - const masterTaggingPublicKey: Point = new Point(new Fr(7), new Fr(8)); - const partialAddress: PartialAddress = new Fr(69); + const masterNullifierPublicKey = Point.random(); + const masterIncomingViewingPublicKey = Point.random(); + const masterOutgoingViewingPublicKey = Point.random(); + const masterTaggingPublicKey = Point.random(); + const partialAddress: PartialAddress = Fr.random(); // TODO(#5726): use computePublicKeysHash function const publicKeysHash = poseidon2Hash([ @@ -59,16 +59,16 @@ describe('Key Registry', () => { // We hash the partial address and the public keys hash to get the account address // TODO(#5726): Move the following line to AztecAddress class? - accountAddedToRegistry = poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1]); + accountAddedToRegistry = AztecAddress.fromField(poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1])); it('should fail registering with mismatched address', async () => { - const mismatchedAddress = Fr.random(); + const mismatchedAddress = AztecAddress.random(); await expect( keyRegistry .withWallet(wallets[0]) .methods.register( - AztecAddress.fromField(mismatchedAddress), + mismatchedAddress, partialAddress, masterNullifierPublicKey, masterIncomingViewingPublicKey, @@ -143,7 +143,7 @@ describe('Key Registry', () => { // We hash the partial address and the public keys hash to get the account address // TODO(#5726): Move the following line to AztecAddress class? - accountAddedToRegistry = poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1]); + accountAddedToRegistry = AztecAddress.fromField(poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1])); await keyRegistry .withWallet(wallets[0]) @@ -186,9 +186,7 @@ describe('Key Registry', () => { describe('key rotation flows', () => { const firstNewMasterNullifierPublicKey = Point.random(); - describe('normal key rotation flow', () => { - // This changes - + describe('normal key rotation flow', () => { it('we rotate the nullifier key', async () => { await keyRegistry .withWallet(wallets[0]) @@ -222,7 +220,7 @@ describe('Key Registry', () => { }); describe('key rotation flow with authwit', () => { - // This changes + // This is the new value const secondNewMasterNullifierPublicKey = Point.random(); it('wallet 0 lets wallet 1 call rotate_nullifier_public_key on his behalf with a pre-defined new public key', async () => { @@ -263,11 +261,11 @@ describe('Key Registry', () => { }); }) - describe('key registration flow no PXE', () => { - const masterNullifierPublicKey: Point = new Point(new Fr(9), new Fr(10)); - const masterIncomingViewingPublicKey: Point = new Point(new Fr(11), new Fr(12)); - const masterOutgoingViewingPublicKey: Point = new Point(new Fr(13), new Fr(14)); - const masterTaggingPublicKey: Point = new Point(new Fr(15), new Fr(16)); + describe('test keys are fresh: key registration flow, no PXE', () => { + const masterNullifierPublicKey = Point.random(); + const masterIncomingViewingPublicKey = Point.random(); + const masterOutgoingViewingPublicKey = Point.random(); + const masterTaggingPublicKey = Point.random(); const partialAddress: PartialAddress = new Fr(420); const publicKeysHash = poseidon2Hash([ @@ -280,7 +278,7 @@ describe('Key Registry', () => { // We hash the partial address and the public keys hash to get the account address // TODO(#5726): Move the following line to AztecAddress class? - const accountAddedToRegistry = poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1]); + const accountAddedToRegistry = AztecAddress.fromField(poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1])); it('should fail as we have not registered anything to the registry nor have we registered a recipient', async () => { await expect( @@ -288,7 +286,7 @@ describe('Key Registry', () => { .test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey) .send() .wait(), - ).rejects.toThrow(); + ).rejects.toThrow(`Cannot satisfy constraint 'computed_address.eq(address)'`); }); it('Now we add it to registry', async () => { @@ -312,7 +310,7 @@ describe('Key Registry', () => { .test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey) .send() .wait(), - ).rejects.toThrow(); + ).rejects.toThrow(`Cannot satisfy constraint 'computed_address.eq(address)'`); }); it('checks key freshness after a delay, and is successful', async () => { @@ -323,9 +321,24 @@ describe('Key Registry', () => { .send() .wait(); }); + + it('should succeed even if our pxe gives conflicting information', async () => { + // FIX THIS (#5834) + await pxe.registerRecipient(CompleteAddress.create(accountAddedToRegistry, Point.ZERO, partialAddress), [ + new Point(Fr.random(), Fr.random()), + masterIncomingViewingPublicKey, + masterOutgoingViewingPublicKey, + masterTaggingPublicKey, + ]); + + await testContract.methods + .test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey) + .send() + .wait(); + }); }); - describe('key registration flow via PXE', () => { + describe('test keys are fresh: key registration flow, with PXE', () => { const masterNullifierPublicKey: Point = new Point(new Fr(17), new Fr(18)); const masterIncomingViewingPublicKey: Point = new Point(new Fr(19), new Fr(20)); const masterOutgoingViewingPublicKey: Point = new Point(new Fr(21), new Fr(22)); @@ -343,7 +356,7 @@ describe('Key Registry', () => { // We hash the partial address and the public keys hash to get the account address // TODO(#5726): Move the following line to AztecAddress class? - const accountAddedToRegistry = poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1]); + const accountAddedToRegistry = AztecAddress.fromField(poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1])); it('should fail as we have not registered anything to the registry nor have we registered a recipient', async () => { await expect( @@ -351,11 +364,27 @@ describe('Key Registry', () => { .test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey) .send() .wait(), - ).rejects.toThrow(); + ).rejects.toThrow(`Cannot satisfy constraint 'computed_address.eq(address)'`); + }); + + it('should fail when we register bad keys and the lib checks our pxe', async () => { + const randAddress = AztecAddress.random(); + // FIX THIS (#5834) + await pxe.registerRecipient(CompleteAddress.create(randAddress, Point.ZERO, partialAddress), [ + masterNullifierPublicKey, + masterIncomingViewingPublicKey, + masterOutgoingViewingPublicKey, + masterTaggingPublicKey, + ]); + + await expect(testContract.methods + .test_nullifier_key_freshness(randAddress, masterNullifierPublicKey) + .send() + .wait()).rejects.toThrow(`Cannot satisfy constraint 'computed_address.eq(address)'`); }); it('should succeed because we register our recipient manually and the lib checks our pxe', async () => { - // FIX THIS + // FIX THIS (#5834) await pxe.registerRecipient(CompleteAddress.create(accountAddedToRegistry, Point.ZERO, partialAddress), [ masterNullifierPublicKey, masterIncomingViewingPublicKey, @@ -368,6 +397,13 @@ describe('Key Registry', () => { .wait(); }); + it('should fail when we put in a different key', async () => { + await expect(testContract.methods + .test_nullifier_key_freshness(accountAddedToRegistry, masterIncomingViewingPublicKey) + .send() + .wait()).rejects.toThrow(`Cannot satisfy constraint 'keys[key_type].eq(key)'`); + }); + it('Now we add it to registry', async () => { await keyRegistry .withWallet(wallets[0]) @@ -419,7 +455,7 @@ describe('Key Registry', () => { }); describe('key rotation flow; assert keys are fresh', () => { - const newMasterNullifierPublicKey = new Point(new Fr(910), new Fr(1112)); + const newMasterNullifierPublicKey = Point.random(); it('we rotate the nullifier key', async () => { await keyRegistry @@ -435,7 +471,7 @@ describe('Key Registry', () => { .test_nullifier_key_freshness(wallets[0].getAddress(), newMasterNullifierPublicKey) .send() .wait(), - ).rejects.toThrow(); + ).rejects.toThrow(`Cannot satisfy constraint 'hashed_nullifier_public_key == poseidon2_hash(nullifier_public_key_to_test.serialize())`); }); it('checks our registry contract from test contract and succeeds because the change has been applied', async () => { From 9051c8ebaa0410a8a3a07e7c03e0ac2727db617f Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 26 Apr 2024 19:23:58 +0000 Subject: [PATCH 15/93] format --- .../end-to-end/src/e2e_key_registry.test.ts | 89 +++++++++++-------- .../simulator/src/client/view_data_oracle.ts | 1 - 2 files changed, 53 insertions(+), 37 deletions(-) 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 index 6ca01a15d1e..c719e0a0f5c 100644 --- a/yarn-project/end-to-end/src/e2e_key_registry.test.ts +++ b/yarn-project/end-to-end/src/e2e_key_registry.test.ts @@ -59,7 +59,9 @@ describe('Key Registry', () => { // We hash the partial address and the public keys hash to get the account address // TODO(#5726): Move the following line to AztecAddress class? - accountAddedToRegistry = AztecAddress.fromField(poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1])); + accountAddedToRegistry = AztecAddress.fromField( + poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1]), + ); it('should fail registering with mismatched address', async () => { const mismatchedAddress = AztecAddress.random(); @@ -143,7 +145,9 @@ describe('Key Registry', () => { // We hash the partial address and the public keys hash to get the account address // TODO(#5726): Move the following line to AztecAddress class? - accountAddedToRegistry = AztecAddress.fromField(poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1])); + accountAddedToRegistry = AztecAddress.fromField( + poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1]), + ); await keyRegistry .withWallet(wallets[0]) @@ -186,7 +190,7 @@ describe('Key Registry', () => { describe('key rotation flows', () => { const firstNewMasterNullifierPublicKey = Point.random(); - describe('normal key rotation flow', () => { + describe('normal key rotation flow', () => { it('we rotate the nullifier key', async () => { await keyRegistry .withWallet(wallets[0]) @@ -194,72 +198,78 @@ describe('Key Registry', () => { .send() .wait(); }); - + it("checks our registry contract from test contract and finds our old public key because the key rotation hasn't been applied yet", async () => { const { txHash } = await testContract.methods .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) .send() .wait(); - + const rawLogs = await pxe.getUnencryptedLogs({ txHash }); expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(0)); }); - + it('checks our registry contract from test contract and finds the new nullifier public key that has been rotated', async () => { await delay(5); - + const { txHash } = await testContract.methods .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) .send() .wait(); - + const rawLogs = await pxe.getUnencryptedLogs({ txHash }); - - expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(poseidon2Hash(firstNewMasterNullifierPublicKey.toFields())); + + expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual( + poseidon2Hash(firstNewMasterNullifierPublicKey.toFields()), + ); }); }); - + describe('key rotation flow with authwit', () => { // This is the new value const secondNewMasterNullifierPublicKey = Point.random(); - + it('wallet 0 lets wallet 1 call rotate_nullifier_public_key on his behalf with a pre-defined new public key', async () => { const action = keyRegistry .withWallet(wallets[1]) .methods.rotate_nullifier_public_key(wallets[0].getAddress(), secondNewMasterNullifierPublicKey); - + await wallets[0] .setPublicAuthWit({ caller: wallets[1].getCompleteAddress().address, action }, true) .send() .wait(); - + await action.send().wait(); }); - + it("checks our registry contract from test contract and finds our old public key because the key rotation hasn't been applied yet", async () => { const { txHash } = await testContract.methods .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) .send() .wait(); - + const rawLogs = await pxe.getUnencryptedLogs({ txHash }); - expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(poseidon2Hash(firstNewMasterNullifierPublicKey.toFields())); + expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual( + poseidon2Hash(firstNewMasterNullifierPublicKey.toFields()), + ); }); - + it('checks our registry contract from test contract and finds the new nullifier public key that has been rotated', async () => { await delay(5); - + const { txHash } = await testContract.methods .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) .send() .wait(); - + const rawLogs = await pxe.getUnencryptedLogs({ txHash }); - - expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(poseidon2Hash(secondNewMasterNullifierPublicKey.toFields())); + + expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual( + poseidon2Hash(secondNewMasterNullifierPublicKey.toFields()), + ); }); }); - }) + }); describe('test keys are fresh: key registration flow, no PXE', () => { const masterNullifierPublicKey = Point.random(); @@ -278,7 +288,9 @@ describe('Key Registry', () => { // We hash the partial address and the public keys hash to get the account address // TODO(#5726): Move the following line to AztecAddress class? - const accountAddedToRegistry = AztecAddress.fromField(poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1])); + const accountAddedToRegistry = AztecAddress.fromField( + poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1]), + ); it('should fail as we have not registered anything to the registry nor have we registered a recipient', async () => { await expect( @@ -323,7 +335,7 @@ describe('Key Registry', () => { }); it('should succeed even if our pxe gives conflicting information', async () => { - // FIX THIS (#5834) + // FIX THIS (#5834) await pxe.registerRecipient(CompleteAddress.create(accountAddedToRegistry, Point.ZERO, partialAddress), [ new Point(Fr.random(), Fr.random()), masterIncomingViewingPublicKey, @@ -356,7 +368,9 @@ describe('Key Registry', () => { // We hash the partial address and the public keys hash to get the account address // TODO(#5726): Move the following line to AztecAddress class? - const accountAddedToRegistry = AztecAddress.fromField(poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1])); + const accountAddedToRegistry = AztecAddress.fromField( + poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1]), + ); it('should fail as we have not registered anything to the registry nor have we registered a recipient', async () => { await expect( @@ -369,7 +383,7 @@ describe('Key Registry', () => { it('should fail when we register bad keys and the lib checks our pxe', async () => { const randAddress = AztecAddress.random(); - // FIX THIS (#5834) + // FIX THIS (#5834) await pxe.registerRecipient(CompleteAddress.create(randAddress, Point.ZERO, partialAddress), [ masterNullifierPublicKey, masterIncomingViewingPublicKey, @@ -377,10 +391,9 @@ describe('Key Registry', () => { masterTaggingPublicKey, ]); - await expect(testContract.methods - .test_nullifier_key_freshness(randAddress, masterNullifierPublicKey) - .send() - .wait()).rejects.toThrow(`Cannot satisfy constraint 'computed_address.eq(address)'`); + await expect( + testContract.methods.test_nullifier_key_freshness(randAddress, masterNullifierPublicKey).send().wait(), + ).rejects.toThrow(`Cannot satisfy constraint 'computed_address.eq(address)'`); }); it('should succeed because we register our recipient manually and the lib checks our pxe', async () => { @@ -398,10 +411,12 @@ describe('Key Registry', () => { }); it('should fail when we put in a different key', async () => { - await expect(testContract.methods - .test_nullifier_key_freshness(accountAddedToRegistry, masterIncomingViewingPublicKey) - .send() - .wait()).rejects.toThrow(`Cannot satisfy constraint 'keys[key_type].eq(key)'`); + await expect( + testContract.methods + .test_nullifier_key_freshness(accountAddedToRegistry, masterIncomingViewingPublicKey) + .send() + .wait(), + ).rejects.toThrow(`Cannot satisfy constraint 'keys[key_type].eq(key)'`); }); it('Now we add it to registry', async () => { @@ -471,7 +486,9 @@ describe('Key Registry', () => { .test_nullifier_key_freshness(wallets[0].getAddress(), newMasterNullifierPublicKey) .send() .wait(), - ).rejects.toThrow(`Cannot satisfy constraint 'hashed_nullifier_public_key == poseidon2_hash(nullifier_public_key_to_test.serialize())`); + ).rejects.toThrow( + `Cannot satisfy constraint 'hashed_nullifier_public_key == poseidon2_hash(nullifier_public_key_to_test.serialize())`, + ); }); it('checks our registry contract from test contract and succeeds because the change has been applied', async () => { diff --git a/yarn-project/simulator/src/client/view_data_oracle.ts b/yarn-project/simulator/src/client/view_data_oracle.ts index 48c4adc873f..2bc1fbfc937 100644 --- a/yarn-project/simulator/src/client/view_data_oracle.ts +++ b/yarn-project/simulator/src/client/view_data_oracle.ts @@ -166,7 +166,6 @@ export class ViewDataOracle extends TypedOracle { return this.db.popCapsule(); } - /** * Gets public keys for an address, getCompleteAddress should be modified to include this * @param The address to look up From 6e3509acbb06f7644ef839df8ebb545a0b1f61e9 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 26 Apr 2024 19:48:50 +0000 Subject: [PATCH 16/93] test --- yarn-project/end-to-end/src/e2e_key_registry.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index c719e0a0f5c..ce62bc216ff 100644 --- a/yarn-project/end-to-end/src/e2e_key_registry.test.ts +++ b/yarn-project/end-to-end/src/e2e_key_registry.test.ts @@ -487,7 +487,7 @@ describe('Key Registry', () => { .send() .wait(), ).rejects.toThrow( - `Cannot satisfy constraint 'hashed_nullifier_public_key == poseidon2_hash(nullifier_public_key_to_test.serialize())`, + `Cannot satisfy constraint 'hashed_nullifier_public_key_in_registry == poseidon2_hash(nullifier_public_key_to_test.serialize())'`, ); }); From afdd9df08a08b100a395f7820b9ff9251e8029cc Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Mon, 29 Apr 2024 20:16:10 +0000 Subject: [PATCH 17/93] initial --- .../src/keys/assert_public_key_freshness.nr | 38 ++++++++++++++++--- .../aztec-nr/aztec/src/oracle/keys.nr | 21 +++++----- 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr b/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr index dc0915b92e4..54c82e76cd3 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr @@ -48,20 +48,48 @@ pub fn assert_nullifier_public_key_is_fresh( // In the case that the value is not found in the registry we need to manually pass in the address preimage if (hashed_nullifier_public_key_in_registry == 0) { - check_public_key_validity(address, PublicKeyType.NULLIFIER, nullifier_public_key_to_test); + check_public_key_validity(address, PublicKeyType.NULLIFIER, nullifier_public_key_to_test, true); } else { assert(hashed_nullifier_public_key_in_registry == poseidon2_hash(nullifier_public_key_to_test.serialize())); } } -fn check_public_key_validity(address: AztecAddress, key_type: u8, key: GrumpkinPoint) { - let keys = get_public_keys_internal(address); +pub fn get_fresh_nullifier_public_key_hash( + context: &mut PrivateContext, + address: AztecAddress, +) -> Field { + // This is the storage slot of the nullifier_public_key inside the key registry contract + let storage_slot_of_nullifier_public_key = 1; + // We have to derive this slot to get the location of the shared mutable inside the Map + // This should mimic how maps derive their slots + let derived_slot = pedersen_hash( + [storage_slot_of_nullifier_public_key, address.to_field()], + 0 + ); + + // It's a bit wonky because we need to know the delay for get_current_value_in_private to work correctly + // We read from the canonical Key Registry + let registry_private_getter: SharedMutablePrivateGetter = SharedMutablePrivateGetter::new(*context, AztecAddress::from_field(CANONICAL_KEY_REGISTRY_ADDRESS), derived_slot); + let hashed_nullifier_public_key_in_registry = registry_private_getter.get_current_value_in_private(); + + let nullifier_public_key_hash = if hashed_nullifier_public_key_in_registry == 0 { + let keys = get_public_keys_internal(address, false); + poseidon2_hash(keys[PublicKeyType.NULLIFIER].serialize()) + } else { + hashed_nullifier_public_key_in_registry + }; + + nullifier_public_key_hash +} + +fn check_public_key_validity(address: AztecAddress, key_type: u8, key: GrumpkinPoint, check_validity: bool) { + let keys = get_public_keys_internal(address, check_validity); assert(keys[key_type].eq(key)); } -fn get_public_keys_internal(address: AztecAddress) -> [GrumpkinPoint; 4] { - let (_, public_keys) = oracle::keys::get_public_keys_and_partial_address(address); +fn get_public_keys_internal(address: AztecAddress, check_validity: bool) -> [GrumpkinPoint; 4] { + let (_, public_keys) = oracle::keys::get_public_keys_and_partial_address(address, check_validity); public_keys } diff --git a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr index 2a7fd4a41ee..36389f4f418 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr @@ -20,7 +20,7 @@ unconstrained fn get_public_keys_and_partial_address_oracle_wrapper(address: Azt get_public_keys_and_partial_address_oracle(address) } -pub fn get_public_keys_and_partial_address(address: AztecAddress) -> (PartialAddress, [GrumpkinPoint; 4]) { +pub fn get_public_keys_and_partial_address(address: AztecAddress, check_validity: bool) -> (PartialAddress, [GrumpkinPoint; 4]) { let result = get_public_keys_and_partial_address_oracle_wrapper(address); let partial_address = PartialAddress::from_field(result[0]); @@ -29,14 +29,17 @@ pub fn get_public_keys_and_partial_address(address: AztecAddress) -> (PartialAdd let outgoing_pub_key = GrumpkinPoint::new(result[5], result[6]); let tagging_pub_key = GrumpkinPoint::new(result[7], result[8]); - _check_public_key_validity_constrain_oracle( - address, - partial_address, - nullifier_pub_key, - incoming_pub_key, - outgoing_pub_key, - tagging_pub_key, - ); + // check_validity is only used if the address does not exist in the registry, which means that there has been no key rotation + if (check_validity) { + _check_public_key_validity_constrain_oracle( + address, + partial_address, + nullifier_pub_key, + incoming_pub_key, + outgoing_pub_key, + tagging_pub_key, + ); + } (partial_address, [nullifier_pub_key, incoming_pub_key, outgoing_pub_key, tagging_pub_key]) } From 48b0626c45e8ebff9f5016803a43becc950307e0 Mon Sep 17 00:00:00 2001 From: Esau Date: Mon, 29 Apr 2024 22:17:24 +0200 Subject: [PATCH 18/93] initial --- .../aztec/src/context/private_context.nr | 6 +-- .../aztec/src/oracle/nullifier_key.nr | 18 ++++---- .../aztec-nr/value-note/src/value_note.nr | 34 ++++++++------- .../src/subscription_note.nr | 32 +++++++------- .../src/types/token_note.nr | 39 ++++++++--------- .../token_contract/src/types/balances_map.nr | 4 +- .../token_contract/src/types/token_note.nr | 39 ++++++++--------- .../circuit-types/src/keys/key_store.ts | 17 ++++++++ yarn-project/key-store/src/test_key_store.ts | 42 ++++++++++++++++++- .../pxe/src/simulator_oracle/index.ts | 6 +-- .../simulator/src/acvm/oracle/oracle.ts | 4 +- .../simulator/src/client/db_oracle.ts | 4 +- .../simulator/src/client/view_data_oracle.ts | 6 +-- 13 files changed, 160 insertions(+), 91 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index 40fe7613575..1614df4670e 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -212,9 +212,9 @@ impl PrivateContext { self.side_effect_counter = self.side_effect_counter + 1; } - pub fn request_app_nullifier_secret_key(&mut self, account: AztecAddress) -> Field { + pub fn request_app_nullifier_secret_key(&mut self, master_public_nullifying_key_hash: Field) -> Field { let keys = if self.nullifier_key.is_none() { - let keys = get_nullifier_keys(account); + let keys = get_nullifier_keys(master_public_nullifying_key_hash); let request = NullifierKeyValidationRequest { master_nullifier_public_key: keys.master_nullifier_public_key, app_nullifier_secret_key: keys.app_nullifier_secret_key @@ -226,7 +226,7 @@ impl PrivateContext { let keys = self.nullifier_key.unwrap_unchecked(); // If MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL is larger than 1, need to update the way the key pair is cached. assert(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL == 1); - assert(keys.account == account, "Cannot query nullifier key for more than one account per call"); + assert(keys.master_nullifier_public_key_hash == master_public_nullifying_key_hash, "Cannot query nullifier key for more than one master_nullifying_public_key_hash per call"); keys }; keys.app_nullifier_secret_key diff --git a/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr b/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr index 0926fca65e6..69cc8d00f4c 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr @@ -2,27 +2,27 @@ use dep::protocol_types::{address::AztecAddress, grumpkin_point::GrumpkinPoint, // Nullifier keys pertaining to a specific account struct NullifierKeys { - account: AztecAddress, + master_nullifier_public_key_hash: Field, master_nullifier_public_key: GrumpkinPoint, app_nullifier_secret_key: Field, } #[oracle(getNullifierKeys)] -fn get_nullifier_keys_oracle(_account: AztecAddress) -> [Field; 3] {} +fn get_nullifier_keys_oracle(_master_nullifier_public_key_hash: Field) -> [Field; 3] {} -unconstrained fn get_nullifier_keys_internal(account: AztecAddress) -> NullifierKeys { - let result = get_nullifier_keys_oracle(account); +unconstrained fn get_nullifier_keys_internal(master_nullifier_public_key_hash: Field) -> NullifierKeys { + let result = get_nullifier_keys_oracle(master_nullifier_public_key_hash); NullifierKeys { - account, + master_nullifier_public_key_hash, master_nullifier_public_key: GrumpkinPoint { x: result[0], y: result[1] }, app_nullifier_secret_key: result[2], } } -pub fn get_nullifier_keys(account: AztecAddress) -> NullifierKeys { - get_nullifier_keys_internal(account) +pub fn get_nullifier_keys(master_nullifier_public_key_hash: Field) -> NullifierKeys { + get_nullifier_keys_internal(master_nullifier_public_key_hash) } -pub fn get_app_nullifier_secret_key(account: AztecAddress) -> Field { - get_nullifier_keys_internal(account).app_nullifier_secret_key +pub fn get_app_nullifier_secret_key(master_nullifier_public_key_hash: Field) -> Field { + get_nullifier_keys_internal(master_nullifier_public_key_hash).app_nullifier_secret_key } diff --git a/noir-projects/aztec-nr/value-note/src/value_note.nr b/noir-projects/aztec-nr/value-note/src/value_note.nr index b67cd8a98dc..3190baa13a1 100644 --- a/noir-projects/aztec-nr/value-note/src/value_note.nr +++ b/noir-projects/aztec-nr/value-note/src/value_note.nr @@ -14,7 +14,10 @@ global VALUE_NOTE_LEN: Field = 3; // 3 plus a header. #[aztec(note)] struct ValueNote { value: Field, - owner: AztecAddress, + // the nullifying public key of the person who owns the note. The owner (recipient) to ensure that the note + // can be privately spent. When nullifier secret and encryption private key is same + // we can simply use the owner for this one. + owner_nullifying_public_key_hash: Field, randomness: Field, } // docs:end:value-note-def @@ -24,7 +27,7 @@ impl NoteInterface for ValueNote { fn compute_nullifier(self, context: &mut PrivateContext) -> Field { let note_hash_for_nullify = compute_note_hash_for_consumption(self); - let secret = context.request_app_nullifier_secret_key(self.owner); + let secret = context.request_app_nullifier_secret_key(self.owner_nullifying_public_key_hash); poseidon2_hash([ note_hash_for_nullify, secret, @@ -36,7 +39,7 @@ impl NoteInterface for ValueNote { fn compute_nullifier_without_context(self) -> Field { let note_hash_for_nullify = compute_note_hash_for_consumption(self); - let secret = get_app_nullifier_secret_key(self.owner); + let secret = get_app_nullifier_secret_key(self.owner_nullifying_public_key_hash); poseidon2_hash([ note_hash_for_nullify, secret, @@ -46,23 +49,24 @@ impl NoteInterface for ValueNote { // Broadcasts the note as an encrypted log on L1. fn broadcast(self, context: &mut PrivateContext, slot: Field) { - let encryption_pub_key = get_public_key(self.owner); - emit_encrypted_log( - context, - (*context).this_address(), - slot, - Self::get_note_type_id(), - encryption_pub_key, - self.serialize_content(), - ); + // TODO (ek): Disabled this until we fix the emit log types + // let encryption_pub_key = get_public_key(self.owner_nullifying_public_key_hash); + // emit_encrypted_log( + // context, + // (*context).this_address(), + // slot, + // Self::get_note_type_id(), + // encryption_pub_key, + // self.serialize_content(), + // ); } } impl ValueNote { - pub fn new(value: Field, owner: AztecAddress) -> Self { + pub fn new(value: Field, owner_nullifying_public_key_hash: Field) -> Self { let randomness = unsafe_rand(); let header = NoteHeader::empty(); - ValueNote { value, owner, randomness, header } + ValueNote { value, randomness, owner_nullifying_public_key_hash, header } } } @@ -70,6 +74,6 @@ impl Serialize<7> for ValueNote { fn serialize(self) -> [Field; 7] { let header = self.header.serialize(); - [self.value, self.owner.to_field(), self.randomness, header[0], header[1], header[2], header[3]] + [self.value, self.owner_nullifying_public_key_hash, self.randomness, header[0], header[1], header[2], header[3]] } } diff --git a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/subscription_note.nr b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/subscription_note.nr index 435f61191b3..8e3afe180bd 100644 --- a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/subscription_note.nr +++ b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/subscription_note.nr @@ -11,15 +11,18 @@ global SUBSCRIPTION_NOTE_LEN: Field = 3; // TODO: Do we need to include a nonce, in case we want to read/nullify/recreate with the same pubkey value? #[aztec(note)] struct SubscriptionNote { - owner: AztecAddress, expiry_block_number: Field, remaining_txs: Field, + // the nullifying public key of the person who owns the note. The owner (recipient) to ensure that the note + // can be privately spent. When nullifier secret and encryption private key is same + // we can simply use the owner for this one. + owner_nullifying_public_key_hash: Field, } impl NoteInterface for SubscriptionNote { fn compute_nullifier(self, context: &mut PrivateContext) -> Field { let note_hash_for_nullify = compute_note_hash_for_consumption(self); - let secret = context.request_app_nullifier_secret_key(self.owner); + let secret = context.request_app_nullifier_secret_key(self.owner_nullifying_public_key_hash); poseidon2_hash([ note_hash_for_nullify, secret, @@ -29,7 +32,7 @@ impl NoteInterface for SubscriptionNote { fn compute_nullifier_without_context(self) -> Field { let note_hash_for_nullify = compute_note_hash_for_consumption(self); - let secret = get_app_nullifier_secret_key(self.owner); + let secret = get_app_nullifier_secret_key(self.owner_nullifying_public_key_hash); poseidon2_hash([ note_hash_for_nullify, secret, @@ -39,20 +42,21 @@ impl NoteInterface for SubscriptionNote { // Broadcasts the note as an encrypted log on L1. fn broadcast(self, context: &mut PrivateContext, slot: Field) { - let encryption_pub_key = get_public_key(self.owner); - emit_encrypted_log( - context, - (*context).this_address(), - slot, - Self::get_note_type_id(), - encryption_pub_key, - self.serialize_content(), - ); + // TODO (ek): Disabled this until we fix the emit log types + // let encryption_pub_key = get_public_key(self.owner_nullifying_public_key_hash); + // emit_encrypted_log( + // context, + // (*context).this_address(), + // slot, + // Self::get_note_type_id(), + // encryption_pub_key, + // self.serialize_content(), + // ); } } impl SubscriptionNote { - pub fn new(owner: AztecAddress, expiry_block_number: Field, remaining_txs: Field) -> Self { - SubscriptionNote { owner, expiry_block_number, remaining_txs, header: NoteHeader::empty() } + pub fn new(expiry_block_number: Field, remaining_txs: Field, owner_nullifying_public_key_hash: Field) -> Self { + SubscriptionNote { expiry_block_number, remaining_txs, owner_nullifying_public_key_hash, header: NoteHeader::empty() } } } diff --git a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr index 5f6edf94d5f..f37b35c7c83 100644 --- a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr +++ b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr @@ -6,9 +6,9 @@ use dep::aztec::{ }; trait OwnedNote { - fn new(amount: U128, owner: AztecAddress) -> Self; + fn new(amount: U128, owner_nullifying_public_key_hash: Field) -> Self; fn get_amount(self) -> U128; - fn get_owner(self) -> AztecAddress; + fn get_owner_nullifying_public_key_hash(self) -> Field; } global TOKEN_NOTE_LEN: Field = 3; // 3 plus a header. @@ -17,10 +17,10 @@ global TOKEN_NOTE_LEN: Field = 3; // 3 plus a header. struct TokenNote { // the amount of tokens in the note amount: U128, - // the provider of secrets for the nullifier. The owner (recipient) to ensure that the note + // the nullifying public key of the person who owns the note. The owner (recipient) to ensure that the note // can be privately spent. When nullifier secret and encryption private key is same // we can simply use the owner for this one. - owner: AztecAddress, + owner_nullifying_public_key_hash: Field, // randomness of the note to hide contents. randomness: Field, } @@ -29,7 +29,7 @@ impl NoteInterface for TokenNote { // docs:start:nullifier fn compute_nullifier(self, context: &mut PrivateContext) -> Field { let note_hash_for_nullify = compute_note_hash_for_consumption(self); - let secret = context.request_app_nullifier_secret_key(self.owner); + let secret = context.request_app_nullifier_secret_key(self.owner_nullifying_public_key_hash); poseidon2_hash([ note_hash_for_nullify, secret, @@ -40,7 +40,7 @@ impl NoteInterface for TokenNote { fn compute_nullifier_without_context(self) -> Field { let note_hash_for_nullify = compute_note_hash_for_consumption(self); - let secret = get_app_nullifier_secret_key(self.owner); + let secret = get_app_nullifier_secret_key(self.owner_nullifying_public_key_hash); poseidon2_hash([ note_hash_for_nullify, secret, @@ -52,24 +52,25 @@ impl NoteInterface for TokenNote { fn broadcast(self, context: &mut PrivateContext, slot: Field) { // We only bother inserting the note if non-empty to save funds on gas. if !(self.amount == U128::from_integer(0)) { - let encryption_pub_key = get_public_key(self.owner); - emit_encrypted_log( - context, - (*context).this_address(), - slot, - Self::get_note_type_id(), - encryption_pub_key, - self.serialize_content(), - ); + // TODO (ek): Disabled this until we fix the emit log types + // let encryption_pub_key = get_public_key(self.owner_nullifying_public_key_hash); + // emit_encrypted_log( + // context, + // (*context).this_address(), + // slot, + // Self::get_note_type_id(), + // encryption_pub_key, + // self.serialize_content(), + // ); } } } impl OwnedNote for TokenNote { - fn new(amount: U128, owner: AztecAddress) -> Self { + fn new(amount: U128, owner_nullifying_public_key_hash: Field) -> Self { Self { amount, - owner, + owner_nullifying_public_key_hash, randomness: unsafe_rand(), header: NoteHeader::empty(), } @@ -79,7 +80,7 @@ impl OwnedNote for TokenNote { self.amount } - fn get_owner(self) -> AztecAddress { - self.owner + fn get_owner_nullifying_public_key_hash(self) -> Field { + self.owner_nullifying_public_key_hash } } diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr index 0a71bd9891e..605d5a5a647 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr @@ -60,7 +60,9 @@ impl BalancesMap { owner: AztecAddress, addend: U128 ) where T: NoteInterface + OwnedNote { - let mut addend_note = T::new(addend, owner); + // Lookup in registry + let nullifier_public_key_hash = 0; + let mut addend_note = T::new(addend, nullifier_public_key_hash); // docs:start:insert self.map.at(owner).insert(&mut addend_note, true); diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr index 5f6edf94d5f..f37b35c7c83 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr @@ -6,9 +6,9 @@ use dep::aztec::{ }; trait OwnedNote { - fn new(amount: U128, owner: AztecAddress) -> Self; + fn new(amount: U128, owner_nullifying_public_key_hash: Field) -> Self; fn get_amount(self) -> U128; - fn get_owner(self) -> AztecAddress; + fn get_owner_nullifying_public_key_hash(self) -> Field; } global TOKEN_NOTE_LEN: Field = 3; // 3 plus a header. @@ -17,10 +17,10 @@ global TOKEN_NOTE_LEN: Field = 3; // 3 plus a header. struct TokenNote { // the amount of tokens in the note amount: U128, - // the provider of secrets for the nullifier. The owner (recipient) to ensure that the note + // the nullifying public key of the person who owns the note. The owner (recipient) to ensure that the note // can be privately spent. When nullifier secret and encryption private key is same // we can simply use the owner for this one. - owner: AztecAddress, + owner_nullifying_public_key_hash: Field, // randomness of the note to hide contents. randomness: Field, } @@ -29,7 +29,7 @@ impl NoteInterface for TokenNote { // docs:start:nullifier fn compute_nullifier(self, context: &mut PrivateContext) -> Field { let note_hash_for_nullify = compute_note_hash_for_consumption(self); - let secret = context.request_app_nullifier_secret_key(self.owner); + let secret = context.request_app_nullifier_secret_key(self.owner_nullifying_public_key_hash); poseidon2_hash([ note_hash_for_nullify, secret, @@ -40,7 +40,7 @@ impl NoteInterface for TokenNote { fn compute_nullifier_without_context(self) -> Field { let note_hash_for_nullify = compute_note_hash_for_consumption(self); - let secret = get_app_nullifier_secret_key(self.owner); + let secret = get_app_nullifier_secret_key(self.owner_nullifying_public_key_hash); poseidon2_hash([ note_hash_for_nullify, secret, @@ -52,24 +52,25 @@ impl NoteInterface for TokenNote { fn broadcast(self, context: &mut PrivateContext, slot: Field) { // We only bother inserting the note if non-empty to save funds on gas. if !(self.amount == U128::from_integer(0)) { - let encryption_pub_key = get_public_key(self.owner); - emit_encrypted_log( - context, - (*context).this_address(), - slot, - Self::get_note_type_id(), - encryption_pub_key, - self.serialize_content(), - ); + // TODO (ek): Disabled this until we fix the emit log types + // let encryption_pub_key = get_public_key(self.owner_nullifying_public_key_hash); + // emit_encrypted_log( + // context, + // (*context).this_address(), + // slot, + // Self::get_note_type_id(), + // encryption_pub_key, + // self.serialize_content(), + // ); } } } impl OwnedNote for TokenNote { - fn new(amount: U128, owner: AztecAddress) -> Self { + fn new(amount: U128, owner_nullifying_public_key_hash: Field) -> Self { Self { amount, - owner, + owner_nullifying_public_key_hash, randomness: unsafe_rand(), header: NoteHeader::empty(), } @@ -79,7 +80,7 @@ impl OwnedNote for TokenNote { self.amount } - fn get_owner(self) -> AztecAddress { - self.owner + fn get_owner_nullifying_public_key_hash(self) -> Field { + self.owner_nullifying_public_key_hash } } diff --git a/yarn-project/circuit-types/src/keys/key_store.ts b/yarn-project/circuit-types/src/keys/key_store.ts index dd77bde64ed..2ce244d91ab 100644 --- a/yarn-project/circuit-types/src/keys/key_store.ts +++ b/yarn-project/circuit-types/src/keys/key_store.ts @@ -31,6 +31,14 @@ export interface KeyStore { */ getAccounts(): Promise; + /** + * Gets the master nullifier public key for a given master nullifier public key hash. + * @throws If the master nullifier public key hash does not exist in the key store. + * @param masterNullifierPublicKeyHash - The master nullifier public key hash for which to retrieve the master nullifier public key. + * @returns The master nullifier public key for the account. + */ + getMasterNullifierPublicKeyWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr): Promise; + /** * Gets the master nullifier public key for a given account. * @throws If the account does not exist in the key store. @@ -72,6 +80,15 @@ export interface KeyStore { */ getAppNullifierSecretKey(account: AztecAddress, app: AztecAddress): Promise; + /** + * Retrieves application nullifier secret key. + * @throws If the masterNullifierPublicKeyHash does not exist in the key store. + * @param masterNullifierPublicKeyHash - The account to retrieve the application nullifier secret key for. + * @param app - The application address to retrieve the nullifier secret key for. + * @returns A Promise that resolves to the application nullifier secret key. + */ + getAppNullifierSecretKeyWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr, app: AztecAddress): Promise; + /** * Retrieves application incoming viewing secret key. * @throws If the account does not exist in the key store. diff --git a/yarn-project/key-store/src/test_key_store.ts b/yarn-project/key-store/src/test_key_store.ts index 288ffc9430d..708dcae15a0 100644 --- a/yarn-project/key-store/src/test_key_store.ts +++ b/yarn-project/key-store/src/test_key_store.ts @@ -58,7 +58,7 @@ export class TestKeyStore implements KeyStore { const accountAddressFr = poseidon2Hash([publicKeysHash, partialAddress, GeneratorIndex.CONTRACT_ADDRESS_V1]); const accountAddress = AztecAddress.fromField(accountAddressFr); - // We save the keys to db + // We save the keys to db associated with the account address await this.#keys.set(`${accountAddress.toString()}-public_keys_hash`, publicKeysHash.toBuffer()); await this.#keys.set(`${accountAddress.toString()}-nsk_m`, masterNullifierSecretKey.toBuffer()); @@ -71,6 +71,11 @@ export class TestKeyStore implements KeyStore { await this.#keys.set(`${accountAddress.toString()}-ovpk_m`, masterOutgoingViewingPublicKey.toBuffer()); await this.#keys.set(`${accountAddress.toString()}-tpk_m`, masterTaggingPublicKey.toBuffer()); + const masterNullifierPublicKeyHash = poseidon2Hash(masterNullifierPublicKey.toFields()); + // We save nullifier keys to db under the master nullifier key hash + await this.#keys.set(`${masterNullifierPublicKeyHash.toString()}-nsk_m`, masterNullifierSecretKey.toBuffer()); + await this.#keys.set(`${masterNullifierPublicKeyHash.toString()}-npk_m`, masterNullifierPublicKey.toBuffer()); + // At last, we return the newly derived account address return Promise.resolve(accountAddress); } @@ -102,6 +107,22 @@ export class TestKeyStore implements KeyStore { return Promise.resolve(Point.fromBuffer(masterNullifierPublicKeyBuffer)); } + /** + * Gets the master nullifier public key for a given master nullifier public key hash. + * @throws If the master nullifier public key hash does not exist in the key store. + * @param masterNullifierPublicKeyHash - The master nullifier public key hash for which to retrieve the master nullifier public key. + * @returns The master nullifier public key for the account. + */ + getMasterNullifierPublicKeyWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr): Promise { + const masterNullifierPublicKeyBuffer = this.#keys.get(`${masterNullifierPublicKeyHash.toString()}-npk_m`); + if (!masterNullifierPublicKeyBuffer) { + throw new Error( + `Master nullifier public keys hash ${masterNullifierPublicKeyHash.toString()} does not exist.`, + ); + } + return Promise.resolve(Point.fromBuffer(masterNullifierPublicKeyBuffer)); + } + /** * Gets the master incoming viewing public key for a given account. * @throws If the account does not exist in the key store. @@ -169,6 +190,25 @@ export class TestKeyStore implements KeyStore { return Promise.resolve(appNullifierSecretKey); } +/** + * Retrieves application nullifier secret key. + * @throws If the masterNullifierPublicKeyHash does not exist in the key store. + * @param masterNullifierPublicKeyHash - The account to retrieve the application nullifier secret key for. + * @param app - The application address to retrieve the nullifier secret key for. + * @returns A Promise that resolves to the application nullifier secret key. + */ + getAppNullifierSecretKeyWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr, app: AztecAddress): Promise { + const masterNullifierSecretKeyBuffer = this.#keys.get(`${masterNullifierPublicKeyHash.toString()}-nsk_m`); + if (!masterNullifierSecretKeyBuffer) { + throw new Error( + `Master nullifier public keys hash ${masterNullifierPublicKeyHash.toString()} does not exist.`, + ); + } + const masterNullifierSecretKey = GrumpkinScalar.fromBuffer(masterNullifierSecretKeyBuffer); + const appNullifierSecretKey = computeAppNullifierSecretKey(masterNullifierSecretKey, app); + return Promise.resolve(appNullifierSecretKey); + } + /** * Retrieves application incoming viewing secret key. * @throws If the account does not exist in the key store. diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index 0a81cc5b1d6..ec3f317fddf 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -38,9 +38,9 @@ export class SimulatorOracle implements DBOracle { private log = createDebugLogger('aztec:pxe:simulator_oracle'), ) {} - async getNullifierKeys(accountAddress: AztecAddress, contractAddress: AztecAddress): Promise { - const masterNullifierPublicKey = await this.keyStore.getMasterNullifierPublicKey(accountAddress); - const appNullifierSecretKey = await this.keyStore.getAppNullifierSecretKey(accountAddress, contractAddress); + async getNullifierKeys(masterNullifierPublicKeyHash: AztecAddress, contractAddress: AztecAddress): Promise { + const masterNullifierPublicKey = await this.keyStore.getMasterNullifierPublicKeyWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash); + const appNullifierSecretKey = await this.keyStore.getAppNullifierSecretKeyWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash, contractAddress); return { masterNullifierPublicKey, appNullifierSecretKey }; } diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index 625830ba973..ee3bb211e04 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -42,9 +42,9 @@ export class Oracle { return unpacked.map(toACVMField); } - async getNullifierKeys([accountAddress]: ACVMField[]): Promise { + async getNullifierKeys([masterNullifierPublicKeyHash]: ACVMField[]): Promise { const { masterNullifierPublicKey, appNullifierSecretKey } = await this.typedOracle.getNullifierKeys( - fromACVMField(accountAddress), + fromACVMField(masterNullifierPublicKeyHash), ); return [ toACVMField(masterNullifierPublicKey.x), diff --git a/yarn-project/simulator/src/client/db_oracle.ts b/yarn-project/simulator/src/client/db_oracle.ts index 2646898a612..c8ec5a6d02a 100644 --- a/yarn-project/simulator/src/client/db_oracle.ts +++ b/yarn-project/simulator/src/client/db_oracle.ts @@ -75,12 +75,12 @@ export interface DBOracle extends CommitmentsDB { /** * Retrieve nullifier keys associated with a specific account and app/contract address. * - * @param accountAddress - The account address. + * @param masterNullifierPublicKeyHash - The master nullifer public key hash. * @param contractAddress - The contract address. * @returns A Promise that resolves to nullifier keys of a requested account and contract. * @throws An error if the account is not registered in the database. */ - getNullifierKeys(accountAddress: AztecAddress, contractAddress: AztecAddress): Promise; + getNullifierKeys(masterNullifierPublicKeyHash: Fr, contractAddress: AztecAddress): Promise; /** * Retrieves a set of notes stored in the database for a given contract address and storage slot. diff --git a/yarn-project/simulator/src/client/view_data_oracle.ts b/yarn-project/simulator/src/client/view_data_oracle.ts index 2bc1fbfc937..4222e794dd9 100644 --- a/yarn-project/simulator/src/client/view_data_oracle.ts +++ b/yarn-project/simulator/src/client/view_data_oracle.ts @@ -37,12 +37,12 @@ export class ViewDataOracle extends TypedOracle { /** * Retrieve nullifier keys associated with a specific account and app/contract address. * - * @param accountAddress - The account address. + * @param masterNullifierPublicKeyHash - The master nullifer public key hash. * @returns A Promise that resolves to nullifier keys of a requested account and contract. * @throws An error if the account is not registered in the database. */ - public override getNullifierKeys(account: AztecAddress): Promise { - return this.db.getNullifierKeys(account, this.contractAddress); + public override getNullifierKeys(masterNullifierPublicKeyHash: Fr): Promise { + return this.db.getNullifierKeys(masterNullifierPublicKeyHash, this.contractAddress); } /** From 0ca8578b0713e104555103eccb87cb9aa3276b91 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Wed, 1 May 2024 12:00:42 +0000 Subject: [PATCH 19/93] Addressing comments --- noir-projects/aztec-nr/aztec/src/keys.nr | 4 +- .../src/keys/assert_public_key_freshness.nr | 67 ------ .../aztec-nr/aztec/src/keys/getters.nr | 55 +++++ .../aztec-nr/aztec/src/oracle/keys.nr | 53 +---- .../aztec-nr/aztec/src/state_vars/map.nr | 6 +- .../key_registry_contract/src/main.nr | 34 +-- .../contracts/test_contract/src/main.nr | 28 ++- .../crates/types/src/address/aztec_address.nr | 19 ++ .../types/src/address/public_keys_hash.nr | 27 ++- .../circuit-types/src/keys/key_store.ts | 1 + .../end-to-end/jest.integration.config.json | 2 +- .../end-to-end/src/e2e_key_registry.test.ts | 221 +++++++----------- .../end-to-end/src/e2e_state_vars.test.ts | 18 +- yarn-project/key-store/src/test_key_store.ts | 1 + yarn-project/package.common.json | 2 +- .../simulator/src/acvm/oracle/oracle.ts | 7 +- 16 files changed, 237 insertions(+), 308 deletions(-) delete mode 100644 noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr create mode 100644 noir-projects/aztec-nr/aztec/src/keys/getters.nr diff --git a/noir-projects/aztec-nr/aztec/src/keys.nr b/noir-projects/aztec-nr/aztec/src/keys.nr index 427d30ba671..25249687e3c 100644 --- a/noir-projects/aztec-nr/aztec/src/keys.nr +++ b/noir-projects/aztec-nr/aztec/src/keys.nr @@ -1,3 +1,3 @@ -mod assert_public_key_freshness; +mod getters; -use crate::keys::assert_public_key_freshness::assert_nullifier_public_key_is_fresh; +use crate::keys::getters::get_fresh_nullifier_public_key_hash; diff --git a/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr b/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr deleted file mode 100644 index dc0915b92e4..00000000000 --- a/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr +++ /dev/null @@ -1,67 +0,0 @@ -use dep::protocol_types::{ - address::{ - AztecAddress, - PartialAddress - }, - constants::{ - GENERATOR_INDEX__PUBLIC_KEYS_HASH, - GENERATOR_INDEX__CONTRACT_ADDRESS_V1, - CANONICAL_KEY_REGISTRY_ADDRESS - }, - grumpkin_point::GrumpkinPoint, -}; - -use crate::context::PrivateContext; -use crate::hash::{ - pedersen_hash, - poseidon2_hash, -}; -use crate::oracle; -use crate::state_vars::shared_mutable::shared_mutable_private_getter::SharedMutablePrivateGetter; - -struct PublicKeyTypeEnum { - NULLIFIER: u8, -} - -global PublicKeyType = PublicKeyTypeEnum { - NULLIFIER: 0, -}; - -pub fn assert_nullifier_public_key_is_fresh( - context: &mut PrivateContext, - address: AztecAddress, - nullifier_public_key_to_test: GrumpkinPoint, -) { - // This is the storage slot of the nullifier_public_key inside the key registry contract - let storage_slot_of_nullifier_public_key = 1; - // We have to derive this slot to get the location of the shared mutable inside the Map - // This should mimic how maps derive their slots - let derived_slot = pedersen_hash( - [storage_slot_of_nullifier_public_key, address.to_field()], - 0 - ); - - // It's a bit wonky because we need to know the delay for get_current_value_in_private to work correctly - // We read from the canonical Key Registry - let registry_private_getter: SharedMutablePrivateGetter = SharedMutablePrivateGetter::new(*context, AztecAddress::from_field(CANONICAL_KEY_REGISTRY_ADDRESS), derived_slot); - let hashed_nullifier_public_key_in_registry = registry_private_getter.get_current_value_in_private(); - - // In the case that the value is not found in the registry we need to manually pass in the address preimage - if (hashed_nullifier_public_key_in_registry == 0) { - check_public_key_validity(address, PublicKeyType.NULLIFIER, nullifier_public_key_to_test); - } else { - assert(hashed_nullifier_public_key_in_registry == poseidon2_hash(nullifier_public_key_to_test.serialize())); - } -} - -fn check_public_key_validity(address: AztecAddress, key_type: u8, key: GrumpkinPoint) { - let keys = get_public_keys_internal(address); - - assert(keys[key_type].eq(key)); -} - -fn get_public_keys_internal(address: AztecAddress) -> [GrumpkinPoint; 4] { - let (_, public_keys) = oracle::keys::get_public_keys_and_partial_address(address); - - public_keys -} diff --git a/noir-projects/aztec-nr/aztec/src/keys/getters.nr b/noir-projects/aztec-nr/aztec/src/keys/getters.nr new file mode 100644 index 00000000000..321441e7a7e --- /dev/null +++ b/noir-projects/aztec-nr/aztec/src/keys/getters.nr @@ -0,0 +1,55 @@ +use dep::protocol_types::{ + address::{ + AztecAddress, + PartialAddress + }, + constants::{ + GENERATOR_INDEX__PUBLIC_KEYS_HASH, + GENERATOR_INDEX__CONTRACT_ADDRESS_V1, + CANONICAL_KEY_REGISTRY_ADDRESS + }, + grumpkin_point::GrumpkinPoint, +}; + +use crate::context::PrivateContext; +use crate::hash::{ + pedersen_hash, + poseidon2_hash, +}; +use crate::oracle; +use crate::state_vars::{ + map::derive_storage_slot_in_map, + shared_mutable::shared_mutable_private_getter::SharedMutablePrivateGetter, +}; + +struct PublicKeyTypeEnum { + NULLIFIER: u8, +} + +global PublicKeyType = PublicKeyTypeEnum { + NULLIFIER: 0, +}; + +pub fn get_fresh_nullifier_public_key_hash( + context: &mut PrivateContext, + address: AztecAddress, +) -> Field { + // This is the storage slot of the nullifier_public_key inside the key registry contract + let storage_slot_of_nullifier_public_key = 1; + + let derived_slot = derive_storage_slot_in_map(storage_slot_of_nullifier_public_key, address); + + // It's a bit wonky because we need to know the delay for get_current_value_in_private to work correctly + // We read from the canonical Key Registry + let registry_private_getter: SharedMutablePrivateGetter = SharedMutablePrivateGetter::new(*context, AztecAddress::from_field(CANONICAL_KEY_REGISTRY_ADDRESS), derived_slot); + let nullifier_public_key_hash_in_registry = registry_private_getter.get_current_value_in_private(); + + let nullifier_public_key_hash = if nullifier_public_key_hash_in_registry == 0 { + let keys = oracle::keys::get_public_keys(address); + poseidon2_hash(keys[PublicKeyType.NULLIFIER].serialize()) + } else { + nullifier_public_key_hash_in_registry + }; + + nullifier_public_key_hash +} diff --git a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr index 2a7fd4a41ee..98ea76ed617 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr @@ -20,57 +20,24 @@ unconstrained fn get_public_keys_and_partial_address_oracle_wrapper(address: Azt get_public_keys_and_partial_address_oracle(address) } -pub fn get_public_keys_and_partial_address(address: AztecAddress) -> (PartialAddress, [GrumpkinPoint; 4]) { +pub fn get_public_keys(address: AztecAddress) -> [GrumpkinPoint; 4] { let result = get_public_keys_and_partial_address_oracle_wrapper(address); - let partial_address = PartialAddress::from_field(result[0]); - let nullifier_pub_key = GrumpkinPoint::new(result[1], result[2]); - let incoming_pub_key = GrumpkinPoint::new(result[3], result[4]); - let outgoing_pub_key = GrumpkinPoint::new(result[5], result[6]); - let tagging_pub_key = GrumpkinPoint::new(result[7], result[8]); + let nullifier_pub_key = GrumpkinPoint::new(result[0], result[1]); + let incoming_pub_key = GrumpkinPoint::new(result[2], result[3]); + let outgoing_pub_key = GrumpkinPoint::new(result[4], result[5]); + let tagging_pub_key = GrumpkinPoint::new(result[6], result[7]); + let partial_address = PartialAddress::from_field(result[8]); - _check_public_key_validity_constrain_oracle( - address, - partial_address, + let computed_address = AztecAddress::compute_from_public_keys_and_partial_address( nullifier_pub_key, incoming_pub_key, outgoing_pub_key, tagging_pub_key, - ); - - (partial_address, [nullifier_pub_key, incoming_pub_key, outgoing_pub_key, tagging_pub_key]) -} - -fn _check_public_key_validity_constrain_oracle( - address: AztecAddress, - partial_address: PartialAddress, - nullifier_public_key: GrumpkinPoint, - incoming_public_key: GrumpkinPoint, - outgoing_public_key: GrumpkinPoint, - tagging_public_key: GrumpkinPoint - ) { - let public_keys_hash = poseidon2_hash([ - nullifier_public_key.serialize()[0], - nullifier_public_key.serialize()[1], - incoming_public_key.serialize()[0], - incoming_public_key.serialize()[1], - outgoing_public_key.serialize()[0], - outgoing_public_key.serialize()[1], - tagging_public_key.serialize()[0], - tagging_public_key.serialize()[1], - GENERATOR_INDEX__PUBLIC_KEYS_HASH, - ]); - -// TODO: #5830: we can compute this like below once refactored -// let calculated_address = AztecAddress::compute(PublicKeysHash::compute(pub_key), partial_address); - - let computed_address = AztecAddress::from_field( - poseidon2_hash([ - partial_address.to_field(), - public_keys_hash.to_field(), - GENERATOR_INDEX__CONTRACT_ADDRESS_V1, - ]) + partial_address, ); assert(computed_address.eq(address)); + + [nullifier_pub_key, incoming_pub_key, outgoing_pub_key, tagging_pub_key] } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/map.nr b/noir-projects/aztec-nr/aztec/src/state_vars/map.nr index a138a8deb9c..c075578db3f 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/map.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/map.nr @@ -27,10 +27,14 @@ impl Map { // docs:start:at pub fn at(self, key: K) -> V where K: ToField { // TODO(#1204): use a generator index for the storage slot - let derived_storage_slot = pedersen_hash([self.storage_slot, key.to_field()], 0); + let derived_storage_slot = derive_storage_slot_in_map(self.storage_slot, key); let state_var_constructor = self.state_var_constructor; state_var_constructor(self.context, derived_storage_slot) } // docs:end:at } + +pub fn derive_storage_slot_in_map(storage_slot: Field, key: K) -> Field where K: ToField { + pedersen_hash([storage_slot, key.to_field()], 0) +} 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 index 6124253c417..9d25af0055e 100644 --- a/noir-projects/noir-contracts/contracts/key_registry_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/key_registry_contract/src/main.nr @@ -25,9 +25,12 @@ contract KeyRegistry { #[aztec(storage)] struct Storage { + //! This should stay at storage slot 1. If you change this, make sure you change the hardcoded value in keys/assert_public_key_freshness. + //! We use this hardcoded storage slot with derive_storage_slot_in_map and the SharedMutablePrivateGetter to directly read the value at an address in this contract. + nullifier_public_key_hash_registry: Map>, + // We are not supporting rotating / changing keys other than the nullifier public in the registry at the moment, but will in the future. // Uncomment lines below to enable that functionality - nullifier_public_key_hash_registry: Map>, // incoming_public_key_registry: Map>, // outgoing_public_key_registry: Map>, // tagging_public_key_registry: Map>, @@ -70,30 +73,13 @@ contract KeyRegistry { "All public keys must be non-zero" ); - // TODO (ek): Do it below after refactoring all public_keys_hash_elemtns - // let public_keys_hash = PublicKeysHash::compute(nullifier_public_key, tagging_public_key, incoming_public_key, outgoing_public_key); - // let address = AztecAddress::compute(public_keys_hash, partial_address); // We could also pass in original_public_keys_hash instead of computing it here, if all we need the original one is for being able to prove ownership of address - let public_keys_hash = poseidon2_hash([ - nullifier_public_key.serialize()[0], - nullifier_public_key.serialize()[1], - incoming_public_key.serialize()[0], - incoming_public_key.serialize()[1], - outgoing_public_key.serialize()[0], - outgoing_public_key.serialize()[1], - tagging_public_key.serialize()[0], - tagging_public_key.serialize()[1], - GENERATOR_INDEX__PUBLIC_KEYS_HASH, - ] - ); - - let computed_address = AztecAddress::from_field( - poseidon2_hash([ - partial_address.to_field(), - public_keys_hash.to_field(), - GENERATOR_INDEX__CONTRACT_ADDRESS_V1 as Field, - ] - ) + let computed_address = AztecAddress::compute_from_public_keys_and_partial_address( + nullifier_public_key, + incoming_public_key, + outgoing_public_key, + tagging_public_key, + partial_address, ); assert(computed_address.eq(address), "Computed address does not match supplied address"); 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 e84e4b4e596..7349bb9c2c5 100644 --- a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr @@ -10,18 +10,18 @@ contract Test { use dep::aztec::protocol_types::{ abis::private_circuit_public_inputs::PrivateCircuitPublicInputs, - constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, traits::Serialize, + constants::{MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, CANONICAL_KEY_REGISTRY_ADDRESS}, traits::Serialize, grumpkin_point::GrumpkinPoint }; use dep::aztec::note::constants::MAX_NOTES_PER_PAGE; - use dep::aztec::state_vars::shared_mutable::SharedMutablePrivateGetter; + use dep::aztec::state_vars::{shared_mutable::SharedMutablePrivateGetter, map::derive_storage_slot_in_map}; use dep::aztec::{ - keys::assert_public_key_freshness::assert_nullifier_public_key_is_fresh, + keys::getters::get_fresh_nullifier_public_key_hash, context::{Context, inputs::private_context_inputs::PrivateContextInputs}, - hash::{pedersen_hash, compute_secret_hash, ArgsHasher}, + hash::{pedersen_hash, poseidon2_hash, compute_secret_hash, ArgsHasher}, note::{ lifecycle::{create_note, destroy_note}, note_getter::{get_notes, view_notes}, note_getter_options::NoteStatus @@ -379,36 +379,34 @@ contract Test { #[aztec(private)] fn test_shared_mutable_private_getter_for_registry_contract( - contract_address_to_read: AztecAddress, storage_slot_of_shared_mutable: Field, address_to_get_in_registry: AztecAddress - ) { + ) -> Field { // We have to derive this slot to get the location of the shared mutable inside the Map - let derived_slot = dep::aztec::hash::pedersen_hash( - [storage_slot_of_shared_mutable, address_to_get_in_registry.to_field()], - 0 - ); + let derived_slot = derive_storage_slot_in_map(storage_slot_of_shared_mutable, address_to_get_in_registry); + // It's a bit wonky because we need to know the delay for get_current_value_in_private to work correctly - let registry_private_getter: SharedMutablePrivateGetter = SharedMutablePrivateGetter::new(context, contract_address_to_read, derived_slot); + let registry_private_getter: SharedMutablePrivateGetter = SharedMutablePrivateGetter::new(context, AztecAddress::from_field(CANONICAL_KEY_REGISTRY_ADDRESS), derived_slot); let nullifier_public_key = registry_private_getter.get_current_value_in_private(); - context.emit_unencrypted_log(nullifier_public_key); + nullifier_public_key } #[aztec(private)] fn test_shared_mutable_private_getter( contract_address_to_read: AztecAddress, storage_slot_of_shared_mutable: Field - ) { + ) -> AztecAddress { // It's a bit wonky because we need to know the delay for get_current_value_in_private to work correctly let test: SharedMutablePrivateGetter = SharedMutablePrivateGetter::new( context, contract_address_to_read, storage_slot_of_shared_mutable ); + let authorized = test.get_current_value_in_private(); - context.emit_unencrypted_log(authorized); + authorized } #[aztec(private)] @@ -416,7 +414,7 @@ contract Test { address: AztecAddress, public_nullifying_key: GrumpkinPoint, ) { - assert_nullifier_public_key_is_fresh(&mut context, address, public_nullifying_key); + assert_eq(get_fresh_nullifier_public_key_hash(&mut context, address), poseidon2_hash(public_nullifying_key.serialize())); } #[aztec(public)] diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr b/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr index fcbae4871d9..06463ce268c 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr @@ -61,6 +61,25 @@ impl AztecAddress { ) } + pub fn compute_from_public_keys_and_partial_address( + nullifier_public_key: GrumpkinPoint, + incoming_public_key: GrumpkinPoint, + outgoing_public_key: GrumpkinPoint, + tagging_public_key: GrumpkinPoint, + partial_address: PartialAddress, + ) -> AztecAddress { + let public_keys_hash = PublicKeysHash::compute_new( + nullifier_public_key, + incoming_public_key, + outgoing_public_key, + tagging_public_key, + ); + + let computed_address = AztecAddress::compute(public_keys_hash, partial_address); + + computed_address + } + pub fn is_zero(self) -> bool { self.inner == 0 } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/address/public_keys_hash.nr b/noir-projects/noir-protocol-circuits/crates/types/src/address/public_keys_hash.nr index dfe3023abb2..9ea508fc140 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/address/public_keys_hash.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/address/public_keys_hash.nr @@ -1,6 +1,7 @@ use crate::{ - constants::GENERATOR_INDEX__PARTIAL_ADDRESS, hash::pedersen_hash, grumpkin_point::GrumpkinPoint, - traits::{ToField, Serialize, Deserialize} + constants::{GENERATOR_INDEX__PARTIAL_ADDRESS, GENERATOR_INDEX__PUBLIC_KEYS_HASH}, hash::pedersen_hash, grumpkin_point::GrumpkinPoint, + traits::{ToField, Serialize, Deserialize}, + hash::poseidon2_hash, }; // Public keys hash. Used in the computation of an address. @@ -50,6 +51,28 @@ impl PublicKeysHash { ) } + // TODO(#5830): Use this as the new one + pub fn compute_new( + nullifier_public_key: GrumpkinPoint, + incoming_public_key: GrumpkinPoint, + outgoing_public_key: GrumpkinPoint, + tagging_public_key: GrumpkinPoint + ) -> Self { + PublicKeysHash::from_field( + poseidon2_hash([ + nullifier_public_key.x, + nullifier_public_key.y, + incoming_public_key.x, + incoming_public_key.y, + outgoing_public_key.x, + outgoing_public_key.y, + tagging_public_key.x, + tagging_public_key.y, + GENERATOR_INDEX__PUBLIC_KEYS_HASH, + ]) + ) + } + pub fn to_field(self) -> Field { self.inner } diff --git a/yarn-project/circuit-types/src/keys/key_store.ts b/yarn-project/circuit-types/src/keys/key_store.ts index dd77bde64ed..168ec8d5f04 100644 --- a/yarn-project/circuit-types/src/keys/key_store.ts +++ b/yarn-project/circuit-types/src/keys/key_store.ts @@ -126,6 +126,7 @@ export interface KeyStore { * @param masterOutgoingViewingPublicKey - The stored outgoing viewing public key * @param masterTaggingPublicKey - The stored master tagging public key */ + // TODO(#5834): Move this function out of here. Key store should only be used for accounts, not recipients addPublicKeysForAccount( accountAddress: AztecAddress, masterNullifierPublicKey: Point, diff --git a/yarn-project/end-to-end/jest.integration.config.json b/yarn-project/end-to-end/jest.integration.config.json index 721267ff552..84d61df320c 100644 --- a/yarn-project/end-to-end/jest.integration.config.json +++ b/yarn-project/end-to-end/jest.integration.config.json @@ -6,7 +6,7 @@ "moduleNameMapper": { "^(\\.{1,2}/.*)\\.js$": "$1" }, - "reporters": [["default", { "summaryThreshold": 9999 }]], + "reporters": [["default", {"summaryThreshold": 9999}]], "testRegex": "./src/.*\\.test\\.ts$", "rootDir": "./src" } 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 index ce62bc216ff..a02e952fecc 100644 --- a/yarn-project/end-to-end/src/e2e_key_registry.test.ts +++ b/yarn-project/end-to-end/src/e2e_key_registry.test.ts @@ -41,7 +41,7 @@ describe('Key Registry', () => { describe('failure cases', () => { let accountAddedToRegistry: AztecAddress; - describe('should fail registering with bad input', () => { + describe('should fail when registering with different types of invalid input', () => { const masterNullifierPublicKey = Point.random(); const masterIncomingViewingPublicKey = Point.random(); const masterOutgoingViewingPublicKey = Point.random(); @@ -57,13 +57,13 @@ describe('Key Registry', () => { GeneratorIndex.PUBLIC_KEYS_HASH, ]); - // We hash the partial address and the public keys hash to get the account address + // TODO(#5726): Move the following line to AztecAddress class? accountAddedToRegistry = AztecAddress.fromField( - poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1]), + poseidon2Hash([publicKeysHash, partialAddress, GeneratorIndex.CONTRACT_ADDRESS_V1]), ); - it('should fail registering with mismatched address', async () => { + it('should fail when we register with a mismatched address', async () => { const mismatchedAddress = AztecAddress.random(); await expect( @@ -82,7 +82,7 @@ describe('Key Registry', () => { ).rejects.toThrow('Computed address does not match supplied address'); }); - it('should fail registering with mismatched nullifier public key', async () => { + it('should fail when we register with mismatched nullifier public key', async () => { const mismatchedMasterNullifierPublicKey = Point.random(); await expect( @@ -102,8 +102,8 @@ describe('Key Registry', () => { }); }); - describe('should fail when rotating keys with bad input', () => { - it('should fail when trying to rotate setting a 0 key', async () => { + describe('should fail when rotating keys with different types of bad input', () => { + it('should fail when we try to rotate keys, while setting a 0 key', async () => { await expect( keyRegistry .withWallet(wallets[0]) @@ -113,7 +113,7 @@ describe('Key Registry', () => { ).rejects.toThrow('New nullifier public key must be non-zero'); }); - it('should fail when trying to rotate for another address without authwit', async () => { + it('should fail when we try to rotate keys for another address without authwit', async () => { await expect( keyRegistry .withWallet(wallets[0]) @@ -127,13 +127,13 @@ describe('Key Registry', () => { describe('key registration flow', () => { let accountAddedToRegistry: AztecAddress; - const masterNullifierPublicKey: Point = new Point(new Fr(1), new Fr(2)); + const masterNullifierPublicKey = Point.random(); - it('should generate and register with original keys', async () => { - const masterIncomingViewingPublicKey: Point = new Point(new Fr(3), new Fr(4)); - const masterOutgoingViewingPublicKey: Point = new Point(new Fr(5), new Fr(6)); - const masterTaggingPublicKey: Point = new Point(new Fr(7), new Fr(8)); - const partialAddress: PartialAddress = new Fr(69); + it('should generate master public keys, a partial address, and register with the key registry', async () => { + const masterIncomingViewingPublicKey = Point.random(); + const masterOutgoingViewingPublicKey = Point.random(); + const masterTaggingPublicKey = Point.random(); + const partialAddress: PartialAddress = new Fr(420); const publicKeysHash = poseidon2Hash([ masterNullifierPublicKey, @@ -143,10 +143,9 @@ describe('Key Registry', () => { GeneratorIndex.PUBLIC_KEYS_HASH, ]); - // We hash the partial address and the public keys hash to get the account address // TODO(#5726): Move the following line to AztecAddress class? accountAddedToRegistry = AztecAddress.fromField( - poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1]), + poseidon2Hash([publicKeysHash, partialAddress, GeneratorIndex.CONTRACT_ADDRESS_V1]), ); await keyRegistry @@ -161,75 +160,60 @@ describe('Key Registry', () => { ) .send() .wait(); - }); - it('checks our registry contract from test contract and fails because the address has not been registered yet', async () => { - const { txHash } = await testContract.methods + // We check if our registered nullifier key is equal to the key obtained from the getter by + // reading our registry contract from the test contract. We expect this to fail because the change has not been applied yet + const emptyNullifierPublicKey = await testContract.methods .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, accountAddedToRegistry) - .send() - .wait(); + .simulate(); - const rawLogs = await pxe.getUnencryptedLogs({ txHash }); - expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(Fr.ZERO); - }); + expect(new Fr(emptyNullifierPublicKey)).toEqual(Fr.ZERO); - it('checks our registry contract from test contract and finds the address and associated nullifier public key after a delay', async () => { + // We check it again after a delay and expect that the change has been applied and consequently the assert is true await delay(5); - const { txHash } = await testContract.methods + const nullifierPublicKey = await testContract.methods .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, accountAddedToRegistry) - .send() - .wait(); + .simulate(); - const rawLogs = await pxe.getUnencryptedLogs({ txHash }); - - expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(poseidon2Hash(masterNullifierPublicKey.toFields())); + expect(new Fr(nullifierPublicKey)).toEqual(poseidon2Hash(masterNullifierPublicKey.toFields())); }); }); describe('key rotation flows', () => { const firstNewMasterNullifierPublicKey = Point.random(); - describe('normal key rotation flow', () => { - it('we rotate the nullifier key', async () => { + describe('key rotation flow without authwit', () => { + it('we call the key registry to rotate our nullifier key', async () => { await keyRegistry .withWallet(wallets[0]) .methods.rotate_nullifier_public_key(wallets[0].getAddress(), firstNewMasterNullifierPublicKey) .send() .wait(); - }); - - it("checks our registry contract from test contract and finds our old public key because the key rotation hasn't been applied yet", async () => { - const { txHash } = await testContract.methods - .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) - .send() - .wait(); - const rawLogs = await pxe.getUnencryptedLogs({ txHash }); - expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(0)); - }); + // We check if our rotated nullifier key is equal to the key obtained from the getter by + // reading our registry contract from the test contract. We expect this to fail because the change has not been applied yet + const emptyNullifierPublicKey = await testContract.methods + .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) + .simulate(); - it('checks our registry contract from test contract and finds the new nullifier public key that has been rotated', async () => { - await delay(5); + expect(new Fr(emptyNullifierPublicKey)).toEqual(Fr.ZERO); - const { txHash } = await testContract.methods - .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) - .send() - .wait(); + // We check it again after a delay and expect that the change has been applied and consequently the assert is true + await delay(5); - const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + const nullifierPublicKey = await testContract.methods + .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) + .simulate(); - expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual( - poseidon2Hash(firstNewMasterNullifierPublicKey.toFields()), - ); + expect(new Fr(nullifierPublicKey)).toEqual(poseidon2Hash(firstNewMasterNullifierPublicKey.toFields())); }); }); describe('key rotation flow with authwit', () => { - // This is the new value const secondNewMasterNullifierPublicKey = Point.random(); - it('wallet 0 lets wallet 1 call rotate_nullifier_public_key on his behalf with a pre-defined new public key', async () => { + it(`wallet 1 rotates wallet 0's nullifying public key with an authwit`, async () => { const action = keyRegistry .withWallet(wallets[1]) .methods.rotate_nullifier_public_key(wallets[0].getAddress(), secondNewMasterNullifierPublicKey); @@ -240,38 +224,28 @@ describe('Key Registry', () => { .wait(); await action.send().wait(); - }); - it("checks our registry contract from test contract and finds our old public key because the key rotation hasn't been applied yet", async () => { - const { txHash } = await testContract.methods + // We check if our rotated nullifier key is equal to the key obtained from the getter by + // reading our registry contract from the test contract. We expect this value to be the old one, because the new one hasn't been applied + const oldNullifierPublicKey = await testContract.methods .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) - .send() - .wait(); + .simulate(); - const rawLogs = await pxe.getUnencryptedLogs({ txHash }); - expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual( - poseidon2Hash(firstNewMasterNullifierPublicKey.toFields()), - ); - }); + expect(new Fr(oldNullifierPublicKey)).toEqual(poseidon2Hash(firstNewMasterNullifierPublicKey.toFields())); - it('checks our registry contract from test contract and finds the new nullifier public key that has been rotated', async () => { + // We check it again after a delay and expect that the change has been applied and consequently the assert is true await delay(5); - const { txHash } = await testContract.methods + const newNullifierPublicKey = await testContract.methods .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) - .send() - .wait(); - - const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + .simulate(); - expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual( - poseidon2Hash(secondNewMasterNullifierPublicKey.toFields()), - ); + expect(new Fr(newNullifierPublicKey)).toEqual(poseidon2Hash(secondNewMasterNullifierPublicKey.toFields())); }); }); }); - describe('test keys are fresh: key registration flow, no PXE', () => { + describe('testing get_fresh_nullifier_public_key_hash: key registration flow, no PXE', () => { const masterNullifierPublicKey = Point.random(); const masterIncomingViewingPublicKey = Point.random(); const masterOutgoingViewingPublicKey = Point.random(); @@ -286,10 +260,9 @@ describe('Key Registry', () => { GeneratorIndex.PUBLIC_KEYS_HASH, ]); - // We hash the partial address and the public keys hash to get the account address // TODO(#5726): Move the following line to AztecAddress class? const accountAddedToRegistry = AztecAddress.fromField( - poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1]), + poseidon2Hash([publicKeysHash, partialAddress, GeneratorIndex.CONTRACT_ADDRESS_V1]), ); it('should fail as we have not registered anything to the registry nor have we registered a recipient', async () => { @@ -301,7 +274,7 @@ describe('Key Registry', () => { ).rejects.toThrow(`Cannot satisfy constraint 'computed_address.eq(address)'`); }); - it('Now we add it to registry', async () => { + it('adds an entry to the key registry, and checks the key freshness without and with conflicting information from our pxe', async () => { await keyRegistry .withWallet(wallets[0]) .methods.register( @@ -314,28 +287,25 @@ describe('Key Registry', () => { ) .send() .wait(); - }); - it('checks key freshness and fails because the address change has not been applied yet due to lack of delay', async () => { + // We check if our registered nullifier key is equal to the key obtained from the getter by + // reading our registry contract from the test contract. We expect this to fail because the change has not been applied yet await expect( testContract.methods .test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey) .send() .wait(), ).rejects.toThrow(`Cannot satisfy constraint 'computed_address.eq(address)'`); - }); - it('checks key freshness after a delay, and is successful', async () => { + // We check it again after a delay and expect that the change has been applied and consequently the assert is true await delay(5); await testContract.methods .test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey) .send() .wait(); - }); - it('should succeed even if our pxe gives conflicting information', async () => { - // FIX THIS (#5834) + // TODO: (#5834) Refactor complete address to move the public keys await pxe.registerRecipient(CompleteAddress.create(accountAddedToRegistry, Point.ZERO, partialAddress), [ new Point(Fr.random(), Fr.random()), masterIncomingViewingPublicKey, @@ -343,6 +313,7 @@ describe('Key Registry', () => { masterTaggingPublicKey, ]); + // Our check should still succeed even if our pxe gives conflicting information, taking the registry as the source of truth. await testContract.methods .test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey) .send() @@ -350,12 +321,11 @@ describe('Key Registry', () => { }); }); - describe('test keys are fresh: key registration flow, with PXE', () => { - const masterNullifierPublicKey: Point = new Point(new Fr(17), new Fr(18)); - const masterIncomingViewingPublicKey: Point = new Point(new Fr(19), new Fr(20)); - const masterOutgoingViewingPublicKey: Point = new Point(new Fr(21), new Fr(22)); - const masterTaggingPublicKey: Point = new Point(new Fr(23), new Fr(24)); - + describe('testing assert_nullifier_key_is_fresh: key registration flow, with PXE', () => { + const masterNullifierPublicKey = Point.random(); + const masterIncomingViewingPublicKey = Point.random(); + const masterOutgoingViewingPublicKey = Point.random(); + const masterTaggingPublicKey = Point.random(); const partialAddress: PartialAddress = new Fr(69420); const publicKeysHash = poseidon2Hash([ @@ -366,10 +336,9 @@ describe('Key Registry', () => { GeneratorIndex.PUBLIC_KEYS_HASH, ]); - // We hash the partial address and the public keys hash to get the account address // TODO(#5726): Move the following line to AztecAddress class? const accountAddedToRegistry = AztecAddress.fromField( - poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1]), + poseidon2Hash([publicKeysHash, partialAddress, GeneratorIndex.CONTRACT_ADDRESS_V1]), ); it('should fail as we have not registered anything to the registry nor have we registered a recipient', async () => { @@ -381,9 +350,9 @@ describe('Key Registry', () => { ).rejects.toThrow(`Cannot satisfy constraint 'computed_address.eq(address)'`); }); - it('should fail when we register bad keys and the lib checks our pxe', async () => { + it('should fail when we try to check the public keys for a invalid address', async () => { const randAddress = AztecAddress.random(); - // FIX THIS (#5834) + // TODO: (#5834) Refactor complete address to move the public keys await pxe.registerRecipient(CompleteAddress.create(randAddress, Point.ZERO, partialAddress), [ masterNullifierPublicKey, masterIncomingViewingPublicKey, @@ -394,32 +363,24 @@ describe('Key Registry', () => { await expect( testContract.methods.test_nullifier_key_freshness(randAddress, masterNullifierPublicKey).send().wait(), ).rejects.toThrow(`Cannot satisfy constraint 'computed_address.eq(address)'`); - }); + }) - it('should succeed because we register our recipient manually and the lib checks our pxe', async () => { - // FIX THIS (#5834) + it('adds a recipient to our pxe, and checks the key freshness with and without adding an entry to our key registry', async () => { + // TODO: (#5834) Refactor complete address to move the public keys await pxe.registerRecipient(CompleteAddress.create(accountAddedToRegistry, Point.ZERO, partialAddress), [ masterNullifierPublicKey, masterIncomingViewingPublicKey, masterOutgoingViewingPublicKey, masterTaggingPublicKey, ]); + + // The check should succeed because we register our recipient manually and the lib checks our pxe await testContract.methods .test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey) .send() .wait(); - }); - - it('should fail when we put in a different key', async () => { - await expect( - testContract.methods - .test_nullifier_key_freshness(accountAddedToRegistry, masterIncomingViewingPublicKey) - .send() - .wait(), - ).rejects.toThrow(`Cannot satisfy constraint 'keys[key_type].eq(key)'`); - }); - it('Now we add it to registry', async () => { + // Now we add the keys to registry await keyRegistry .withWallet(wallets[0]) .methods.register( @@ -432,36 +393,23 @@ describe('Key Registry', () => { ) .send() .wait(); - }); - it('we start the change in the registry, it has not been applied yet, but we still see we have a fresh key due to it being added in the pxe', async () => { - const { txHash } = await testContract.methods + // We check if our rotated nullifier key is equal to the key obtained from the getter by + // reading our registry contract from the test contract. We expect this to be 0 because the change has not been applied yet + const emptyNullifierPublicKey = await testContract.methods .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, accountAddedToRegistry) - .send() - .wait(); + .simulate(); - const rawLogs = await pxe.getUnencryptedLogs({ txHash }); - expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(Fr.ZERO); + expect(new Fr(emptyNullifierPublicKey)).toEqual(Fr.ZERO); - // Checks freshness of newly added keys, but the change hasn't been affected yet, but we have manually added it to our pxe so it should pass + // We check if our rotated nullifier key is equal to the key obtained from the getter. We expect this to succeed because even though the change + // has not been applied yet to the registry, we have manually the keys to our pxe await testContract.methods .test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey) .send() .wait(); - }); - - it('in the case where the key exists both in the pxe and our registry, we know nothing weird will happen', async () => { - await delay(5); - - const { txHash } = await testContract.methods - .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, accountAddedToRegistry) - .send() - .wait(); - - const rawLogs = await pxe.getUnencryptedLogs({ txHash }); - - expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(poseidon2Hash(masterNullifierPublicKey.toFields())); + // In the case where the key exists both in the pxe and our registry, we know that our assert will still remain true await testContract.methods .test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey) .send() @@ -469,29 +417,28 @@ describe('Key Registry', () => { }); }); - describe('key rotation flow; assert keys are fresh', () => { + describe('testing assert_nullifier_key_is_fresh: key rotation flow', () => { const newMasterNullifierPublicKey = Point.random(); - it('we rotate the nullifier key', async () => { + it('we rotate the nullifier key and check that the key is fresh', async () => { await keyRegistry .withWallet(wallets[0]) .methods.rotate_nullifier_public_key(wallets[0].getAddress(), newMasterNullifierPublicKey) .send() .wait(); - }); - it("checks our registry contract from test contract and fails because the change hasn't been applied yet", async () => { + // We check if our rotated nullifier key is equal to the key obtained from the getter by + // reading our registry contract from the test contract. We expect this to fail because the change has not been applied yet await expect( testContract.methods .test_nullifier_key_freshness(wallets[0].getAddress(), newMasterNullifierPublicKey) .send() .wait(), ).rejects.toThrow( - `Cannot satisfy constraint 'hashed_nullifier_public_key_in_registry == poseidon2_hash(nullifier_public_key_to_test.serialize())'`, + `Cannot satisfy constraint 'assert_eq(get_fresh_nullifier_public_key_hash(&mut context, address), poseidon2_hash(public_nullifying_key.serialize()))'`, ); - }); - it('checks our registry contract from test contract and succeeds because the change has been applied', async () => { + // We check it again after a delay and expect that the change has been applied and consequently the assert is true await delay(5); await testContract.methods diff --git a/yarn-project/end-to-end/src/e2e_state_vars.test.ts b/yarn-project/end-to-end/src/e2e_state_vars.test.ts index 8a6ed6dc23e..c9e8609a9c1 100644 --- a/yarn-project/end-to-end/src/e2e_state_vars.test.ts +++ b/yarn-project/end-to-end/src/e2e_state_vars.test.ts @@ -249,27 +249,21 @@ describe('e2e_state_vars', () => { }, 30_000); it("checks authorized in auth contract from test contract and finds the old value because the change hasn't been applied yet", async () => { - const { txHash } = await testContract.methods + const authorized = await testContract.methods .test_shared_mutable_private_getter(authContract.address, 2) - .send() - .wait(); + .simulate(); - // The function above emits an unencrypted log as a means of returning the data - const rawLogs = await pxe.getUnencryptedLogs({ txHash }); - expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(0)); + expect(AztecAddress.fromBigInt(authorized)).toEqual(AztecAddress.ZERO); }); it('checks authorized in auth contract from test contract and finds the correctly set value', async () => { await delay(5); - const { txHash } = await testContract.methods + const authorized = await testContract.methods .test_shared_mutable_private_getter(authContract.address, 2) - .send() - .wait(); + .simulate(); - // The function above emits an unencrypted log as a means of returning the data - const rawLogs = await pxe.getUnencryptedLogs({ txHash }); - expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(6969696969)); + expect(AztecAddress.fromBigInt(authorized)).toEqual(AztecAddress.fromBigInt(6969696969n)); }); }); }); diff --git a/yarn-project/key-store/src/test_key_store.ts b/yarn-project/key-store/src/test_key_store.ts index 288ffc9430d..a3c0d4b239b 100644 --- a/yarn-project/key-store/src/test_key_store.ts +++ b/yarn-project/key-store/src/test_key_store.ts @@ -293,6 +293,7 @@ export class TestKeyStore implements KeyStore { return Promise.resolve(Fr.fromBuffer(publicKeysHashBuffer)); } + // TODO(#5834): Re-add separation between recipients and accounts in keystore. public async addPublicKeysForAccount( accountAddress: AztecAddress, masterNullifierPublicKey: Point, diff --git a/yarn-project/package.common.json b/yarn-project/package.common.json index 6fcf1a28315..80b56a8d697 100644 --- a/yarn-project/package.common.json +++ b/yarn-project/package.common.json @@ -24,7 +24,7 @@ "moduleNameMapper": { "^(\\.{1,2}/.*)\\.[cm]?js$": "$1" }, - "reporters": [["default", { "summaryThreshold": 9999 }]], + "reporters": [["default", {"summaryThreshold": 9999}]], "testRegex": "./src/.*\\.test\\.(js|mjs|ts)$", "rootDir": "./src" } diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index 625830ba973..f46990d5ca9 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -173,8 +173,9 @@ export class Oracle { } async getPublicKeysAndPartialAddress([address]: ACVMField[]): Promise { - let partialAddress: PartialAddress; let publicKeys: Point[] | undefined; + let partialAddress: PartialAddress; + // TODO #5834: This should be reworked to return the public keys as well try { ({ partialAddress } = await this.typedOracle.getCompleteAddress(AztecAddress.fromField(fromACVMField(address)))); @@ -188,9 +189,9 @@ export class Oracle { publicKeys = Array(4).fill(Point.ZERO); } - const acvmKeys = publicKeys.flatMap(key => key.toFields()); + const acvmPublicKeys = publicKeys.flatMap(key => key.toFields()); - return [partialAddress, ...acvmKeys].map(toACVMField); + return [...acvmPublicKeys, partialAddress].map(toACVMField); } async getNotes( From c852740f1700ff71979479e795d7c4c89b877438 Mon Sep 17 00:00:00 2001 From: esau <152162806+sklppy88@users.noreply.github.com> Date: Wed, 1 May 2024 07:09:34 -0500 Subject: [PATCH 20/93] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jan Beneš --- yarn-project/circuit-types/src/interfaces/pxe.ts | 2 +- yarn-project/simulator/src/client/db_oracle.ts | 4 ++-- yarn-project/simulator/src/client/view_data_oracle.ts | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/yarn-project/circuit-types/src/interfaces/pxe.ts b/yarn-project/circuit-types/src/interfaces/pxe.ts index eab85b46980..0e95d024727 100644 --- a/yarn-project/circuit-types/src/interfaces/pxe.ts +++ b/yarn-project/circuit-types/src/interfaces/pxe.ts @@ -73,7 +73,7 @@ export interface PXE { * the recipient's notes. We can send notes to this account because we can encrypt them with the recipient's * public key. */ - // TODO: #5834: FIX THIS AFTER THE COMPLETE ADDRESS REFACTOR + // TODO: #5834: Nuke publicKeys optional parameter after `CompleteAddress` refactor. registerRecipient(recipient: CompleteAddress, publicKeys?: Point[]): Promise; /** diff --git a/yarn-project/simulator/src/client/db_oracle.ts b/yarn-project/simulator/src/client/db_oracle.ts index 2646898a612..eb545df6e11 100644 --- a/yarn-project/simulator/src/client/db_oracle.ts +++ b/yarn-project/simulator/src/client/db_oracle.ts @@ -65,10 +65,10 @@ export interface DBOracle extends CommitmentsDB { popCapsule(): Promise; /** - * Gets public keys for an address, getCompleteAddress should be modified to include this + * Gets public keys for an address. * @param The address to look up * @returns The public keys for a specific address - * TODO: #5834 + * TODO(#5834): Replace with `getCompleteAddress`. */ getPublicKeysForAddress(address: AztecAddress): Promise; diff --git a/yarn-project/simulator/src/client/view_data_oracle.ts b/yarn-project/simulator/src/client/view_data_oracle.ts index 2bc1fbfc937..50dc2552c25 100644 --- a/yarn-project/simulator/src/client/view_data_oracle.ts +++ b/yarn-project/simulator/src/client/view_data_oracle.ts @@ -167,10 +167,10 @@ export class ViewDataOracle extends TypedOracle { } /** - * Gets public keys for an address, getCompleteAddress should be modified to include this + * Gets public keys for an address. * @param The address to look up * @returns The public keys for a specific address - * TODO: #5834 + * TODO(#5834): Replace with `getCompleteAddress`. */ public override getPublicKeysForAddress(address: AztecAddress) { return this.db.getPublicKeysForAddress(address); From b76ab1a613164f4d8c73133e102f854594380c92 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Wed, 1 May 2024 12:56:20 +0000 Subject: [PATCH 21/93] fix --- .../end-to-end/src/e2e_key_registry.test.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) 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 index 501e2734cc3..4fb21eb4a99 100644 --- a/yarn-project/end-to-end/src/e2e_key_registry.test.ts +++ b/yarn-project/end-to-end/src/e2e_key_registry.test.ts @@ -164,7 +164,7 @@ describe('Key Registry', () => { // We check if our registered nullifier key is equal to the key obtained from the getter by // reading our registry contract from the test contract. We expect this to fail because the change has not been applied yet const emptyNullifierPublicKey = await testContract.methods - .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, accountAddedToRegistry) + .test_shared_mutable_private_getter_for_registry_contract(1, accountAddedToRegistry) .simulate(); expect(new Fr(emptyNullifierPublicKey)).toEqual(Fr.ZERO); @@ -173,7 +173,7 @@ describe('Key Registry', () => { await delay(5); const nullifierPublicKey = await testContract.methods - .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, accountAddedToRegistry) + .test_shared_mutable_private_getter_for_registry_contract(1, accountAddedToRegistry) .simulate(); expect(new Fr(nullifierPublicKey)).toEqual(poseidon2Hash(masterNullifierPublicKey.toFields())); @@ -194,7 +194,7 @@ describe('Key Registry', () => { // We check if our rotated nullifier key is equal to the key obtained from the getter by // reading our registry contract from the test contract. We expect this to fail because the change has not been applied yet const emptyNullifierPublicKey = await testContract.methods - .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) + .test_shared_mutable_private_getter_for_registry_contract(1, wallets[0].getAddress()) .simulate(); expect(new Fr(emptyNullifierPublicKey)).toEqual(Fr.ZERO); @@ -203,7 +203,7 @@ describe('Key Registry', () => { await delay(5); const nullifierPublicKey = await testContract.methods - .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) + .test_shared_mutable_private_getter_for_registry_contract(1, wallets[0].getAddress()) .simulate(); expect(new Fr(nullifierPublicKey)).toEqual(poseidon2Hash(firstNewMasterNullifierPublicKey.toFields())); @@ -228,7 +228,7 @@ describe('Key Registry', () => { // We check if our rotated nullifier key is equal to the key obtained from the getter by // reading our registry contract from the test contract. We expect this value to be the old one, because the new one hasn't been applied const oldNullifierPublicKey = await testContract.methods - .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) + .test_shared_mutable_private_getter_for_registry_contract(1, wallets[0].getAddress()) .simulate(); expect(new Fr(oldNullifierPublicKey)).toEqual(poseidon2Hash(firstNewMasterNullifierPublicKey.toFields())); @@ -237,7 +237,7 @@ describe('Key Registry', () => { await delay(5); const newNullifierPublicKey = await testContract.methods - .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) + .test_shared_mutable_private_getter_for_registry_contract(1, wallets[0].getAddress()) .simulate(); expect(new Fr(newNullifierPublicKey)).toEqual(poseidon2Hash(secondNewMasterNullifierPublicKey.toFields())); @@ -397,7 +397,7 @@ describe('Key Registry', () => { // We check if our rotated nullifier key is equal to the key obtained from the getter by // reading our registry contract from the test contract. We expect this to be 0 because the change has not been applied yet const emptyNullifierPublicKey = await testContract.methods - .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, accountAddedToRegistry) + .test_shared_mutable_private_getter_for_registry_contract(1, accountAddedToRegistry) .simulate(); expect(new Fr(emptyNullifierPublicKey)).toEqual(Fr.ZERO); From 59a4c1894063620d2810b91c3f42cf82bf940477 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Wed, 1 May 2024 16:22:05 +0000 Subject: [PATCH 22/93] format --- .../end-to-end/src/e2e_key_registry.test.ts | 43 +++++++++---------- .../end-to-end/src/e2e_state_vars.test.ts | 5 +-- 2 files changed, 23 insertions(+), 25 deletions(-) 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 index 4fb21eb4a99..092ee32682d 100644 --- a/yarn-project/end-to-end/src/e2e_key_registry.test.ts +++ b/yarn-project/end-to-end/src/e2e_key_registry.test.ts @@ -57,7 +57,6 @@ describe('Key Registry', () => { GeneratorIndex.PUBLIC_KEYS_HASH, ]); - // TODO(#5726): Move the following line to AztecAddress class? accountAddedToRegistry = AztecAddress.fromField( poseidon2Hash([publicKeysHash, partialAddress, GeneratorIndex.CONTRACT_ADDRESS_V1]), @@ -161,7 +160,7 @@ describe('Key Registry', () => { .send() .wait(); - // We check if our registered nullifier key is equal to the key obtained from the getter by + // We check if our registered nullifier key is equal to the key obtained from the getter by // reading our registry contract from the test contract. We expect this to fail because the change has not been applied yet const emptyNullifierPublicKey = await testContract.methods .test_shared_mutable_private_getter_for_registry_contract(1, accountAddedToRegistry) @@ -191,22 +190,22 @@ describe('Key Registry', () => { .send() .wait(); - // We check if our rotated nullifier key is equal to the key obtained from the getter by - // reading our registry contract from the test contract. We expect this to fail because the change has not been applied yet - const emptyNullifierPublicKey = await testContract.methods - .test_shared_mutable_private_getter_for_registry_contract(1, wallets[0].getAddress()) - .simulate(); + // We check if our rotated nullifier key is equal to the key obtained from the getter by + // reading our registry contract from the test contract. We expect this to fail because the change has not been applied yet + const emptyNullifierPublicKey = await testContract.methods + .test_shared_mutable_private_getter_for_registry_contract(1, wallets[0].getAddress()) + .simulate(); - expect(new Fr(emptyNullifierPublicKey)).toEqual(Fr.ZERO); + expect(new Fr(emptyNullifierPublicKey)).toEqual(Fr.ZERO); - // We check it again after a delay and expect that the change has been applied and consequently the assert is true - await delay(5); + // We check it again after a delay and expect that the change has been applied and consequently the assert is true + await delay(5); - const nullifierPublicKey = await testContract.methods - .test_shared_mutable_private_getter_for_registry_contract(1, wallets[0].getAddress()) - .simulate(); + const nullifierPublicKey = await testContract.methods + .test_shared_mutable_private_getter_for_registry_contract(1, wallets[0].getAddress()) + .simulate(); - expect(new Fr(nullifierPublicKey)).toEqual(poseidon2Hash(firstNewMasterNullifierPublicKey.toFields())); + expect(new Fr(nullifierPublicKey)).toEqual(poseidon2Hash(firstNewMasterNullifierPublicKey.toFields())); }); }); @@ -225,9 +224,9 @@ describe('Key Registry', () => { await action.send().wait(); - // We check if our rotated nullifier key is equal to the key obtained from the getter by - // reading our registry contract from the test contract. We expect this value to be the old one, because the new one hasn't been applied - const oldNullifierPublicKey = await testContract.methods + // We check if our rotated nullifier key is equal to the key obtained from the getter by + // reading our registry contract from the test contract. We expect this value to be the old one, because the new one hasn't been applied + const oldNullifierPublicKey = await testContract.methods .test_shared_mutable_private_getter_for_registry_contract(1, wallets[0].getAddress()) .simulate(); @@ -288,7 +287,7 @@ describe('Key Registry', () => { .send() .wait(); - // We check if our registered nullifier key is equal to the key obtained from the getter by + // We check if our registered nullifier key is equal to the key obtained from the getter by // reading our registry contract from the test contract. We expect this to fail because the change has not been applied yet await expect( testContract.methods @@ -363,7 +362,7 @@ describe('Key Registry', () => { await expect( testContract.methods.test_nullifier_key_freshness(randAddress, masterNullifierPublicKey).send().wait(), ).rejects.toThrow(`Cannot satisfy constraint 'computed_address.eq(address)'`); - }) + }); it('adds a recipient to our pxe, and checks the key freshness with and without adding an entry to our key registry', async () => { // TODO: (#5834) Refactor complete address to move the public keys @@ -394,7 +393,7 @@ describe('Key Registry', () => { .send() .wait(); - // We check if our rotated nullifier key is equal to the key obtained from the getter by + // We check if our rotated nullifier key is equal to the key obtained from the getter by // reading our registry contract from the test contract. We expect this to be 0 because the change has not been applied yet const emptyNullifierPublicKey = await testContract.methods .test_shared_mutable_private_getter_for_registry_contract(1, accountAddedToRegistry) @@ -402,7 +401,7 @@ describe('Key Registry', () => { expect(new Fr(emptyNullifierPublicKey)).toEqual(Fr.ZERO); - // We check if our rotated nullifier key is equal to the key obtained from the getter. We expect this to succeed because even though the change + // We check if our rotated nullifier key is equal to the key obtained from the getter. We expect this to succeed because even though the change // has not been applied yet to the registry, we have manually the keys to our pxe await testContract.methods .test_nullifier_key_freshness(accountAddedToRegistry, masterNullifierPublicKey) @@ -427,7 +426,7 @@ describe('Key Registry', () => { .send() .wait(); - // We check if our rotated nullifier key is equal to the key obtained from the getter by + // We check if our rotated nullifier key is equal to the key obtained from the getter by // reading our registry contract from the test contract. We expect this to fail because the change has not been applied yet await expect( testContract.methods diff --git a/yarn-project/end-to-end/src/e2e_state_vars.test.ts b/yarn-project/end-to-end/src/e2e_state_vars.test.ts index 426072cf8fc..dcdbdfd9454 100644 --- a/yarn-project/end-to-end/src/e2e_state_vars.test.ts +++ b/yarn-project/end-to-end/src/e2e_state_vars.test.ts @@ -1,4 +1,4 @@ -import { AztecAddress, Fr, type PXE, type Wallet } from '@aztec/aztec.js'; +import { AztecAddress, Fr, type Wallet } from '@aztec/aztec.js'; import { AuthContract, DocsExampleContract, TestContract } from '@aztec/noir-contracts.js'; import { jest } from '@jest/globals'; @@ -8,7 +8,6 @@ import { setup } from './fixtures/utils.js'; const TIMEOUT = 100_000; describe('e2e_state_vars', () => { - let pxe: PXE; jest.setTimeout(TIMEOUT); let wallet: Wallet; @@ -20,7 +19,7 @@ describe('e2e_state_vars', () => { const RANDOMNESS = 2n; beforeAll(async () => { - ({ teardown, wallet, pxe } = await setup(2)); + ({ teardown, wallet } = await setup(2)); contract = await DocsExampleContract.deploy(wallet).send().deployed(); }); From dd9ae574bd05213ee5df72cb3a3e5035610bb04c Mon Sep 17 00:00:00 2001 From: Esau Date: Wed, 1 May 2024 18:43:32 +0200 Subject: [PATCH 23/93] test --- .../aztec-nr/value-note/src/value_note.nr | 34 ++++++++----------- .../src/subscription_note.nr | 32 ++++++++--------- 2 files changed, 29 insertions(+), 37 deletions(-) diff --git a/noir-projects/aztec-nr/value-note/src/value_note.nr b/noir-projects/aztec-nr/value-note/src/value_note.nr index 3190baa13a1..b67cd8a98dc 100644 --- a/noir-projects/aztec-nr/value-note/src/value_note.nr +++ b/noir-projects/aztec-nr/value-note/src/value_note.nr @@ -14,10 +14,7 @@ global VALUE_NOTE_LEN: Field = 3; // 3 plus a header. #[aztec(note)] struct ValueNote { value: Field, - // the nullifying public key of the person who owns the note. The owner (recipient) to ensure that the note - // can be privately spent. When nullifier secret and encryption private key is same - // we can simply use the owner for this one. - owner_nullifying_public_key_hash: Field, + owner: AztecAddress, randomness: Field, } // docs:end:value-note-def @@ -27,7 +24,7 @@ impl NoteInterface for ValueNote { fn compute_nullifier(self, context: &mut PrivateContext) -> Field { let note_hash_for_nullify = compute_note_hash_for_consumption(self); - let secret = context.request_app_nullifier_secret_key(self.owner_nullifying_public_key_hash); + let secret = context.request_app_nullifier_secret_key(self.owner); poseidon2_hash([ note_hash_for_nullify, secret, @@ -39,7 +36,7 @@ impl NoteInterface for ValueNote { fn compute_nullifier_without_context(self) -> Field { let note_hash_for_nullify = compute_note_hash_for_consumption(self); - let secret = get_app_nullifier_secret_key(self.owner_nullifying_public_key_hash); + let secret = get_app_nullifier_secret_key(self.owner); poseidon2_hash([ note_hash_for_nullify, secret, @@ -49,24 +46,23 @@ impl NoteInterface for ValueNote { // Broadcasts the note as an encrypted log on L1. fn broadcast(self, context: &mut PrivateContext, slot: Field) { - // TODO (ek): Disabled this until we fix the emit log types - // let encryption_pub_key = get_public_key(self.owner_nullifying_public_key_hash); - // emit_encrypted_log( - // context, - // (*context).this_address(), - // slot, - // Self::get_note_type_id(), - // encryption_pub_key, - // self.serialize_content(), - // ); + let encryption_pub_key = get_public_key(self.owner); + emit_encrypted_log( + context, + (*context).this_address(), + slot, + Self::get_note_type_id(), + encryption_pub_key, + self.serialize_content(), + ); } } impl ValueNote { - pub fn new(value: Field, owner_nullifying_public_key_hash: Field) -> Self { + pub fn new(value: Field, owner: AztecAddress) -> Self { let randomness = unsafe_rand(); let header = NoteHeader::empty(); - ValueNote { value, randomness, owner_nullifying_public_key_hash, header } + ValueNote { value, owner, randomness, header } } } @@ -74,6 +70,6 @@ impl Serialize<7> for ValueNote { fn serialize(self) -> [Field; 7] { let header = self.header.serialize(); - [self.value, self.owner_nullifying_public_key_hash, self.randomness, header[0], header[1], header[2], header[3]] + [self.value, self.owner.to_field(), self.randomness, header[0], header[1], header[2], header[3]] } } diff --git a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/subscription_note.nr b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/subscription_note.nr index 8e3afe180bd..435f61191b3 100644 --- a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/subscription_note.nr +++ b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/subscription_note.nr @@ -11,18 +11,15 @@ global SUBSCRIPTION_NOTE_LEN: Field = 3; // TODO: Do we need to include a nonce, in case we want to read/nullify/recreate with the same pubkey value? #[aztec(note)] struct SubscriptionNote { + owner: AztecAddress, expiry_block_number: Field, remaining_txs: Field, - // the nullifying public key of the person who owns the note. The owner (recipient) to ensure that the note - // can be privately spent. When nullifier secret and encryption private key is same - // we can simply use the owner for this one. - owner_nullifying_public_key_hash: Field, } impl NoteInterface for SubscriptionNote { fn compute_nullifier(self, context: &mut PrivateContext) -> Field { let note_hash_for_nullify = compute_note_hash_for_consumption(self); - let secret = context.request_app_nullifier_secret_key(self.owner_nullifying_public_key_hash); + let secret = context.request_app_nullifier_secret_key(self.owner); poseidon2_hash([ note_hash_for_nullify, secret, @@ -32,7 +29,7 @@ impl NoteInterface for SubscriptionNote { fn compute_nullifier_without_context(self) -> Field { let note_hash_for_nullify = compute_note_hash_for_consumption(self); - let secret = get_app_nullifier_secret_key(self.owner_nullifying_public_key_hash); + let secret = get_app_nullifier_secret_key(self.owner); poseidon2_hash([ note_hash_for_nullify, secret, @@ -42,21 +39,20 @@ impl NoteInterface for SubscriptionNote { // Broadcasts the note as an encrypted log on L1. fn broadcast(self, context: &mut PrivateContext, slot: Field) { - // TODO (ek): Disabled this until we fix the emit log types - // let encryption_pub_key = get_public_key(self.owner_nullifying_public_key_hash); - // emit_encrypted_log( - // context, - // (*context).this_address(), - // slot, - // Self::get_note_type_id(), - // encryption_pub_key, - // self.serialize_content(), - // ); + let encryption_pub_key = get_public_key(self.owner); + emit_encrypted_log( + context, + (*context).this_address(), + slot, + Self::get_note_type_id(), + encryption_pub_key, + self.serialize_content(), + ); } } impl SubscriptionNote { - pub fn new(expiry_block_number: Field, remaining_txs: Field, owner_nullifying_public_key_hash: Field) -> Self { - SubscriptionNote { expiry_block_number, remaining_txs, owner_nullifying_public_key_hash, header: NoteHeader::empty() } + pub fn new(owner: AztecAddress, expiry_block_number: Field, remaining_txs: Field) -> Self { + SubscriptionNote { owner, expiry_block_number, remaining_txs, header: NoteHeader::empty() } } } From 32598c9997b66516858ed3d58674dee501bf7ffd Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Wed, 1 May 2024 16:43:39 +0000 Subject: [PATCH 24/93] remove --- .../src/keys/assert_public_key_freshness.nr | 95 ------------------- 1 file changed, 95 deletions(-) delete mode 100644 noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr diff --git a/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr b/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr deleted file mode 100644 index 54c82e76cd3..00000000000 --- a/noir-projects/aztec-nr/aztec/src/keys/assert_public_key_freshness.nr +++ /dev/null @@ -1,95 +0,0 @@ -use dep::protocol_types::{ - address::{ - AztecAddress, - PartialAddress - }, - constants::{ - GENERATOR_INDEX__PUBLIC_KEYS_HASH, - GENERATOR_INDEX__CONTRACT_ADDRESS_V1, - CANONICAL_KEY_REGISTRY_ADDRESS - }, - grumpkin_point::GrumpkinPoint, -}; - -use crate::context::PrivateContext; -use crate::hash::{ - pedersen_hash, - poseidon2_hash, -}; -use crate::oracle; -use crate::state_vars::shared_mutable::shared_mutable_private_getter::SharedMutablePrivateGetter; - -struct PublicKeyTypeEnum { - NULLIFIER: u8, -} - -global PublicKeyType = PublicKeyTypeEnum { - NULLIFIER: 0, -}; - -pub fn assert_nullifier_public_key_is_fresh( - context: &mut PrivateContext, - address: AztecAddress, - nullifier_public_key_to_test: GrumpkinPoint, -) { - // This is the storage slot of the nullifier_public_key inside the key registry contract - let storage_slot_of_nullifier_public_key = 1; - // We have to derive this slot to get the location of the shared mutable inside the Map - // This should mimic how maps derive their slots - let derived_slot = pedersen_hash( - [storage_slot_of_nullifier_public_key, address.to_field()], - 0 - ); - - // It's a bit wonky because we need to know the delay for get_current_value_in_private to work correctly - // We read from the canonical Key Registry - let registry_private_getter: SharedMutablePrivateGetter = SharedMutablePrivateGetter::new(*context, AztecAddress::from_field(CANONICAL_KEY_REGISTRY_ADDRESS), derived_slot); - let hashed_nullifier_public_key_in_registry = registry_private_getter.get_current_value_in_private(); - - // In the case that the value is not found in the registry we need to manually pass in the address preimage - if (hashed_nullifier_public_key_in_registry == 0) { - check_public_key_validity(address, PublicKeyType.NULLIFIER, nullifier_public_key_to_test, true); - } else { - assert(hashed_nullifier_public_key_in_registry == poseidon2_hash(nullifier_public_key_to_test.serialize())); - } -} - -pub fn get_fresh_nullifier_public_key_hash( - context: &mut PrivateContext, - address: AztecAddress, -) -> Field { - // This is the storage slot of the nullifier_public_key inside the key registry contract - let storage_slot_of_nullifier_public_key = 1; - // We have to derive this slot to get the location of the shared mutable inside the Map - // This should mimic how maps derive their slots - let derived_slot = pedersen_hash( - [storage_slot_of_nullifier_public_key, address.to_field()], - 0 - ); - - // It's a bit wonky because we need to know the delay for get_current_value_in_private to work correctly - // We read from the canonical Key Registry - let registry_private_getter: SharedMutablePrivateGetter = SharedMutablePrivateGetter::new(*context, AztecAddress::from_field(CANONICAL_KEY_REGISTRY_ADDRESS), derived_slot); - let hashed_nullifier_public_key_in_registry = registry_private_getter.get_current_value_in_private(); - - let nullifier_public_key_hash = if hashed_nullifier_public_key_in_registry == 0 { - let keys = get_public_keys_internal(address, false); - poseidon2_hash(keys[PublicKeyType.NULLIFIER].serialize()) - } else { - hashed_nullifier_public_key_in_registry - }; - - nullifier_public_key_hash -} - -fn check_public_key_validity(address: AztecAddress, key_type: u8, key: GrumpkinPoint, check_validity: bool) { - let keys = get_public_keys_internal(address, check_validity); - - assert(keys[key_type].eq(key)); -} - -fn get_public_keys_internal(address: AztecAddress, check_validity: bool) -> [GrumpkinPoint; 4] { - let (_, public_keys) = oracle::keys::get_public_keys_and_partial_address(address, check_validity); - - public_keys -} From 0f0df8160ef9621b3fc329b9da27d96d73ceb9ca Mon Sep 17 00:00:00 2001 From: Esau Date: Wed, 1 May 2024 18:47:53 +0200 Subject: [PATCH 25/93] another --- .../src/types/token_note.nr | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr index f37b35c7c83..5f6edf94d5f 100644 --- a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr +++ b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr @@ -6,9 +6,9 @@ use dep::aztec::{ }; trait OwnedNote { - fn new(amount: U128, owner_nullifying_public_key_hash: Field) -> Self; + fn new(amount: U128, owner: AztecAddress) -> Self; fn get_amount(self) -> U128; - fn get_owner_nullifying_public_key_hash(self) -> Field; + fn get_owner(self) -> AztecAddress; } global TOKEN_NOTE_LEN: Field = 3; // 3 plus a header. @@ -17,10 +17,10 @@ global TOKEN_NOTE_LEN: Field = 3; // 3 plus a header. struct TokenNote { // the amount of tokens in the note amount: U128, - // the nullifying public key of the person who owns the note. The owner (recipient) to ensure that the note + // the provider of secrets for the nullifier. The owner (recipient) to ensure that the note // can be privately spent. When nullifier secret and encryption private key is same // we can simply use the owner for this one. - owner_nullifying_public_key_hash: Field, + owner: AztecAddress, // randomness of the note to hide contents. randomness: Field, } @@ -29,7 +29,7 @@ impl NoteInterface for TokenNote { // docs:start:nullifier fn compute_nullifier(self, context: &mut PrivateContext) -> Field { let note_hash_for_nullify = compute_note_hash_for_consumption(self); - let secret = context.request_app_nullifier_secret_key(self.owner_nullifying_public_key_hash); + let secret = context.request_app_nullifier_secret_key(self.owner); poseidon2_hash([ note_hash_for_nullify, secret, @@ -40,7 +40,7 @@ impl NoteInterface for TokenNote { fn compute_nullifier_without_context(self) -> Field { let note_hash_for_nullify = compute_note_hash_for_consumption(self); - let secret = get_app_nullifier_secret_key(self.owner_nullifying_public_key_hash); + let secret = get_app_nullifier_secret_key(self.owner); poseidon2_hash([ note_hash_for_nullify, secret, @@ -52,25 +52,24 @@ impl NoteInterface for TokenNote { fn broadcast(self, context: &mut PrivateContext, slot: Field) { // We only bother inserting the note if non-empty to save funds on gas. if !(self.amount == U128::from_integer(0)) { - // TODO (ek): Disabled this until we fix the emit log types - // let encryption_pub_key = get_public_key(self.owner_nullifying_public_key_hash); - // emit_encrypted_log( - // context, - // (*context).this_address(), - // slot, - // Self::get_note_type_id(), - // encryption_pub_key, - // self.serialize_content(), - // ); + let encryption_pub_key = get_public_key(self.owner); + emit_encrypted_log( + context, + (*context).this_address(), + slot, + Self::get_note_type_id(), + encryption_pub_key, + self.serialize_content(), + ); } } } impl OwnedNote for TokenNote { - fn new(amount: U128, owner_nullifying_public_key_hash: Field) -> Self { + fn new(amount: U128, owner: AztecAddress) -> Self { Self { amount, - owner_nullifying_public_key_hash, + owner, randomness: unsafe_rand(), header: NoteHeader::empty(), } @@ -80,7 +79,7 @@ impl OwnedNote for TokenNote { self.amount } - fn get_owner_nullifying_public_key_hash(self) -> Field { - self.owner_nullifying_public_key_hash + fn get_owner(self) -> AztecAddress { + self.owner } } From cf27fc9ee147acb790a887dc7e6354a97d8d6e84 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Wed, 1 May 2024 17:21:47 +0000 Subject: [PATCH 26/93] Add support for both --- .../aztec/src/context/private_context.nr | 30 ++++++++++++-- .../aztec/src/oracle/nullifier_key.nr | 40 ++++++++++++++----- .../pxe/src/simulator_oracle/index.ts | 8 +++- .../simulator/src/acvm/oracle/oracle.ts | 13 +++++- .../simulator/src/acvm/oracle/typed_oracle.ts | 4 ++ .../simulator/src/client/db_oracle.ts | 12 +++++- .../simulator/src/client/view_data_oracle.ts | 13 +++++- 7 files changed, 103 insertions(+), 17 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index 1614df4670e..47b0a7709b5 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -4,7 +4,7 @@ use crate::{ oracle::{ arguments, returns, call_private_function::call_private_function_internal, enqueue_public_function_call::enqueue_public_function_call_internal, header::get_header_at, - nullifier_key::{get_nullifier_keys, NullifierKeys} + nullifier_key::{get_nullifier_keys, get_nullifier_keys_with_master_nullifier_public_key_hash, NullifierKeys} } }; use dep::protocol_types::{ @@ -212,9 +212,9 @@ impl PrivateContext { self.side_effect_counter = self.side_effect_counter + 1; } - pub fn request_app_nullifier_secret_key(&mut self, master_public_nullifying_key_hash: Field) -> Field { + pub fn request_app_nullifier_secret_key(&mut self, account: AztecAddress) -> Field { let keys = if self.nullifier_key.is_none() { - let keys = get_nullifier_keys(master_public_nullifying_key_hash); + let keys = get_nullifier_keys(account); let request = NullifierKeyValidationRequest { master_nullifier_public_key: keys.master_nullifier_public_key, app_nullifier_secret_key: keys.app_nullifier_secret_key @@ -226,7 +226,29 @@ impl PrivateContext { let keys = self.nullifier_key.unwrap_unchecked(); // If MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL is larger than 1, need to update the way the key pair is cached. assert(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL == 1); - assert(keys.master_nullifier_public_key_hash == master_public_nullifying_key_hash, "Cannot query nullifier key for more than one master_nullifying_public_key_hash per call"); + assert(keys.account == account, "Cannot query nullifier key for more than one account per call"); + keys + }; + keys.app_nullifier_secret_key + } + + // TODO(ek): Replace above with this + pub fn request_app_nullifier_secret_key_with_master_public_nullifying_key_hash(&mut self, master_public_nullifying_key_hash: Field) -> Field { + let keys = if self.nullifier_key.is_none() { + let keys = get_nullifier_keys_with_master_nullifier_public_key_hash(master_public_nullifying_key_hash); + let request = NullifierKeyValidationRequest { + master_nullifier_public_key: keys.master_nullifier_public_key, + app_nullifier_secret_key: keys.app_nullifier_secret_key + }; + self.nullifier_key_validation_requests.push(request); + self.nullifier_key = Option::some(keys); + keys + } else { + let keys = self.nullifier_key.unwrap_unchecked(); + // If MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL is larger than 1, need to update the way the key pair is cached. + assert(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL == 1); + // TODO: (ek) Enable this after we nuke all the accounts + // assert(keys.master_nullifier_public_key_hash == master_public_nullifying_key_hash, "Cannot query nullifier key for more than one master_nullifying_public_key_hash per call"); keys }; keys.app_nullifier_secret_key diff --git a/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr b/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr index 69cc8d00f4c..13b9fee6469 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr @@ -2,27 +2,49 @@ use dep::protocol_types::{address::AztecAddress, grumpkin_point::GrumpkinPoint, // Nullifier keys pertaining to a specific account struct NullifierKeys { - master_nullifier_public_key_hash: Field, + // TODO: (ek) Replace this with master_nullifier_public_key_hash + account: AztecAddress, master_nullifier_public_key: GrumpkinPoint, app_nullifier_secret_key: Field, } #[oracle(getNullifierKeys)] -fn get_nullifier_keys_oracle(_master_nullifier_public_key_hash: Field) -> [Field; 3] {} +fn get_nullifier_keys_oracle(_account: AztecAddress) -> [Field; 3] {} -unconstrained fn get_nullifier_keys_internal(master_nullifier_public_key_hash: Field) -> NullifierKeys { - let result = get_nullifier_keys_oracle(master_nullifier_public_key_hash); +unconstrained fn get_nullifier_keys_internal(account: AztecAddress) -> NullifierKeys { + let result = get_nullifier_keys_oracle(account); NullifierKeys { - master_nullifier_public_key_hash, + account, master_nullifier_public_key: GrumpkinPoint { x: result[0], y: result[1] }, app_nullifier_secret_key: result[2], } } -pub fn get_nullifier_keys(master_nullifier_public_key_hash: Field) -> NullifierKeys { - get_nullifier_keys_internal(master_nullifier_public_key_hash) +pub fn get_nullifier_keys(account: AztecAddress) -> NullifierKeys { + get_nullifier_keys_internal(account) } -pub fn get_app_nullifier_secret_key(master_nullifier_public_key_hash: Field) -> Field { - get_nullifier_keys_internal(master_nullifier_public_key_hash).app_nullifier_secret_key +pub fn get_app_nullifier_secret_key(account: AztecAddress) -> Field { + get_nullifier_keys_internal(account).app_nullifier_secret_key +} + +// TODO(ek): Replace the one above with this +#[oracle(getNullifierKeysWithMasterNullifierPublicKeyHash)] +fn get_nullifier_keys_with_master_nullifier_public_key_hash_oracle(_master_nullifier_public_key_hash: Field) -> [Field; 3] {} + +unconstrained fn get_nullifier_keys_with_master_nullifier_public_key_hash_internal(master_nullifier_public_key_hash: Field) -> NullifierKeys { + let result = get_nullifier_keys_with_master_nullifier_public_key_hash_oracle(master_nullifier_public_key_hash); + NullifierKeys { + account: AztecAddress::zero(), + master_nullifier_public_key: GrumpkinPoint { x: result[0], y: result[1] }, + app_nullifier_secret_key: result[2], + } +} + +pub fn get_nullifier_keys_with_master_nullifier_public_key_hash(master_nullifier_public_key_hash: Field) -> NullifierKeys { + get_nullifier_keys_with_master_nullifier_public_key_hash_internal(master_nullifier_public_key_hash) +} + +pub fn get_app_nullifier_secret_key_with_master_nullifier_public_key_hash(master_nullifier_public_key_hash: Field) -> Field { + get_nullifier_keys_with_master_nullifier_public_key_hash_internal(master_nullifier_public_key_hash).app_nullifier_secret_key } diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index ec3f317fddf..ab2978172c3 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -38,7 +38,13 @@ export class SimulatorOracle implements DBOracle { private log = createDebugLogger('aztec:pxe:simulator_oracle'), ) {} - async getNullifierKeys(masterNullifierPublicKeyHash: AztecAddress, contractAddress: AztecAddress): Promise { + async getNullifierKeys(accountAddress: AztecAddress, contractAddress: AztecAddress): Promise { + const masterNullifierPublicKey = await this.keyStore.getMasterNullifierPublicKey(accountAddress); + const appNullifierSecretKey = await this.keyStore.getAppNullifierSecretKey(accountAddress, contractAddress); + return { masterNullifierPublicKey, appNullifierSecretKey }; + } + + async getNullifierKeysWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: AztecAddress, contractAddress: AztecAddress): Promise { const masterNullifierPublicKey = await this.keyStore.getMasterNullifierPublicKeyWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash); const appNullifierSecretKey = await this.keyStore.getAppNullifierSecretKeyWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash, contractAddress); return { masterNullifierPublicKey, appNullifierSecretKey }; diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index d3d37b2efed..bc2aa3bc282 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -42,7 +42,18 @@ export class Oracle { return unpacked.map(toACVMField); } - async getNullifierKeys([masterNullifierPublicKeyHash]: ACVMField[]): Promise { + async getNullifierKeys([accountAddress]: ACVMField[]): Promise { + const { masterNullifierPublicKey, appNullifierSecretKey } = await this.typedOracle.getNullifierKeys( + fromACVMField(accountAddress), + ); + return [ + toACVMField(masterNullifierPublicKey.x), + toACVMField(masterNullifierPublicKey.y), + toACVMField(appNullifierSecretKey), + ]; + } + + async getNullifierKeysWithMasterNullifierPublicKeyHash([masterNullifierPublicKeyHash]: ACVMField[]): Promise { const { masterNullifierPublicKey, appNullifierSecretKey } = await this.typedOracle.getNullifierKeys( fromACVMField(masterNullifierPublicKeyHash), ); diff --git a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts index af2be1de22c..738c9e6066d 100644 --- a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts @@ -93,6 +93,10 @@ export abstract class TypedOracle { throw new OracleMethodNotAvailableError('getNullifierKeys'); } + getNullifierKeysWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr): Promise { + throw new OracleMethodNotAvailableError('getNullifierKeys'); + } + getPublicKeyAndPartialAddress(_address: AztecAddress): Promise { throw new OracleMethodNotAvailableError('getPublicKeyAndPartialAddress'); } diff --git a/yarn-project/simulator/src/client/db_oracle.ts b/yarn-project/simulator/src/client/db_oracle.ts index 4e10b61a3ec..eb949e3797c 100644 --- a/yarn-project/simulator/src/client/db_oracle.ts +++ b/yarn-project/simulator/src/client/db_oracle.ts @@ -72,6 +72,16 @@ export interface DBOracle extends CommitmentsDB { */ getPublicKeysForAddress(address: AztecAddress): Promise; + /** + * Retrieve nullifier keys associated with a specific account and app/contract address. + * + * @param accountAddress - The account address. + * @param contractAddress - The contract address. + * @returns A Promise that resolves to nullifier keys of a requested account and contract. + * @throws An error if the account is not registered in the database. + */ + getNullifierKeys(accountAddress: AztecAddress, contractAddress: AztecAddress): Promise; + /** * Retrieve nullifier keys associated with a specific account and app/contract address. * @@ -80,7 +90,7 @@ export interface DBOracle extends CommitmentsDB { * @returns A Promise that resolves to nullifier keys of a requested account and contract. * @throws An error if the account is not registered in the database. */ - getNullifierKeys(masterNullifierPublicKeyHash: Fr, contractAddress: AztecAddress): Promise; + getNullifierKeysWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr, contractAddress: AztecAddress): Promise; /** * Retrieves a set of notes stored in the database for a given contract address and storage slot. diff --git a/yarn-project/simulator/src/client/view_data_oracle.ts b/yarn-project/simulator/src/client/view_data_oracle.ts index 4ebf20fadbf..09236481ba4 100644 --- a/yarn-project/simulator/src/client/view_data_oracle.ts +++ b/yarn-project/simulator/src/client/view_data_oracle.ts @@ -34,6 +34,17 @@ export class ViewDataOracle extends TypedOracle { super(); } +/** + * Retrieve nullifier keys associated with a specific account and app/contract address. + * + * @param accountAddress - The account address. + * @returns A Promise that resolves to nullifier keys of a requested account and contract. + * @throws An error if the account is not registered in the database. + */ + public override getNullifierKeys(account: AztecAddress): Promise { + return this.db.getNullifierKeys(account, this.contractAddress); + } + /** * Retrieve nullifier keys associated with a specific account and app/contract address. * @@ -41,7 +52,7 @@ export class ViewDataOracle extends TypedOracle { * @returns A Promise that resolves to nullifier keys of a requested account and contract. * @throws An error if the account is not registered in the database. */ - public override getNullifierKeys(masterNullifierPublicKeyHash: Fr): Promise { + public override getNullifierKeysWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr): Promise { return this.db.getNullifierKeys(masterNullifierPublicKeyHash, this.contractAddress); } From 194df19b36aef093b785d5113a4a5e33891540c5 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Wed, 1 May 2024 18:20:42 +0000 Subject: [PATCH 27/93] Address comments --- .../aztec-nr/aztec/src/keys/getters.nr | 30 ++++++++++++-- .../aztec-nr/aztec/src/oracle/keys.nr | 21 ++-------- .../key_registry_contract/src/main.nr | 4 ++ .../contracts/test_contract/src/main.nr | 39 ++++++++++--------- .../types/src/address/public_keys_hash.nr | 4 +- .../end-to-end/src/e2e_key_registry.test.ts | 10 ++--- 6 files changed, 62 insertions(+), 46 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/keys/getters.nr b/noir-projects/aztec-nr/aztec/src/keys/getters.nr index 321441e7a7e..bbc0eb2dda8 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/getters.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/getters.nr @@ -16,7 +16,7 @@ use crate::hash::{ pedersen_hash, poseidon2_hash, }; -use crate::oracle; +use crate::oracle::keys::get_public_keys_and_partial_address; use crate::state_vars::{ map::derive_storage_slot_in_map, shared_mutable::shared_mutable_private_getter::SharedMutablePrivateGetter, @@ -35,17 +35,19 @@ pub fn get_fresh_nullifier_public_key_hash( address: AztecAddress, ) -> Field { // This is the storage slot of the nullifier_public_key inside the key registry contract + // TODO: (#6133) We should have this be directly imported from the other contract if possible, or at least this should not be this brittle let storage_slot_of_nullifier_public_key = 1; let derived_slot = derive_storage_slot_in_map(storage_slot_of_nullifier_public_key, address); - // It's a bit wonky because we need to know the delay for get_current_value_in_private to work correctly // We read from the canonical Key Registry + // TODO: (#6134) It's a bit wonky because we need to know the delay for get_current_value_in_private to work correctly. + // We should allow for this usecase without needing to hard code it here. let registry_private_getter: SharedMutablePrivateGetter = SharedMutablePrivateGetter::new(*context, AztecAddress::from_field(CANONICAL_KEY_REGISTRY_ADDRESS), derived_slot); let nullifier_public_key_hash_in_registry = registry_private_getter.get_current_value_in_private(); let nullifier_public_key_hash = if nullifier_public_key_hash_in_registry == 0 { - let keys = oracle::keys::get_public_keys(address); + let keys = get_original_public_keys_internal(address); poseidon2_hash(keys[PublicKeyType.NULLIFIER].serialize()) } else { nullifier_public_key_hash_in_registry @@ -53,3 +55,25 @@ pub fn get_fresh_nullifier_public_key_hash( nullifier_public_key_hash } + +// This constraint only works on keys that have not been rotated, otherwise this call will fail as the public keys are not constrained +fn get_original_public_keys_internal(address: AztecAddress) -> [GrumpkinPoint; 4] { + let (public_keys, partial_address) = get_public_keys_and_partial_address(address); + + let nullifier_pub_key = public_keys[0]; + let incoming_pub_key = public_keys[1]; + let outgoing_pub_key = public_keys[2]; + let tagging_pub_key = public_keys[3]; + + let computed_address = AztecAddress::compute_from_public_keys_and_partial_address( + nullifier_pub_key, + incoming_pub_key, + outgoing_pub_key, + tagging_pub_key, + partial_address, + ); + + assert(computed_address.eq(address)); + + [nullifier_pub_key, incoming_pub_key, outgoing_pub_key, tagging_pub_key] +} diff --git a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr index 98ea76ed617..d8737a0dd06 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr @@ -2,12 +2,7 @@ use dep::protocol_types::{ address::{ AztecAddress, PartialAddress, - PublicKeysHash, }, - constants::{ - GENERATOR_INDEX__PUBLIC_KEYS_HASH, - GENERATOR_INDEX__CONTRACT_ADDRESS_V1, - }, grumpkin_point::GrumpkinPoint, }; @@ -20,7 +15,7 @@ unconstrained fn get_public_keys_and_partial_address_oracle_wrapper(address: Azt get_public_keys_and_partial_address_oracle(address) } -pub fn get_public_keys(address: AztecAddress) -> [GrumpkinPoint; 4] { +fn get_public_keys_and_partial_address(address: AztecAddress) -> ([GrumpkinPoint; 4], PartialAddress) { let result = get_public_keys_and_partial_address_oracle_wrapper(address); let nullifier_pub_key = GrumpkinPoint::new(result[0], result[1]); @@ -29,15 +24,5 @@ pub fn get_public_keys(address: AztecAddress) -> [GrumpkinPoint; 4] { let tagging_pub_key = GrumpkinPoint::new(result[6], result[7]); let partial_address = PartialAddress::from_field(result[8]); - let computed_address = AztecAddress::compute_from_public_keys_and_partial_address( - nullifier_pub_key, - incoming_pub_key, - outgoing_pub_key, - tagging_pub_key, - partial_address, - ); - - assert(computed_address.eq(address)); - - [nullifier_pub_key, incoming_pub_key, outgoing_pub_key, tagging_pub_key] -} + ([nullifier_pub_key, incoming_pub_key, outgoing_pub_key, tagging_pub_key], partial_address) +} \ No newline at end of file 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 index 9d25af0055e..2d2111d07dd 100644 --- a/noir-projects/noir-contracts/contracts/key_registry_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/key_registry_contract/src/main.nr @@ -40,14 +40,18 @@ contract KeyRegistry { fn rotate_nullifier_public_key( address: AztecAddress, new_nullifier_public_key: GrumpkinPoint, + nonce: Field, ) { assert( !new_nullifier_public_key.is_zero(), "New nullifier public key must be non-zero" ); + // TODO: (#6137) if (!address.eq(context.msg_sender())) { assert_current_call_valid_authwit_public(&mut context, address); + } else { + assert(nonce == 0, "invalid nonce"); } let nullifier_key_registry = storage.nullifier_public_key_hash_registry.at(address); 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 7349bb9c2c5..29c71837291 100644 --- a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr @@ -10,7 +10,7 @@ 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, + constants::{MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, CANONICAL_KEY_REGISTRY_ADDRESS}, traits::{Serialize, ToField, FromField}, grumpkin_point::GrumpkinPoint }; @@ -377,6 +377,26 @@ contract Test { constant.value } + // This function is used in the e2e_state_vars to test the SharedMutablePrivateGetter in isolation + #[aztec(private)] + fn test_shared_mutable_private_getter( + contract_address_to_read: AztecAddress, + storage_slot_of_shared_mutable: Field + ) where T: FromField, T: ToField { + // It's a bit wonky because we need to know the delay for get_current_value_in_private to work correctly + let test: SharedMutablePrivateGetter = SharedMutablePrivateGetter::new( + context, + contract_address_to_read, + storage_slot_of_shared_mutable + ); + + let ret = test.get_current_value_in_private(); + + ret.to_field() + } + + // This function is used for testing the registry contract and fresh public key getters. If nothing exists in the registry, but we have added public + // keys to the pxe, this function will return nothing, but the public key getters will return the correct value #[aztec(private)] fn test_shared_mutable_private_getter_for_registry_contract( storage_slot_of_shared_mutable: Field, @@ -392,23 +412,6 @@ contract Test { nullifier_public_key } - #[aztec(private)] - fn test_shared_mutable_private_getter( - contract_address_to_read: AztecAddress, - storage_slot_of_shared_mutable: Field - ) -> AztecAddress { - // It's a bit wonky because we need to know the delay for get_current_value_in_private to work correctly - let test: SharedMutablePrivateGetter = SharedMutablePrivateGetter::new( - context, - contract_address_to_read, - storage_slot_of_shared_mutable - ); - - let authorized = test.get_current_value_in_private(); - - authorized - } - #[aztec(private)] fn test_nullifier_key_freshness( address: AztecAddress, diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/address/public_keys_hash.nr b/noir-projects/noir-protocol-circuits/crates/types/src/address/public_keys_hash.nr index 9ea508fc140..bff82cc1644 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/address/public_keys_hash.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/address/public_keys_hash.nr @@ -38,7 +38,7 @@ impl PublicKeysHash { Self { inner: field } } - // TODO(#5830): update this + // TODO(#5830): When we do this refactor, rename compute_new -> compute pub fn compute(public_key: GrumpkinPoint) -> Self { PublicKeysHash::from_field( pedersen_hash( @@ -51,7 +51,7 @@ impl PublicKeysHash { ) } - // TODO(#5830): Use this as the new one + // TODO(#5830): When we do this refactor, rename compute_new -> compute pub fn compute_new( nullifier_public_key: GrumpkinPoint, incoming_public_key: GrumpkinPoint, 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 index 092ee32682d..ebfc6a07fa1 100644 --- a/yarn-project/end-to-end/src/e2e_key_registry.test.ts +++ b/yarn-project/end-to-end/src/e2e_key_registry.test.ts @@ -106,7 +106,7 @@ describe('Key Registry', () => { await expect( keyRegistry .withWallet(wallets[0]) - .methods.rotate_nullifier_public_key(wallets[0].getAddress(), Point.ZERO) + .methods.rotate_nullifier_public_key(wallets[0].getAddress(), Point.ZERO, new Fr(1)) .send() .wait(), ).rejects.toThrow('New nullifier public key must be non-zero'); @@ -116,7 +116,7 @@ describe('Key Registry', () => { await expect( keyRegistry .withWallet(wallets[0]) - .methods.rotate_nullifier_public_key(wallets[1].getAddress(), Point.random()) + .methods.rotate_nullifier_public_key(wallets[1].getAddress(), Point.random(), new Fr(1)) .send() .wait(), ).rejects.toThrow('Assertion failed: Message not authorized by account'); @@ -186,7 +186,7 @@ describe('Key Registry', () => { it('we call the key registry to rotate our nullifier key', async () => { await keyRegistry .withWallet(wallets[0]) - .methods.rotate_nullifier_public_key(wallets[0].getAddress(), firstNewMasterNullifierPublicKey) + .methods.rotate_nullifier_public_key(wallets[0].getAddress(), firstNewMasterNullifierPublicKey, new Fr(1)) .send() .wait(); @@ -215,7 +215,7 @@ describe('Key Registry', () => { it(`wallet 1 rotates wallet 0's nullifying public key with an authwit`, async () => { const action = keyRegistry .withWallet(wallets[1]) - .methods.rotate_nullifier_public_key(wallets[0].getAddress(), secondNewMasterNullifierPublicKey); + .methods.rotate_nullifier_public_key(wallets[0].getAddress(), secondNewMasterNullifierPublicKey, new Fr(1)); await wallets[0] .setPublicAuthWit({ caller: wallets[1].getCompleteAddress().address, action }, true) @@ -422,7 +422,7 @@ describe('Key Registry', () => { it('we rotate the nullifier key and check that the key is fresh', async () => { await keyRegistry .withWallet(wallets[0]) - .methods.rotate_nullifier_public_key(wallets[0].getAddress(), newMasterNullifierPublicKey) + .methods.rotate_nullifier_public_key(wallets[0].getAddress(), newMasterNullifierPublicKey, new Fr(1)) .send() .wait(); From a85f5131a497450ce04838369381a613e167f833 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Wed, 1 May 2024 19:45:14 +0000 Subject: [PATCH 28/93] fix --- yarn-project/end-to-end/src/e2e_key_registry.test.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 index ebfc6a07fa1..b801beed9e4 100644 --- a/yarn-project/end-to-end/src/e2e_key_registry.test.ts +++ b/yarn-project/end-to-end/src/e2e_key_registry.test.ts @@ -106,7 +106,7 @@ describe('Key Registry', () => { await expect( keyRegistry .withWallet(wallets[0]) - .methods.rotate_nullifier_public_key(wallets[0].getAddress(), Point.ZERO, new Fr(1)) + .methods.rotate_nullifier_public_key(wallets[0].getAddress(), Point.ZERO, Fr.ZERO) .send() .wait(), ).rejects.toThrow('New nullifier public key must be non-zero'); @@ -116,7 +116,7 @@ describe('Key Registry', () => { await expect( keyRegistry .withWallet(wallets[0]) - .methods.rotate_nullifier_public_key(wallets[1].getAddress(), Point.random(), new Fr(1)) + .methods.rotate_nullifier_public_key(wallets[1].getAddress(), Point.random(), Fr.ZERO) .send() .wait(), ).rejects.toThrow('Assertion failed: Message not authorized by account'); @@ -186,7 +186,7 @@ describe('Key Registry', () => { it('we call the key registry to rotate our nullifier key', async () => { await keyRegistry .withWallet(wallets[0]) - .methods.rotate_nullifier_public_key(wallets[0].getAddress(), firstNewMasterNullifierPublicKey, new Fr(1)) + .methods.rotate_nullifier_public_key(wallets[0].getAddress(), firstNewMasterNullifierPublicKey, Fr.ZERO) .send() .wait(); @@ -215,7 +215,7 @@ describe('Key Registry', () => { it(`wallet 1 rotates wallet 0's nullifying public key with an authwit`, async () => { const action = keyRegistry .withWallet(wallets[1]) - .methods.rotate_nullifier_public_key(wallets[0].getAddress(), secondNewMasterNullifierPublicKey, new Fr(1)); + .methods.rotate_nullifier_public_key(wallets[0].getAddress(), secondNewMasterNullifierPublicKey, Fr.ZERO); await wallets[0] .setPublicAuthWit({ caller: wallets[1].getCompleteAddress().address, action }, true) @@ -422,7 +422,7 @@ describe('Key Registry', () => { it('we rotate the nullifier key and check that the key is fresh', async () => { await keyRegistry .withWallet(wallets[0]) - .methods.rotate_nullifier_public_key(wallets[0].getAddress(), newMasterNullifierPublicKey, new Fr(1)) + .methods.rotate_nullifier_public_key(wallets[0].getAddress(), newMasterNullifierPublicKey, Fr.ZERO) .send() .wait(); From 94db9f592074157afc8c7af2bed61f25f58bc603 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Wed, 1 May 2024 20:01:05 +0000 Subject: [PATCH 29/93] Okay --- .../noir-contracts/contracts/test_contract/src/main.nr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 29c71837291..74f0e049512 100644 --- a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr @@ -382,7 +382,7 @@ contract Test { fn test_shared_mutable_private_getter( contract_address_to_read: AztecAddress, storage_slot_of_shared_mutable: Field - ) where T: FromField, T: ToField { + ) -> Field where T: FromField, T: ToField { // It's a bit wonky because we need to know the delay for get_current_value_in_private to work correctly let test: SharedMutablePrivateGetter = SharedMutablePrivateGetter::new( context, From 6f0d45777d7930a8e4c5d23a4b0c2b22bdd83423 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Thu, 2 May 2024 12:39:35 +0000 Subject: [PATCH 30/93] fix good ? --- .../aztec/src/oracle/get_public_key.nr | 19 ++++++++++++++ .../token_contract/src/types/balances_map.nr | 10 +++++--- .../token_contract/src/types/token_note.nr | 25 +++++++++---------- .../circuit-types/src/keys/key_store.ts | 2 ++ yarn-project/key-store/src/test_key_store.ts | 16 +++++++++++- .../pxe/src/simulator_oracle/index.ts | 8 +++++- .../simulator/src/acvm/oracle/oracle.ts | 6 +++++ .../simulator/src/acvm/oracle/typed_oracle.ts | 4 +++ .../simulator/src/client/db_oracle.ts | 2 ++ .../simulator/src/client/view_data_oracle.ts | 4 +++ 10 files changed, 78 insertions(+), 18 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr b/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr index a509e8c1b54..f09ba005bbb 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr @@ -18,3 +18,22 @@ pub fn get_public_key(address: AztecAddress) -> GrumpkinPoint { pub_key } + +#[oracle(getPublicKeyAndPartialAddressWithMasterNullifierPublicKeyHash)] +fn get_public_key_and_partial_address_with_master_nullifier_public_key_hash_oracle(master_nullifier_public_key_hash: Field) -> [Field; 3] {} + +unconstrained fn get_public_key_and_partial_address_with_master_nullifier_public_key_hash_internal(master_nullifier_public_key_hash: Field) -> [Field; 3] { + get_public_key_and_partial_address_with_master_nullifier_public_key_hash_oracle(master_nullifier_public_key_hash) +} + +pub fn get_public_key_with_master_nullifier_public_key_hash(master_nullifier_public_key_hash: Field) -> GrumpkinPoint { + let result = get_public_key_and_partial_address_with_master_nullifier_public_key_hash_internal(master_nullifier_public_key_hash); + let pub_key = GrumpkinPoint::new(result[0], result[1]); + let partial_address = PartialAddress::from_field(result[2]); + + // TODO(#5830): disabling the following constraint until we update the oracle according to the new key scheme + // let calculated_address = AztecAddress::compute(PublicKeysHash::compute(pub_key), partial_address); + // assert(calculated_address.eq(address)); + + pub_key +} diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr index 605d5a5a647..e61a07c5c12 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr @@ -5,7 +5,8 @@ use dep::aztec::prelude::{ use dep::aztec::{ context::{PublicContext, Context}, hash::pedersen_hash, protocol_types::constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, - note::{note_getter::view_notes, note_getter_options::SortOrder} + note::{note_getter::view_notes, note_getter_options::SortOrder}, + keys::getters::get_fresh_nullifier_public_key_hash, }; use crate::types::token_note::{TokenNote, OwnedNote}; @@ -60,8 +61,11 @@ impl BalancesMap { owner: AztecAddress, addend: U128 ) where T: NoteInterface + OwnedNote { - // Lookup in registry - let nullifier_public_key_hash = 0; + // We fetch the nullifier public key hash in the registry / from our PXE + let nullifier_public_key_hash = get_fresh_nullifier_public_key_hash(self.map.context.private.unwrap(), owner); + + dep::aztec::oracle::debug_log::debug_log_array_with_prefix("Nullifier Pub Key Hash", [nullifier_public_key_hash]); + let mut addend_note = T::new(addend, nullifier_public_key_hash); // docs:start:insert diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr index f37b35c7c83..a790a9238ac 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr @@ -2,7 +2,7 @@ use dep::aztec::{ prelude::{AztecAddress, NoteHeader, NoteInterface, PrivateContext, emit_encrypted_log}, protocol_types::constants::GENERATOR_INDEX__NOTE_NULLIFIER, note::utils::compute_note_hash_for_consumption, hash::poseidon2_hash, - oracle::{unsafe_rand::unsafe_rand, nullifier_key::get_app_nullifier_secret_key, get_public_key::get_public_key} + oracle::{unsafe_rand::unsafe_rand, nullifier_key::get_app_nullifier_secret_key_with_master_nullifier_public_key_hash, get_public_key::get_public_key_with_master_nullifier_public_key_hash} }; trait OwnedNote { @@ -29,7 +29,7 @@ impl NoteInterface for TokenNote { // docs:start:nullifier fn compute_nullifier(self, context: &mut PrivateContext) -> Field { let note_hash_for_nullify = compute_note_hash_for_consumption(self); - let secret = context.request_app_nullifier_secret_key(self.owner_nullifying_public_key_hash); + let secret = context.request_app_nullifier_secret_key_with_master_public_nullifying_key_hash(self.owner_nullifying_public_key_hash); poseidon2_hash([ note_hash_for_nullify, secret, @@ -40,7 +40,7 @@ impl NoteInterface for TokenNote { fn compute_nullifier_without_context(self) -> Field { let note_hash_for_nullify = compute_note_hash_for_consumption(self); - let secret = get_app_nullifier_secret_key(self.owner_nullifying_public_key_hash); + let secret = get_app_nullifier_secret_key_with_master_nullifier_public_key_hash(self.owner_nullifying_public_key_hash); poseidon2_hash([ note_hash_for_nullify, secret, @@ -52,16 +52,15 @@ impl NoteInterface for TokenNote { fn broadcast(self, context: &mut PrivateContext, slot: Field) { // We only bother inserting the note if non-empty to save funds on gas. if !(self.amount == U128::from_integer(0)) { - // TODO (ek): Disabled this until we fix the emit log types - // let encryption_pub_key = get_public_key(self.owner_nullifying_public_key_hash); - // emit_encrypted_log( - // context, - // (*context).this_address(), - // slot, - // Self::get_note_type_id(), - // encryption_pub_key, - // self.serialize_content(), - // ); + let encryption_pub_key = get_public_key_with_master_nullifier_public_key_hash(self.owner_nullifying_public_key_hash); + emit_encrypted_log( + context, + (*context).this_address(), + slot, + Self::get_note_type_id(), + encryption_pub_key, + self.serialize_content(), + ); } } } diff --git a/yarn-project/circuit-types/src/keys/key_store.ts b/yarn-project/circuit-types/src/keys/key_store.ts index 7fc0a5988cb..c833f40301d 100644 --- a/yarn-project/circuit-types/src/keys/key_store.ts +++ b/yarn-project/circuit-types/src/keys/key_store.ts @@ -135,6 +135,8 @@ export interface KeyStore { */ getPublicKeysHash(account: AztecAddress): Promise; + getAccountAddressForMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr): AztecAddress; + /** * This is used to register a recipient / for storing public keys of an address * @param accountAddress - The account address to store keys for. diff --git a/yarn-project/key-store/src/test_key_store.ts b/yarn-project/key-store/src/test_key_store.ts index 752660e8953..3454963971d 100644 --- a/yarn-project/key-store/src/test_key_store.ts +++ b/yarn-project/key-store/src/test_key_store.ts @@ -72,9 +72,11 @@ export class TestKeyStore implements KeyStore { await this.#keys.set(`${accountAddress.toString()}-tpk_m`, masterTaggingPublicKey.toBuffer()); const masterNullifierPublicKeyHash = poseidon2Hash(masterNullifierPublicKey.toFields()); - // We save nullifier keys to db under the master nullifier key hash + + // We save nullifier keys and account address to db under the master nullifier key hash await this.#keys.set(`${masterNullifierPublicKeyHash.toString()}-nsk_m`, masterNullifierSecretKey.toBuffer()); await this.#keys.set(`${masterNullifierPublicKeyHash.toString()}-npk_m`, masterNullifierPublicKey.toBuffer()); + await this.#keys.set(`${masterNullifierPublicKeyHash.toString()}-accountAddress`, accountAddress.toBuffer()); // At last, we return the newly derived account address return Promise.resolve(accountAddress); @@ -333,6 +335,18 @@ export class TestKeyStore implements KeyStore { return Promise.resolve(Fr.fromBuffer(publicKeysHashBuffer)); } + public getAccountAddressForMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr): AztecAddress { + const accountAddressBuffer = this.#keys.get(`${masterNullifierPublicKeyHash.toString()}-accountAddress`); + + if (!accountAddressBuffer) { + throw new Error( + `Master nullifier public key hash ${masterNullifierPublicKeyHash.toString()} does not exist.`, + ); + } + + return AztecAddress.fromBuffer(accountAddressBuffer); + } + // TODO(#5834): Re-add separation between recipients and accounts in keystore. public async addPublicKeysForAccount( accountAddress: AztecAddress, diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index ab2978172c3..7e4ee2fdd36 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -9,7 +9,7 @@ import { type SiblingPath, } from '@aztec/circuit-types'; import { - type AztecAddress, + AztecAddress, type CompleteAddress, type Fr, type FunctionSelector, @@ -61,6 +61,12 @@ export class SimulatorOracle implements DBOracle { return completeAddress; } + // TODO: #5834 + getCompleteAddressWithMasterNullifierPublicKey(masterNullifierPublicKey: Fr): Promise { + const address = this.keyStore.getAccountAddressForMasterNullifierPublicKeyHash(masterNullifierPublicKey); + return this.getCompleteAddress(address); + } + async getContractInstance(address: AztecAddress): Promise { const instance = await this.db.getContractInstance(address); if (!instance) { diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index bc2aa3bc282..d24387315a3 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -72,6 +72,12 @@ export class Oracle { return [publicKey.x, publicKey.y, partialAddress].map(toACVMField); } + // TODO: #5834 Nuke this + async getPublicKeyAndPartialAddressWithMasterNullifierPublicKeyHash([masterNullifierPublicKeyHash]: ACVMField[]) { + const { publicKey, partialAddress } = await this.typedOracle.getCompleteAddressWithMasterNullifierPublicKey(fromACVMField(masterNullifierPublicKeyHash)); + return [publicKey.x, publicKey.y, partialAddress].map(toACVMField); + } + async getContractInstance([address]: ACVMField[]) { const instance = await this.typedOracle.getContractInstance(AztecAddress.fromField(fromACVMField(address))); diff --git a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts index 738c9e6066d..92481d7898c 100644 --- a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts @@ -136,6 +136,10 @@ export abstract class TypedOracle { throw new OracleMethodNotAvailableError('getCompleteAddress'); } + getCompleteAddressWithMasterNullifierPublicKey(_masterNullifierPublicKeyHash: Fr): Promise { + throw new OracleMethodNotAvailableError('getCompleteAddressWithMasterNullifierPublicKey'); + } + getAuthWitness(_messageHash: Fr): Promise { throw new OracleMethodNotAvailableError('getAuthWitness'); } diff --git a/yarn-project/simulator/src/client/db_oracle.ts b/yarn-project/simulator/src/client/db_oracle.ts index eb949e3797c..58689cd2b89 100644 --- a/yarn-project/simulator/src/client/db_oracle.ts +++ b/yarn-project/simulator/src/client/db_oracle.ts @@ -50,6 +50,8 @@ export interface DBOracle extends CommitmentsDB { */ getCompleteAddress(address: AztecAddress): Promise; + getCompleteAddressWithMasterNullifierPublicKey(masterNullifierPublicKey: Fr): Promise; + /** * Retrieve the auth witness for a given message hash. * @param messageHash - The message hash. diff --git a/yarn-project/simulator/src/client/view_data_oracle.ts b/yarn-project/simulator/src/client/view_data_oracle.ts index 09236481ba4..4360e7f8c18 100644 --- a/yarn-project/simulator/src/client/view_data_oracle.ts +++ b/yarn-project/simulator/src/client/view_data_oracle.ts @@ -147,6 +147,10 @@ export class ViewDataOracle extends TypedOracle { return this.db.getCompleteAddress(address); } + public override getCompleteAddressWithMasterNullifierPublicKey(masterNullifierPublicKeyHash: Fr): Promise { + return this.db.getCompleteAddressWithMasterNullifierPublicKey(masterNullifierPublicKeyHash); + } + /** * Returns a contract instance associated with an address or throws if not found. * @param address - Address. From 2f19996a9455198548229411e6dcb1efc4ba41a0 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Thu, 2 May 2024 13:48:32 +0000 Subject: [PATCH 31/93] fix --- yarn-project/key-store/src/test_key_store.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/yarn-project/key-store/src/test_key_store.ts b/yarn-project/key-store/src/test_key_store.ts index 3454963971d..1dd1b51c288 100644 --- a/yarn-project/key-store/src/test_key_store.ts +++ b/yarn-project/key-store/src/test_key_store.ts @@ -61,7 +61,7 @@ export class TestKeyStore implements KeyStore { // We save the keys to db associated with the account address await this.#keys.set(`${accountAddress.toString()}-public_keys_hash`, publicKeysHash.toBuffer()); - await this.#keys.set(`${accountAddress.toString()}-nsk_m`, masterNullifierSecretKey.toBuffer()); + await this.#keys.set(`${accountAddress.toString()}-nsk_m-account`, masterNullifierSecretKey.toBuffer()); await this.#keys.set(`${accountAddress.toString()}-ivsk_m`, masterIncomingViewingSecretKey.toBuffer()); await this.#keys.set(`${accountAddress.toString()}-ovsk_m`, masterOutgoingViewingSecretKey.toBuffer()); await this.#keys.set(`${accountAddress.toString()}-tsk_m`, masterTaggingSecretKey.toBuffer()); @@ -74,7 +74,7 @@ export class TestKeyStore implements KeyStore { const masterNullifierPublicKeyHash = poseidon2Hash(masterNullifierPublicKey.toFields()); // We save nullifier keys and account address to db under the master nullifier key hash - await this.#keys.set(`${masterNullifierPublicKeyHash.toString()}-nsk_m`, masterNullifierSecretKey.toBuffer()); + await this.#keys.set(`${masterNullifierPublicKeyHash.toString()}-nsk_m-mnpk`, masterNullifierSecretKey.toBuffer()); await this.#keys.set(`${masterNullifierPublicKeyHash.toString()}-npk_m`, masterNullifierPublicKey.toBuffer()); await this.#keys.set(`${masterNullifierPublicKeyHash.toString()}-accountAddress`, accountAddress.toBuffer()); @@ -88,8 +88,8 @@ export class TestKeyStore implements KeyStore { */ public getAccounts(): Promise { const allMapKeys = Array.from(this.#keys.keys()); - // We return account addresses based on the map keys that end with '-nsk_m' - const accounts = allMapKeys.filter(key => key.endsWith('-nsk_m')).map(key => key.split('-')[0]); + // We return account addresses based on the map keys that end with '-nsk_m-account' + const accounts = allMapKeys.filter(key => key.endsWith('-nsk_m-account')).map(key => key.split('-')[0]); return Promise.resolve(accounts.map(account => AztecAddress.fromString(account))); } @@ -181,7 +181,7 @@ export class TestKeyStore implements KeyStore { * @returns A Promise that resolves to the application nullifier secret key. */ public async getAppNullifierSecretKey(account: AztecAddress, app: AztecAddress): Promise { - const masterNullifierSecretKeyBuffer = this.#keys.get(`${account.toString()}-nsk_m`); + const masterNullifierSecretKeyBuffer = this.#keys.get(`${account.toString()}-nsk_m-account`); if (!masterNullifierSecretKeyBuffer) { throw new Error( `Account ${account.toString()} does not exist. Registered accounts: ${await this.getAccounts()}.`, @@ -200,7 +200,7 @@ export class TestKeyStore implements KeyStore { * @returns A Promise that resolves to the application nullifier secret key. */ getAppNullifierSecretKeyWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr, app: AztecAddress): Promise { - const masterNullifierSecretKeyBuffer = this.#keys.get(`${masterNullifierPublicKeyHash.toString()}-nsk_m`); + const masterNullifierSecretKeyBuffer = this.#keys.get(`${masterNullifierPublicKeyHash.toString()}-nsk_m-mnpk`); if (!masterNullifierSecretKeyBuffer) { throw new Error( `Master nullifier public keys hash ${masterNullifierPublicKeyHash.toString()} does not exist.`, @@ -278,7 +278,7 @@ export class TestKeyStore implements KeyStore { // We extract the account address from the map key const accountAddress = key.split('-')[0]; // We fetch the secret key and return it - const masterNullifierSecretKeyBuffer = this.#keys.get(`${accountAddress.toString()}-nsk_m`); + const masterNullifierSecretKeyBuffer = this.#keys.get(`${accountAddress.toString()}-nsk_m-account`); if (!masterNullifierSecretKeyBuffer) { throw new Error(`Could not find master nullifier secret key for account ${accountAddress.toString()}`); } From fffee53bc4a14aee49b63bf2a131adfeda4028f5 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Thu, 2 May 2024 13:50:24 +0000 Subject: [PATCH 32/93] fmt --- .../circuit-types/src/keys/key_store.ts | 5 ++- yarn-project/key-store/src/test_key_store.ts | 33 +++++++++---------- .../pxe/src/simulator_oracle/index.ts | 16 ++++++--- .../simulator/src/acvm/oracle/oracle.ts | 8 +++-- .../simulator/src/acvm/oracle/typed_oracle.ts | 2 +- .../simulator/src/client/db_oracle.ts | 5 ++- .../simulator/src/client/view_data_oracle.ts | 22 ++++++++----- 7 files changed, 55 insertions(+), 36 deletions(-) diff --git a/yarn-project/circuit-types/src/keys/key_store.ts b/yarn-project/circuit-types/src/keys/key_store.ts index c833f40301d..3fb41d6c0e1 100644 --- a/yarn-project/circuit-types/src/keys/key_store.ts +++ b/yarn-project/circuit-types/src/keys/key_store.ts @@ -87,7 +87,10 @@ export interface KeyStore { * @param app - The application address to retrieve the nullifier secret key for. * @returns A Promise that resolves to the application nullifier secret key. */ - getAppNullifierSecretKeyWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr, app: AztecAddress): Promise; + getAppNullifierSecretKeyWithMasterNullifierPublicKeyHash( + masterNullifierPublicKeyHash: Fr, + app: AztecAddress, + ): Promise; /** * Retrieves application incoming viewing secret key. diff --git a/yarn-project/key-store/src/test_key_store.ts b/yarn-project/key-store/src/test_key_store.ts index 1dd1b51c288..6e811730470 100644 --- a/yarn-project/key-store/src/test_key_store.ts +++ b/yarn-project/key-store/src/test_key_store.ts @@ -109,7 +109,7 @@ export class TestKeyStore implements KeyStore { return Promise.resolve(Point.fromBuffer(masterNullifierPublicKeyBuffer)); } - /** + /** * Gets the master nullifier public key for a given master nullifier public key hash. * @throws If the master nullifier public key hash does not exist in the key store. * @param masterNullifierPublicKeyHash - The master nullifier public key hash for which to retrieve the master nullifier public key. @@ -118,9 +118,7 @@ export class TestKeyStore implements KeyStore { getMasterNullifierPublicKeyWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr): Promise { const masterNullifierPublicKeyBuffer = this.#keys.get(`${masterNullifierPublicKeyHash.toString()}-npk_m`); if (!masterNullifierPublicKeyBuffer) { - throw new Error( - `Master nullifier public keys hash ${masterNullifierPublicKeyHash.toString()} does not exist.`, - ); + throw new Error(`Master nullifier public keys hash ${masterNullifierPublicKeyHash.toString()} does not exist.`); } return Promise.resolve(Point.fromBuffer(masterNullifierPublicKeyBuffer)); } @@ -192,19 +190,20 @@ export class TestKeyStore implements KeyStore { return Promise.resolve(appNullifierSecretKey); } -/** - * Retrieves application nullifier secret key. - * @throws If the masterNullifierPublicKeyHash does not exist in the key store. - * @param masterNullifierPublicKeyHash - The account to retrieve the application nullifier secret key for. - * @param app - The application address to retrieve the nullifier secret key for. - * @returns A Promise that resolves to the application nullifier secret key. - */ - getAppNullifierSecretKeyWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr, app: AztecAddress): Promise { + /** + * Retrieves application nullifier secret key. + * @throws If the masterNullifierPublicKeyHash does not exist in the key store. + * @param masterNullifierPublicKeyHash - The account to retrieve the application nullifier secret key for. + * @param app - The application address to retrieve the nullifier secret key for. + * @returns A Promise that resolves to the application nullifier secret key. + */ + getAppNullifierSecretKeyWithMasterNullifierPublicKeyHash( + masterNullifierPublicKeyHash: Fr, + app: AztecAddress, + ): Promise { const masterNullifierSecretKeyBuffer = this.#keys.get(`${masterNullifierPublicKeyHash.toString()}-nsk_m-mnpk`); if (!masterNullifierSecretKeyBuffer) { - throw new Error( - `Master nullifier public keys hash ${masterNullifierPublicKeyHash.toString()} does not exist.`, - ); + throw new Error(`Master nullifier public keys hash ${masterNullifierPublicKeyHash.toString()} does not exist.`); } const masterNullifierSecretKey = GrumpkinScalar.fromBuffer(masterNullifierSecretKeyBuffer); const appNullifierSecretKey = computeAppNullifierSecretKey(masterNullifierSecretKey, app); @@ -339,9 +338,7 @@ export class TestKeyStore implements KeyStore { const accountAddressBuffer = this.#keys.get(`${masterNullifierPublicKeyHash.toString()}-accountAddress`); if (!accountAddressBuffer) { - throw new Error( - `Master nullifier public key hash ${masterNullifierPublicKeyHash.toString()} does not exist.`, - ); + throw new Error(`Master nullifier public key hash ${masterNullifierPublicKeyHash.toString()} does not exist.`); } return AztecAddress.fromBuffer(accountAddressBuffer); diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index 7e4ee2fdd36..ff0dcd28648 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -9,7 +9,7 @@ import { type SiblingPath, } from '@aztec/circuit-types'; import { - AztecAddress, + type AztecAddress, type CompleteAddress, type Fr, type FunctionSelector, @@ -44,9 +44,17 @@ export class SimulatorOracle implements DBOracle { return { masterNullifierPublicKey, appNullifierSecretKey }; } - async getNullifierKeysWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: AztecAddress, contractAddress: AztecAddress): Promise { - const masterNullifierPublicKey = await this.keyStore.getMasterNullifierPublicKeyWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash); - const appNullifierSecretKey = await this.keyStore.getAppNullifierSecretKeyWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash, contractAddress); + async getNullifierKeysWithMasterNullifierPublicKeyHash( + masterNullifierPublicKeyHash: AztecAddress, + contractAddress: AztecAddress, + ): Promise { + const masterNullifierPublicKey = await this.keyStore.getMasterNullifierPublicKeyWithMasterNullifierPublicKeyHash( + masterNullifierPublicKeyHash, + ); + const appNullifierSecretKey = await this.keyStore.getAppNullifierSecretKeyWithMasterNullifierPublicKeyHash( + masterNullifierPublicKeyHash, + contractAddress, + ); return { masterNullifierPublicKey, appNullifierSecretKey }; } diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index d24387315a3..099e794ec32 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -53,7 +53,9 @@ export class Oracle { ]; } - async getNullifierKeysWithMasterNullifierPublicKeyHash([masterNullifierPublicKeyHash]: ACVMField[]): Promise { + async getNullifierKeysWithMasterNullifierPublicKeyHash([masterNullifierPublicKeyHash]: ACVMField[]): Promise< + ACVMField[] + > { const { masterNullifierPublicKey, appNullifierSecretKey } = await this.typedOracle.getNullifierKeys( fromACVMField(masterNullifierPublicKeyHash), ); @@ -74,7 +76,9 @@ export class Oracle { // TODO: #5834 Nuke this async getPublicKeyAndPartialAddressWithMasterNullifierPublicKeyHash([masterNullifierPublicKeyHash]: ACVMField[]) { - const { publicKey, partialAddress } = await this.typedOracle.getCompleteAddressWithMasterNullifierPublicKey(fromACVMField(masterNullifierPublicKeyHash)); + const { publicKey, partialAddress } = await this.typedOracle.getCompleteAddressWithMasterNullifierPublicKey( + fromACVMField(masterNullifierPublicKeyHash), + ); return [publicKey.x, publicKey.y, partialAddress].map(toACVMField); } diff --git a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts index 92481d7898c..6e36bdd0f15 100644 --- a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts @@ -93,7 +93,7 @@ export abstract class TypedOracle { throw new OracleMethodNotAvailableError('getNullifierKeys'); } - getNullifierKeysWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr): Promise { + getNullifierKeysWithMasterNullifierPublicKeyHash(_masterNullifierPublicKeyHash: Fr): Promise { throw new OracleMethodNotAvailableError('getNullifierKeys'); } diff --git a/yarn-project/simulator/src/client/db_oracle.ts b/yarn-project/simulator/src/client/db_oracle.ts index 58689cd2b89..b133861d6af 100644 --- a/yarn-project/simulator/src/client/db_oracle.ts +++ b/yarn-project/simulator/src/client/db_oracle.ts @@ -92,7 +92,10 @@ export interface DBOracle extends CommitmentsDB { * @returns A Promise that resolves to nullifier keys of a requested account and contract. * @throws An error if the account is not registered in the database. */ - getNullifierKeysWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr, contractAddress: AztecAddress): Promise; + getNullifierKeysWithMasterNullifierPublicKeyHash( + masterNullifierPublicKeyHash: Fr, + contractAddress: AztecAddress, + ): Promise; /** * Retrieves a set of notes stored in the database for a given contract address and storage slot. diff --git a/yarn-project/simulator/src/client/view_data_oracle.ts b/yarn-project/simulator/src/client/view_data_oracle.ts index 4360e7f8c18..c8a34bb8e86 100644 --- a/yarn-project/simulator/src/client/view_data_oracle.ts +++ b/yarn-project/simulator/src/client/view_data_oracle.ts @@ -34,13 +34,13 @@ export class ViewDataOracle extends TypedOracle { super(); } -/** - * Retrieve nullifier keys associated with a specific account and app/contract address. - * - * @param accountAddress - The account address. - * @returns A Promise that resolves to nullifier keys of a requested account and contract. - * @throws An error if the account is not registered in the database. - */ + /** + * Retrieve nullifier keys associated with a specific account and app/contract address. + * + * @param accountAddress - The account address. + * @returns A Promise that resolves to nullifier keys of a requested account and contract. + * @throws An error if the account is not registered in the database. + */ public override getNullifierKeys(account: AztecAddress): Promise { return this.db.getNullifierKeys(account, this.contractAddress); } @@ -52,7 +52,9 @@ export class ViewDataOracle extends TypedOracle { * @returns A Promise that resolves to nullifier keys of a requested account and contract. * @throws An error if the account is not registered in the database. */ - public override getNullifierKeysWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr): Promise { + public override getNullifierKeysWithMasterNullifierPublicKeyHash( + masterNullifierPublicKeyHash: Fr, + ): Promise { return this.db.getNullifierKeys(masterNullifierPublicKeyHash, this.contractAddress); } @@ -147,7 +149,9 @@ export class ViewDataOracle extends TypedOracle { return this.db.getCompleteAddress(address); } - public override getCompleteAddressWithMasterNullifierPublicKey(masterNullifierPublicKeyHash: Fr): Promise { + public override getCompleteAddressWithMasterNullifierPublicKey( + masterNullifierPublicKeyHash: Fr, + ): Promise { return this.db.getCompleteAddressWithMasterNullifierPublicKey(masterNullifierPublicKeyHash); } From 4416ccb9daa5e89e4f7174bab6a2e046a51d4c98 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Thu, 2 May 2024 14:16:22 +0000 Subject: [PATCH 33/93] fix --- .../contracts/token_contract/src/types/token_note.nr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr index 601ecd982af..47c9e4db84a 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr @@ -52,7 +52,7 @@ impl NoteInterface for TokenNote { fn broadcast(self, context: &mut PrivateContext, slot: Field) { // We only bother inserting the note if non-empty to save funds on gas. if !(self.amount == U128::from_integer(0)) { - let encryption_pub_key = get_public_key_with_master_nullifier_public_key_hash(self.owner); + let encryption_pub_key = get_public_key_with_master_nullifier_public_key_hash(self.owner_nullifying_public_key_hash); context.emit_encrypted_log( (*context).this_address(), slot, From c4a745f219ca6d1224a7541c0c1b03406afc95c8 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Thu, 2 May 2024 19:15:24 +0000 Subject: [PATCH 34/93] Fix --- .../aztec-nr/aztec/src/context/private_context.nr | 6 ++++-- .../aztec-nr/aztec/src/oracle/get_public_key.nr | 1 + noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr | 2 +- .../contracts/token_contract/src/types/balances_map.nr | 2 -- yarn-project/circuit-types/src/keys/key_store.ts | 6 ++++++ yarn-project/key-store/src/test_key_store.ts | 6 ++++++ yarn-project/simulator/src/client/db_oracle.ts | 5 +++++ yarn-project/simulator/src/client/view_data_oracle.ts | 9 ++++++--- 8 files changed, 29 insertions(+), 8 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index f37123a464d..64d7ce3ab8d 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -223,10 +223,12 @@ impl PrivateContext { keys.app_nullifier_secret_key } - // TODO(ek): Replace above with this + // TODO(ek): Replace request_app_nullifier_secret_key above with this once we no longer get app nullifier secret key with address pub fn request_app_nullifier_secret_key_with_master_public_nullifying_key_hash(&mut self, master_public_nullifying_key_hash: Field) -> Field { let keys = if self.nullifier_key.is_none() { let keys = get_nullifier_keys_with_master_nullifier_public_key_hash(master_public_nullifying_key_hash); + // Should we inside here constrain the below? + // assert(keys.master_nullifier_public_key_hash == master_public_nullifying_key_hash); let request = NullifierKeyValidationRequest { master_nullifier_public_key: keys.master_nullifier_public_key, app_nullifier_secret_key: keys.app_nullifier_secret_key @@ -238,7 +240,7 @@ impl PrivateContext { let keys = self.nullifier_key.unwrap_unchecked(); // If MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL is larger than 1, need to update the way the key pair is cached. assert(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL == 1); - // TODO: (ek) Enable this after we nuke all the accounts + // TODO: (ek) Enable this after we nuke the account in all notes and when NullifierKeys has a reference to master_nullifier_public_key_hash // assert(keys.master_nullifier_public_key_hash == master_public_nullifying_key_hash, "Cannot query nullifier key for more than one master_nullifying_public_key_hash per call"); keys }; diff --git a/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr b/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr index f09ba005bbb..08ef83bf0db 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr @@ -26,6 +26,7 @@ unconstrained fn get_public_key_and_partial_address_with_master_nullifier_public get_public_key_and_partial_address_with_master_nullifier_public_key_hash_oracle(master_nullifier_public_key_hash) } +// TODO: This is used when we emit encrypted logs and will be changed. pub fn get_public_key_with_master_nullifier_public_key_hash(master_nullifier_public_key_hash: Field) -> GrumpkinPoint { let result = get_public_key_and_partial_address_with_master_nullifier_public_key_hash_internal(master_nullifier_public_key_hash); let pub_key = GrumpkinPoint::new(result[0], result[1]); diff --git a/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr b/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr index 13b9fee6469..cb17de88ba8 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr @@ -28,7 +28,7 @@ pub fn get_app_nullifier_secret_key(account: AztecAddress) -> Field { get_nullifier_keys_internal(account).app_nullifier_secret_key } -// TODO(ek): Replace the one above with this +// TODO(ek): Replace get_nullifier_keys above with this once we no longer get nullifier keys with address #[oracle(getNullifierKeysWithMasterNullifierPublicKeyHash)] fn get_nullifier_keys_with_master_nullifier_public_key_hash_oracle(_master_nullifier_public_key_hash: Field) -> [Field; 3] {} diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr index 687755f9880..249a5f5ed7c 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr @@ -64,8 +64,6 @@ impl BalancesMap { // We fetch the nullifier public key hash in the registry / from our PXE let nullifier_public_key_hash = get_fresh_nullifier_public_key_hash(self.map.context.private.unwrap(), owner); - dep::aztec::oracle::debug_log::debug_log_array_with_prefix("Nullifier Pub Key Hash", [nullifier_public_key_hash]); - let mut addend_note = T::new(addend, nullifier_public_key_hash); // docs:start:insert diff --git a/yarn-project/circuit-types/src/keys/key_store.ts b/yarn-project/circuit-types/src/keys/key_store.ts index 3fb41d6c0e1..2a149cca2ad 100644 --- a/yarn-project/circuit-types/src/keys/key_store.ts +++ b/yarn-project/circuit-types/src/keys/key_store.ts @@ -138,6 +138,12 @@ export interface KeyStore { */ getPublicKeysHash(account: AztecAddress): Promise; + /** + * Gets the account address for a given master nullifier public key hash. + * @throws If the master nullifier public key hash does not exist in the key store. + * @param masterNullifierPublicKeyHash - The master nullifier public key hash for which to retrieve the address. + * @returns The address for the account. + */ getAccountAddressForMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr): AztecAddress; /** diff --git a/yarn-project/key-store/src/test_key_store.ts b/yarn-project/key-store/src/test_key_store.ts index 6e811730470..4fc79e14fab 100644 --- a/yarn-project/key-store/src/test_key_store.ts +++ b/yarn-project/key-store/src/test_key_store.ts @@ -334,6 +334,12 @@ export class TestKeyStore implements KeyStore { return Promise.resolve(Fr.fromBuffer(publicKeysHashBuffer)); } + /** + * Gets the account address for a given master nullifier public key hash. + * @throws If the master nullifier public key hash does not exist in the key store. + * @param masterNullifierPublicKeyHash - The master nullifier public key hash for which to retrieve the address. + * @returns The address for the account. + */ public getAccountAddressForMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr): AztecAddress { const accountAddressBuffer = this.#keys.get(`${masterNullifierPublicKeyHash.toString()}-accountAddress`); diff --git a/yarn-project/simulator/src/client/db_oracle.ts b/yarn-project/simulator/src/client/db_oracle.ts index b133861d6af..ed95fc80089 100644 --- a/yarn-project/simulator/src/client/db_oracle.ts +++ b/yarn-project/simulator/src/client/db_oracle.ts @@ -50,6 +50,11 @@ export interface DBOracle extends CommitmentsDB { */ getCompleteAddress(address: AztecAddress): Promise; + /** + * Retrieve the complete address associated to a given master nullifier public key hash. + * @param masterNullifierPublicKeyHash - Master nullifier public key hash to fetch the complete address for. + * @returns A complete address associated with the input master nullifier public key hash. + */ getCompleteAddressWithMasterNullifierPublicKey(masterNullifierPublicKey: Fr): Promise; /** diff --git a/yarn-project/simulator/src/client/view_data_oracle.ts b/yarn-project/simulator/src/client/view_data_oracle.ts index c8a34bb8e86..7dfd82125b2 100644 --- a/yarn-project/simulator/src/client/view_data_oracle.ts +++ b/yarn-project/simulator/src/client/view_data_oracle.ts @@ -36,7 +36,6 @@ export class ViewDataOracle extends TypedOracle { /** * Retrieve nullifier keys associated with a specific account and app/contract address. - * * @param accountAddress - The account address. * @returns A Promise that resolves to nullifier keys of a requested account and contract. * @throws An error if the account is not registered in the database. @@ -46,8 +45,7 @@ export class ViewDataOracle extends TypedOracle { } /** - * Retrieve nullifier keys associated with a specific account and app/contract address. - * + * Retrieve nullifier keys associated with a specific masterNullifierPublicKeyHash and app/contract address. * @param masterNullifierPublicKeyHash - The master nullifer public key hash. * @returns A Promise that resolves to nullifier keys of a requested account and contract. * @throws An error if the account is not registered in the database. @@ -149,6 +147,11 @@ export class ViewDataOracle extends TypedOracle { return this.db.getCompleteAddress(address); } + /** + * Retrieve the complete address associated to a given master nullifier public key hash. + * @param masterNullifierPublicKeyHash - Master nullifier public key hash to fetch the complete address for. + * @returns A complete address associated with the input master nullifier public key hash. + */ public override getCompleteAddressWithMasterNullifierPublicKey( masterNullifierPublicKeyHash: Fr, ): Promise { From d69e1129eae69afc949f645cd664e23c98e0c3b8 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Thu, 2 May 2024 20:36:09 +0000 Subject: [PATCH 35/93] fix --- .../src/guides/writing_an_account_contract.test.ts | 6 +++--- yarn-project/simulator/src/acvm/oracle/oracle.ts | 2 +- yarn-project/simulator/src/acvm/oracle/typed_oracle.ts | 2 +- yarn-project/simulator/src/client/view_data_oracle.ts | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts b/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts index 1d4b7fc7007..c5a56d197f2 100644 --- a/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts +++ b/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts @@ -64,7 +64,7 @@ describe('guides/writing_an_account_contract', () => { logger.info(`Deployed account contract at ${address}`); // docs:start:account-contract-works - const token = await TokenContract.deploy(wallet, { address }, 'TokenName', 'TokenSymbol', 18).send().deployed(); + const token = await TokenContract.deploy(wallet, address, 'TokenName', 'TokenSymbol', 18).send().deployed(); logger.info(`Deployed token contract at ${token.address}`); const secret = Fr.random(); @@ -84,9 +84,9 @@ describe('guides/writing_an_account_contract', () => { ); await pxe.addNote(extendedNote); - await token.methods.redeem_shield({ address }, mintAmount, secret).send().wait(); + await token.methods.redeem_shield(address, mintAmount, secret).send().wait(); - const balance = await token.methods.balance_of_private({ address }).simulate(); + const balance = await token.methods.balance_of_private(address).simulate(); logger.info(`Balance of wallet is now ${balance}`); // docs:end:account-contract-works expect(balance).toEqual(50n); diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index 5c3f9dd42fd..19626b077b4 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -56,7 +56,7 @@ export class Oracle { async getNullifierKeysWithMasterNullifierPublicKeyHash([masterNullifierPublicKeyHash]: ACVMField[]): Promise< ACVMField[] > { - const { masterNullifierPublicKey, appNullifierSecretKey } = await this.typedOracle.getNullifierKeys( + const { masterNullifierPublicKey, appNullifierSecretKey } = await this.typedOracle.getNullifierKeysWithMasterNullifierPublicKeyHash( fromACVMField(masterNullifierPublicKeyHash), ); return [ diff --git a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts index 751d7e9db04..314029a12e8 100644 --- a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts @@ -94,7 +94,7 @@ export abstract class TypedOracle { } getNullifierKeysWithMasterNullifierPublicKeyHash(_masterNullifierPublicKeyHash: Fr): Promise { - throw new OracleMethodNotAvailableError('getNullifierKeys'); + throw new OracleMethodNotAvailableError('getNullifierKeysWithMasterNullifierPublicKeyHash'); } getPublicKeyAndPartialAddress(_address: AztecAddress): Promise { diff --git a/yarn-project/simulator/src/client/view_data_oracle.ts b/yarn-project/simulator/src/client/view_data_oracle.ts index 7dfd82125b2..7e0b27a1726 100644 --- a/yarn-project/simulator/src/client/view_data_oracle.ts +++ b/yarn-project/simulator/src/client/view_data_oracle.ts @@ -53,7 +53,7 @@ export class ViewDataOracle extends TypedOracle { public override getNullifierKeysWithMasterNullifierPublicKeyHash( masterNullifierPublicKeyHash: Fr, ): Promise { - return this.db.getNullifierKeys(masterNullifierPublicKeyHash, this.contractAddress); + return this.db.getNullifierKeysWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash, this.contractAddress); } /** From b954ecc5febc72bf6143c0682009228d0918daa3 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Thu, 2 May 2024 20:53:13 +0000 Subject: [PATCH 36/93] format --- yarn-project/simulator/src/acvm/oracle/oracle.ts | 7 ++++--- yarn-project/simulator/src/client/db_oracle.ts | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index 19626b077b4..5122be53114 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -56,9 +56,10 @@ export class Oracle { async getNullifierKeysWithMasterNullifierPublicKeyHash([masterNullifierPublicKeyHash]: ACVMField[]): Promise< ACVMField[] > { - const { masterNullifierPublicKey, appNullifierSecretKey } = await this.typedOracle.getNullifierKeysWithMasterNullifierPublicKeyHash( - fromACVMField(masterNullifierPublicKeyHash), - ); + const { masterNullifierPublicKey, appNullifierSecretKey } = + await this.typedOracle.getNullifierKeysWithMasterNullifierPublicKeyHash( + fromACVMField(masterNullifierPublicKeyHash), + ); return [ toACVMField(masterNullifierPublicKey.x), toACVMField(masterNullifierPublicKey.y), diff --git a/yarn-project/simulator/src/client/db_oracle.ts b/yarn-project/simulator/src/client/db_oracle.ts index ed95fc80089..d74b707aa8d 100644 --- a/yarn-project/simulator/src/client/db_oracle.ts +++ b/yarn-project/simulator/src/client/db_oracle.ts @@ -90,7 +90,7 @@ export interface DBOracle extends CommitmentsDB { getNullifierKeys(accountAddress: AztecAddress, contractAddress: AztecAddress): Promise; /** - * Retrieve nullifier keys associated with a specific account and app/contract address. + * Retrieve nullifier keys associated with a specific master nullifier public key hash and app/contract address. * * @param masterNullifierPublicKeyHash - The master nullifer public key hash. * @param contractAddress - The contract address. From 577b69cb451519d5787e22d8e60fafeb36854fe5 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Thu, 2 May 2024 22:35:08 +0000 Subject: [PATCH 37/93] one --- yarn-project/simulator/src/client/simulator.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn-project/simulator/src/client/simulator.test.ts b/yarn-project/simulator/src/client/simulator.test.ts index ef9fd366291..e49599ea6f1 100644 --- a/yarn-project/simulator/src/client/simulator.test.ts +++ b/yarn-project/simulator/src/client/simulator.test.ts @@ -47,7 +47,7 @@ describe('Simulator', () => { oracle = mock(); node = mock(); - oracle.getNullifierKeys.mockResolvedValue({ + oracle.getNullifierKeysWithMasterNullifierPublicKeyHash.mockResolvedValue({ masterNullifierPublicKey: ownerMasterNullifierPublicKey, appNullifierSecretKey, }); From 11b484826fd48720abf7a1795c672d5705d24a16 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Thu, 2 May 2024 22:46:24 +0000 Subject: [PATCH 38/93] fix --- yarn-project/key-store/src/test_key_store.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn-project/key-store/src/test_key_store.ts b/yarn-project/key-store/src/test_key_store.ts index 4fc79e14fab..c6ab226bb5a 100644 --- a/yarn-project/key-store/src/test_key_store.ts +++ b/yarn-project/key-store/src/test_key_store.ts @@ -66,7 +66,7 @@ export class TestKeyStore implements KeyStore { await this.#keys.set(`${accountAddress.toString()}-ovsk_m`, masterOutgoingViewingSecretKey.toBuffer()); await this.#keys.set(`${accountAddress.toString()}-tsk_m`, masterTaggingSecretKey.toBuffer()); - await this.#keys.set(`${accountAddress.toString()}-npk_m`, masterNullifierPublicKey.toBuffer()); + await this.#keys.set(`${accountAddress.toString()}-npk_m-account`, masterNullifierPublicKey.toBuffer()); await this.#keys.set(`${accountAddress.toString()}-ivpk_m`, masterIncomingViewingPublicKey.toBuffer()); await this.#keys.set(`${accountAddress.toString()}-ovpk_m`, masterOutgoingViewingPublicKey.toBuffer()); await this.#keys.set(`${accountAddress.toString()}-tpk_m`, masterTaggingPublicKey.toBuffer()); @@ -74,8 +74,8 @@ export class TestKeyStore implements KeyStore { const masterNullifierPublicKeyHash = poseidon2Hash(masterNullifierPublicKey.toFields()); // We save nullifier keys and account address to db under the master nullifier key hash - await this.#keys.set(`${masterNullifierPublicKeyHash.toString()}-nsk_m-mnpk`, masterNullifierSecretKey.toBuffer()); - await this.#keys.set(`${masterNullifierPublicKeyHash.toString()}-npk_m`, masterNullifierPublicKey.toBuffer()); + await this.#keys.set(`${masterNullifierPublicKeyHash.toString()}-nsk_m-mnpkh`, masterNullifierSecretKey.toBuffer()); + await this.#keys.set(`${masterNullifierPublicKeyHash.toString()}-npk_m-mnpkh`, masterNullifierPublicKey.toBuffer()); await this.#keys.set(`${masterNullifierPublicKeyHash.toString()}-accountAddress`, accountAddress.toBuffer()); // At last, we return the newly derived account address @@ -100,7 +100,7 @@ export class TestKeyStore implements KeyStore { * @returns The master nullifier public key for the account. */ public async getMasterNullifierPublicKey(account: AztecAddress): Promise { - const masterNullifierPublicKeyBuffer = this.#keys.get(`${account.toString()}-npk_m`); + const masterNullifierPublicKeyBuffer = this.#keys.get(`${account.toString()}-npk_m-account`); if (!masterNullifierPublicKeyBuffer) { throw new Error( `Account ${account.toString()} does not exist. Registered accounts: ${await this.getAccounts()}.`, @@ -116,7 +116,7 @@ export class TestKeyStore implements KeyStore { * @returns The master nullifier public key for the account. */ getMasterNullifierPublicKeyWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr): Promise { - const masterNullifierPublicKeyBuffer = this.#keys.get(`${masterNullifierPublicKeyHash.toString()}-npk_m`); + const masterNullifierPublicKeyBuffer = this.#keys.get(`${masterNullifierPublicKeyHash.toString()}-npk_m-mnpkh`); if (!masterNullifierPublicKeyBuffer) { throw new Error(`Master nullifier public keys hash ${masterNullifierPublicKeyHash.toString()} does not exist.`); } @@ -201,7 +201,7 @@ export class TestKeyStore implements KeyStore { masterNullifierPublicKeyHash: Fr, app: AztecAddress, ): Promise { - const masterNullifierSecretKeyBuffer = this.#keys.get(`${masterNullifierPublicKeyHash.toString()}-nsk_m-mnpk`); + const masterNullifierSecretKeyBuffer = this.#keys.get(`${masterNullifierPublicKeyHash.toString()}-nsk_m-mnpkh`); if (!masterNullifierSecretKeyBuffer) { throw new Error(`Master nullifier public keys hash ${masterNullifierPublicKeyHash.toString()} does not exist.`); } @@ -273,7 +273,7 @@ export class TestKeyStore implements KeyStore { public getMasterNullifierSecretKeyForPublicKey(masterNullifierPublicKey: PublicKey): Promise { // We iterate over the map keys to find the account address that corresponds to the provided public key for (const [key, value] of this.#keys.entries()) { - if (value.equals(masterNullifierPublicKey.toBuffer())) { + if (value.equals(masterNullifierPublicKey.toBuffer()) && key.endsWith('account')) { // We extract the account address from the map key const accountAddress = key.split('-')[0]; // We fetch the secret key and return it @@ -358,7 +358,7 @@ export class TestKeyStore implements KeyStore { masterOutgoingViewingPublicKey: Point, masterTaggingPublicKey: Point, ): Promise { - await this.#keys.set(`${accountAddress.toString()}-npk_m`, masterNullifierPublicKey.toBuffer()); + await this.#keys.set(`${accountAddress.toString()}-npk_m-account`, masterNullifierPublicKey.toBuffer()); await this.#keys.set(`${accountAddress.toString()}-ivpk_m`, masterIncomingViewingPublicKey.toBuffer()); await this.#keys.set(`${accountAddress.toString()}-ovpk_m`, masterOutgoingViewingPublicKey.toBuffer()); await this.#keys.set(`${accountAddress.toString()}-tpk_m`, masterTaggingPublicKey.toBuffer()); From a74311be730c3c0549bf68d05a98dd6bd93c84d3 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Thu, 2 May 2024 23:58:03 +0000 Subject: [PATCH 39/93] Fix --- .../aztec.js/src/wallet/base_wallet.ts | 5 +++- .../circuit-types/src/interfaces/pxe.ts | 10 +++++++ .../circuit-types/src/keys/key_store.ts | 1 + .../end-to-end/src/e2e_2_pxes.test.ts | 30 ++++++++++++++----- yarn-project/key-store/src/test_key_store.ts | 15 ++++++++++ .../pxe/src/pxe_service/pxe_service.ts | 13 ++++++++ 6 files changed, 66 insertions(+), 8 deletions(-) diff --git a/yarn-project/aztec.js/src/wallet/base_wallet.ts b/yarn-project/aztec.js/src/wallet/base_wallet.ts index eeacdb4f23a..a771ac515f3 100644 --- a/yarn-project/aztec.js/src/wallet/base_wallet.ts +++ b/yarn-project/aztec.js/src/wallet/base_wallet.ts @@ -15,7 +15,7 @@ import { type TxHash, type TxReceipt, } from '@aztec/circuit-types'; -import { type AztecAddress, type CompleteAddress, type Fr, type PartialAddress } from '@aztec/circuits.js'; +import { Point, type AztecAddress, type CompleteAddress, type Fr, type PartialAddress } from '@aztec/circuits.js'; import { type ContractArtifact } from '@aztec/foundation/abi'; import { type ContractClassWithId, type ContractInstanceWithAddress } from '@aztec/types/contracts'; import { type NodeInfo } from '@aztec/types/interfaces'; @@ -83,6 +83,9 @@ export abstract class BaseWallet implements Wallet { getRegisteredAccountPublicKeysHash(address: AztecAddress): Promise { return this.pxe.getRegisteredAccountPublicKeysHash(address); } + getRegisteredAccountPublicKeys(address: AztecAddress): Promise { + return this.pxe.getRegisteredAccountPublicKeys(address); + } getRecipients(): Promise { return this.pxe.getRecipients(); } diff --git a/yarn-project/circuit-types/src/interfaces/pxe.ts b/yarn-project/circuit-types/src/interfaces/pxe.ts index 0e95d024727..65baf5d6bc1 100644 --- a/yarn-project/circuit-types/src/interfaces/pxe.ts +++ b/yarn-project/circuit-types/src/interfaces/pxe.ts @@ -100,6 +100,16 @@ export interface PXE { */ getRegisteredAccountPublicKeysHash(address: AztecAddress): Promise; + /** + * Retrieves the public keys of the account corresponding to the provided aztec address. + * + * @param address - The address of account. + * @returns The public keys of the requested account if found. + * TODO(#5834): refactor complete address and merge with getRegisteredAccount? + * TODO?: Refactor this ? This is used in e2e_2_pxes to share keys with another sender + */ + getRegisteredAccountPublicKeys(address: AztecAddress): Promise; + /** * Retrieves the recipients added to this PXE Service. * @returns An array of recipients registered on this PXE Service. diff --git a/yarn-project/circuit-types/src/keys/key_store.ts b/yarn-project/circuit-types/src/keys/key_store.ts index 2a149cca2ad..f4d2e4b2e49 100644 --- a/yarn-project/circuit-types/src/keys/key_store.ts +++ b/yarn-project/circuit-types/src/keys/key_store.ts @@ -153,6 +153,7 @@ export interface KeyStore { * @param masterIncomingViewingPublicKey - The stored incoming viewing public key * @param masterOutgoingViewingPublicKey - The stored outgoing viewing public key * @param masterTaggingPublicKey - The stored master tagging public key + * @remarks This also adds the master nullifier public key hash to the store for the recipient */ // TODO(#5834): Move this function out of here. Key store should only be used for accounts, not recipients addPublicKeysForAccount( diff --git a/yarn-project/end-to-end/src/e2e_2_pxes.test.ts b/yarn-project/end-to-end/src/e2e_2_pxes.test.ts index 4f7f20cbe87..bf581215b97 100644 --- a/yarn-project/end-to-end/src/e2e_2_pxes.test.ts +++ b/yarn-project/end-to-end/src/e2e_2_pxes.test.ts @@ -119,10 +119,14 @@ describe('e2e_2_pxes', () => { const tokenInstance = await deployTokenContract(initialBalance, walletA.getAddress(), pxeA); const tokenAddress = tokenInstance.address; + // Get public keys of both accounts + const walletAPublicKeys = await pxeA.getRegisteredAccountPublicKeys(walletA.getAddress()); + const walletBPublicKeys = await pxeB.getRegisteredAccountPublicKeys(walletB.getAddress()); + // Add account B to wallet A - await pxeA.registerRecipient(walletB.getCompleteAddress()); + await pxeA.registerRecipient(walletB.getCompleteAddress(), walletBPublicKeys); // Add account A to wallet B - await pxeB.registerRecipient(walletA.getCompleteAddress()); + await pxeB.registerRecipient(walletA.getCompleteAddress(), walletAPublicKeys); // Add token to PXE B (PXE A already has it because it was deployed through it) await pxeB.registerContract({ @@ -215,10 +219,14 @@ describe('e2e_2_pxes', () => { const tokenInstance = await deployTokenContract(userABalance, walletA.getAddress(), pxeA); const contractWithWalletA = await TokenContract.at(tokenInstance.address, walletA); + // Get public keys of both accounts + const walletAPublicKeys = await pxeA.getRegisteredAccountPublicKeys(walletA.getAddress()); + const walletBPublicKeys = await pxeB.getRegisteredAccountPublicKeys(walletB.getAddress()); + // Add account B to wallet A - await pxeA.registerRecipient(walletB.getCompleteAddress()); + await pxeA.registerRecipient(walletB.getCompleteAddress(), walletBPublicKeys); // Add account A to wallet B - await pxeB.registerRecipient(walletA.getCompleteAddress()); + await pxeB.registerRecipient(walletA.getCompleteAddress(), walletAPublicKeys); // Add token to PXE B (PXE A already has it because it was deployed through it) await pxeB.registerContract({ @@ -268,10 +276,14 @@ describe('e2e_2_pxes', () => { const tokenInstance = await deployTokenContract(initialBalance, walletA.getAddress(), pxeA); const tokenAddress = tokenInstance.address; + // Get public keys of both accounts + const walletAPublicKeys = await pxeA.getRegisteredAccountPublicKeys(walletA.getAddress()); + const walletBPublicKeys = await pxeB.getRegisteredAccountPublicKeys(walletB.getAddress()); + // Add account B to wallet A - await pxeA.registerRecipient(walletB.getCompleteAddress()); + await pxeA.registerRecipient(walletB.getCompleteAddress(), walletBPublicKeys); // Add account A to wallet B - await pxeB.registerRecipient(walletA.getCompleteAddress()); + await pxeB.registerRecipient(walletA.getCompleteAddress(), walletAPublicKeys); // Check initial balances and logs are as expected await expectTokenBalance(walletA, tokenAddress, walletA.getAddress(), initialBalance); @@ -311,7 +323,11 @@ describe('e2e_2_pxes', () => { await sharedAccountOnB.register(); const sharedWalletOnB = await sharedAccountOnB.getWallet(); - await pxeA.registerRecipient(walletB.getCompleteAddress()); + // Get the public keys of wallet B + const walletBPublicKeys = await pxeB.getRegisteredAccountPublicKeys(walletB.getAddress()); + + // Register wallet B in the pxe of wallet A + await pxeA.registerRecipient(walletB.getCompleteAddress(), walletBPublicKeys); // deploy the contract on PXE A const tokenInstance = await deployTokenContract(initialBalance, walletA.getAddress(), pxeA); diff --git a/yarn-project/key-store/src/test_key_store.ts b/yarn-project/key-store/src/test_key_store.ts index c6ab226bb5a..12ef7ad58fe 100644 --- a/yarn-project/key-store/src/test_key_store.ts +++ b/yarn-project/key-store/src/test_key_store.ts @@ -350,6 +350,15 @@ export class TestKeyStore implements KeyStore { return AztecAddress.fromBuffer(accountAddressBuffer); } + /** + * This is used to register a recipient / for storing public keys of an address + * @param accountAddress - The account address to store keys for. + * @param masterNullifierPublicKey - The stored master nullifier public key + * @param masterIncomingViewingPublicKey - The stored incoming viewing public key + * @param masterOutgoingViewingPublicKey - The stored outgoing viewing public key + * @param masterTaggingPublicKey - The stored master tagging public key + * @remarks This also adds the master nullifier public key hash to the store for the recipient + */ // TODO(#5834): Re-add separation between recipients and accounts in keystore. public async addPublicKeysForAccount( accountAddress: AztecAddress, @@ -362,5 +371,11 @@ export class TestKeyStore implements KeyStore { await this.#keys.set(`${accountAddress.toString()}-ivpk_m`, masterIncomingViewingPublicKey.toBuffer()); await this.#keys.set(`${accountAddress.toString()}-ovpk_m`, masterOutgoingViewingPublicKey.toBuffer()); await this.#keys.set(`${accountAddress.toString()}-tpk_m`, masterTaggingPublicKey.toBuffer()); + + const masterNullifierPublicKeyHash = poseidon2Hash(masterNullifierPublicKey.toFields()); + + // We save nullifier keys and account address to db under the master nullifier key hash + await this.#keys.set(`${masterNullifierPublicKeyHash.toString()}-npk_m-mnpkh`, masterNullifierPublicKey.toBuffer()); + await this.#keys.set(`${masterNullifierPublicKeyHash.toString()}-accountAddress`, accountAddress.toBuffer()); } } diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index dc75deb293b..721f84f875f 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -211,6 +211,19 @@ export class PXEService implements PXE { return this.keyStore.getPublicKeysHash(address); } + public async getRegisteredAccountPublicKeys(address: AztecAddress): Promise { + const accounts = await this.keyStore.getAccounts(); + if (!accounts.some(account => account.equals(address))) { + return undefined; + } + return Promise.all([ + this.keyStore.getMasterNullifierPublicKey(address), + this.keyStore.getMasterIncomingViewingPublicKey(address), + this.keyStore.getMasterOutgoingViewingPublicKey(address), + this.keyStore.getMasterTaggingPublicKey(address), + ]); + } + public async registerRecipient(recipient: CompleteAddress, publicKeys: Point[] = []): Promise { const wasAdded = await this.db.addCompleteAddress(recipient); From 1d9964a753d6c23cfa3c193ea5e76308090e4142 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 3 May 2024 00:02:13 +0000 Subject: [PATCH 40/93] comments --- yarn-project/key-store/src/test_key_store.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/yarn-project/key-store/src/test_key_store.ts b/yarn-project/key-store/src/test_key_store.ts index 12ef7ad58fe..0bbb07c2f21 100644 --- a/yarn-project/key-store/src/test_key_store.ts +++ b/yarn-project/key-store/src/test_key_store.ts @@ -372,6 +372,7 @@ export class TestKeyStore implements KeyStore { await this.#keys.set(`${accountAddress.toString()}-ovpk_m`, masterOutgoingViewingPublicKey.toBuffer()); await this.#keys.set(`${accountAddress.toString()}-tpk_m`, masterTaggingPublicKey.toBuffer()); + //! This is especially disgusting / hacky, and will be refactored. const masterNullifierPublicKeyHash = poseidon2Hash(masterNullifierPublicKey.toFields()); // We save nullifier keys and account address to db under the master nullifier key hash From 5fa644dca7bb734c070df53cf1120d3e6de1eff1 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 3 May 2024 00:05:17 +0000 Subject: [PATCH 41/93] format --- yarn-project/aztec.js/src/wallet/base_wallet.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn-project/aztec.js/src/wallet/base_wallet.ts b/yarn-project/aztec.js/src/wallet/base_wallet.ts index a771ac515f3..dac03cfbc0e 100644 --- a/yarn-project/aztec.js/src/wallet/base_wallet.ts +++ b/yarn-project/aztec.js/src/wallet/base_wallet.ts @@ -15,7 +15,7 @@ import { type TxHash, type TxReceipt, } from '@aztec/circuit-types'; -import { Point, type AztecAddress, type CompleteAddress, type Fr, type PartialAddress } from '@aztec/circuits.js'; +import { type AztecAddress, type CompleteAddress, type Fr, type PartialAddress, type Point } from '@aztec/circuits.js'; import { type ContractArtifact } from '@aztec/foundation/abi'; import { type ContractClassWithId, type ContractInstanceWithAddress } from '@aztec/types/contracts'; import { type NodeInfo } from '@aztec/types/interfaces'; From 227378cc1347ceb7db03c0d1b572295f5f29cd21 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 3 May 2024 12:53:10 +0000 Subject: [PATCH 42/93] testkeystore Small refactor Fixes --- .../aztec/src/context/private_context.nr | 11 +- .../aztec/src/oracle/get_public_key.nr | 3 +- .../aztec/src/oracle/nullifier_key.nr | 4 +- .../token_contract/src/types/token_note.nr | 10 +- .../aztec.js/src/wallet/base_wallet.ts | 4 +- .../circuit-types/src/interfaces/pxe.ts | 9 +- .../circuit-types/src/keys/key_store.ts | 30 +---- .../circuits.js/src/types/public_key.ts | 7 ++ .../end-to-end/src/e2e_key_registry.test.ts | 14 +-- yarn-project/key-store/src/test_key_store.ts | 118 +++++++----------- .../pxe/src/pxe_service/pxe_service.ts | 28 +++-- .../pxe/src/simulator_oracle/index.ts | 4 +- 12 files changed, 105 insertions(+), 137 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index ee52270fbcf..3ff5011afbf 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -32,7 +32,8 @@ use dep::protocol_types::{ contrakt::{storage_read::StorageRead, storage_update_request::StorageUpdateRequest}, grumpkin_private_key::GrumpkinPrivateKey, grumpkin_point::GrumpkinPoint, header::Header, messaging::l2_to_l1_message::L2ToL1Message, utils::reader::Reader, - traits::{is_empty, Deserialize, Empty} + traits::{is_empty, Deserialize, Empty}, + hash::poseidon2_hash }; // When finished, one can call .finish() to convert back to the abi @@ -227,8 +228,7 @@ impl PrivateContext { pub fn request_app_nullifier_secret_key_with_master_public_nullifying_key_hash(&mut self, master_public_nullifying_key_hash: Field) -> Field { let keys = if self.nullifier_key.is_none() { let keys = get_nullifier_keys_with_master_nullifier_public_key_hash(master_public_nullifying_key_hash); - // Should we inside here constrain the below? - // assert(keys.master_nullifier_public_key_hash == master_public_nullifying_key_hash); + assert_eq(poseidon2_hash(keys.master_nullifier_public_key.serialize()), master_public_nullifying_key_hash); let request = NullifierKeyValidationRequest { master_nullifier_public_key: keys.master_nullifier_public_key, app_nullifier_secret_key: keys.app_nullifier_secret_key @@ -240,10 +240,11 @@ impl PrivateContext { let keys = self.nullifier_key.unwrap_unchecked(); // If MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL is larger than 1, need to update the way the key pair is cached. assert(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL == 1); - // TODO: (ek) Enable this after we nuke the account in all notes and when NullifierKeys has a reference to master_nullifier_public_key_hash - // assert(keys.master_nullifier_public_key_hash == master_public_nullifying_key_hash, "Cannot query nullifier key for more than one master_nullifying_public_key_hash per call"); keys }; + + // TODO: (#6176) (ek) Enable this after we nuke the account in all notes and when NullifierKeys has a reference to master_nullifier_public_key_hash + // assert_eq(keys.master_nullifier_public_key_hash, master_public_nullifying_key_hash); keys.app_nullifier_secret_key } diff --git a/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr b/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr index 08ef83bf0db..13d3184e845 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr @@ -26,7 +26,8 @@ unconstrained fn get_public_key_and_partial_address_with_master_nullifier_public get_public_key_and_partial_address_with_master_nullifier_public_key_hash_oracle(master_nullifier_public_key_hash) } -// TODO: This is used when we emit encrypted logs and will be changed. +// TODO (#5901): This is used when we emit encrypted logs and will be changed. +// TODO (#6178): This function should not be contraining things here. pub fn get_public_key_with_master_nullifier_public_key_hash(master_nullifier_public_key_hash: Field) -> GrumpkinPoint { let result = get_public_key_and_partial_address_with_master_nullifier_public_key_hash_internal(master_nullifier_public_key_hash); let pub_key = GrumpkinPoint::new(result[0], result[1]); diff --git a/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr b/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr index cb17de88ba8..077672399ee 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr @@ -28,7 +28,7 @@ pub fn get_app_nullifier_secret_key(account: AztecAddress) -> Field { get_nullifier_keys_internal(account).app_nullifier_secret_key } -// TODO(ek): Replace get_nullifier_keys above with this once we no longer get nullifier keys with address +// TODO (#6176): Replace get_nullifier_keys above with this once we no longer get nullifier keys with address #[oracle(getNullifierKeysWithMasterNullifierPublicKeyHash)] fn get_nullifier_keys_with_master_nullifier_public_key_hash_oracle(_master_nullifier_public_key_hash: Field) -> [Field; 3] {} @@ -41,10 +41,12 @@ unconstrained fn get_nullifier_keys_with_master_nullifier_public_key_hash_intern } } +// We get the full struct Nullifier Keys here pub fn get_nullifier_keys_with_master_nullifier_public_key_hash(master_nullifier_public_key_hash: Field) -> NullifierKeys { get_nullifier_keys_with_master_nullifier_public_key_hash_internal(master_nullifier_public_key_hash) } +// We are only getting the app_nullifier_secret_key here pub fn get_app_nullifier_secret_key_with_master_nullifier_public_key_hash(master_nullifier_public_key_hash: Field) -> Field { get_nullifier_keys_with_master_nullifier_public_key_hash_internal(master_nullifier_public_key_hash).app_nullifier_secret_key } diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr index 47c9e4db84a..e408237fd09 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr @@ -15,13 +15,12 @@ global TOKEN_NOTE_LEN: Field = 3; // 3 plus a header. #[aztec(note)] struct TokenNote { - // the amount of tokens in the note + // The amount of tokens in the note amount: U128, - // the nullifying public key of the person who owns the note. The owner (recipient) to ensure that the note - // can be privately spent. When nullifier secret and encryption private key is same - // we can simply use the owner for this one. + // The nullifying public key hash of the person who owns the note. + // This is used with the app_nullifier_secret_key to ensure that the note can be privately spent. owner_nullifying_public_key_hash: Field, - // randomness of the note to hide contents. + // Randomness of the note to hide its contents randomness: Field, } @@ -51,6 +50,7 @@ impl NoteInterface for TokenNote { // Broadcasts the note as an encrypted log on L1. fn broadcast(self, context: &mut PrivateContext, slot: Field) { // We only bother inserting the note if non-empty to save funds on gas. + // TODO: (#5901) This will be changed a lot, as it should use the updated encrypted log format if !(self.amount == U128::from_integer(0)) { let encryption_pub_key = get_public_key_with_master_nullifier_public_key_hash(self.owner_nullifying_public_key_hash); context.emit_encrypted_log( diff --git a/yarn-project/aztec.js/src/wallet/base_wallet.ts b/yarn-project/aztec.js/src/wallet/base_wallet.ts index dac03cfbc0e..bf6c6aeaef5 100644 --- a/yarn-project/aztec.js/src/wallet/base_wallet.ts +++ b/yarn-project/aztec.js/src/wallet/base_wallet.ts @@ -15,7 +15,7 @@ import { type TxHash, type TxReceipt, } from '@aztec/circuit-types'; -import { type AztecAddress, type CompleteAddress, type Fr, type PartialAddress, type Point } from '@aztec/circuits.js'; +import { PublicKeys, type AztecAddress, type CompleteAddress, type Fr, type PartialAddress, type Point } from '@aztec/circuits.js'; import { type ContractArtifact } from '@aztec/foundation/abi'; import { type ContractClassWithId, type ContractInstanceWithAddress } from '@aztec/types/contracts'; import { type NodeInfo } from '@aztec/types/interfaces'; @@ -83,7 +83,7 @@ export abstract class BaseWallet implements Wallet { getRegisteredAccountPublicKeysHash(address: AztecAddress): Promise { return this.pxe.getRegisteredAccountPublicKeysHash(address); } - getRegisteredAccountPublicKeys(address: AztecAddress): Promise { + getRegisteredAccountPublicKeys(address: AztecAddress): Promise { return this.pxe.getRegisteredAccountPublicKeys(address); } getRecipients(): Promise { diff --git a/yarn-project/circuit-types/src/interfaces/pxe.ts b/yarn-project/circuit-types/src/interfaces/pxe.ts index 65baf5d6bc1..db5cc4274f4 100644 --- a/yarn-project/circuit-types/src/interfaces/pxe.ts +++ b/yarn-project/circuit-types/src/interfaces/pxe.ts @@ -1,4 +1,4 @@ -import { type AztecAddress, type CompleteAddress, type Fr, type PartialAddress, type Point } from '@aztec/circuits.js'; +import { type PublicKeys, type AztecAddress, type CompleteAddress, type Fr, type PartialAddress } from '@aztec/circuits.js'; import { type ContractArtifact } from '@aztec/foundation/abi'; import { type ContractClassWithId, type ContractInstanceWithAddress } from '@aztec/types/contracts'; import { type NodeInfo } from '@aztec/types/interfaces'; @@ -68,13 +68,14 @@ export interface PXE { * in order to be able to encrypt data for this recipient. * * @param recipient - The complete address of the recipient + * @param publicKeys - The public keys of the recipient (see #5834) * @remarks Called recipient because we can only send notes to this account and not receive them via this PXE Service. * This is because we don't have the associated private key and for this reason we can't decrypt * the recipient's notes. We can send notes to this account because we can encrypt them with the recipient's * public key. */ // TODO: #5834: Nuke publicKeys optional parameter after `CompleteAddress` refactor. - registerRecipient(recipient: CompleteAddress, publicKeys?: Point[]): Promise; + registerRecipient(recipient: CompleteAddress, publicKeys?: PublicKeys): Promise; /** * Retrieves the user accounts registered on this PXE Service. @@ -106,9 +107,9 @@ export interface PXE { * @param address - The address of account. * @returns The public keys of the requested account if found. * TODO(#5834): refactor complete address and merge with getRegisteredAccount? - * TODO?: Refactor this ? This is used in e2e_2_pxes to share keys with another sender + * This will change after the re enabling separation of keystore and pxe. We shouldn't need both this function and the above one */ - getRegisteredAccountPublicKeys(address: AztecAddress): Promise; + getRegisteredAccountPublicKeys(address: AztecAddress): Promise; /** * Retrieves the recipients added to this PXE Service. diff --git a/yarn-project/circuit-types/src/keys/key_store.ts b/yarn-project/circuit-types/src/keys/key_store.ts index f4d2e4b2e49..06a6e55042a 100644 --- a/yarn-project/circuit-types/src/keys/key_store.ts +++ b/yarn-project/circuit-types/src/keys/key_store.ts @@ -32,20 +32,12 @@ export interface KeyStore { getAccounts(): Promise; /** - * Gets the master nullifier public key for a given master nullifier public key hash. - * @throws If the master nullifier public key hash does not exist in the key store. - * @param masterNullifierPublicKeyHash - The master nullifier public key hash for which to retrieve the master nullifier public key. - * @returns The master nullifier public key for the account. - */ - getMasterNullifierPublicKeyWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr): Promise; - - /** - * Gets the master nullifier public key for a given account. + * Gets the master nullifier public key for a given account or master nullifier public key hash. * @throws If the account does not exist in the key store. - * @param account - The account address for which to retrieve the master nullifier public key. + * @param account or master nullifier public key hash - The account address or master nullifier public key hash for which to retrieve the master nullifier public key. * @returns The master nullifier public key for the account. */ - getMasterNullifierPublicKey(account: AztecAddress): Promise; + getMasterNullifierPublicKey(accountOrMasterNullifierPublicKeyHash: AztecAddress | Fr): Promise; /** * Gets the master incoming viewing public key for a given account. @@ -72,26 +64,14 @@ export interface KeyStore { getMasterTaggingPublicKey(account: AztecAddress): Promise; /** - * Retrieves application nullifier secret key. + * Derives and returns the application nullifier secret key for a given account or master nullifier public key hash. * @throws If the account does not exist in the key store. - * @param account - The account to retrieve the application nullifier secret key for. + * @param account or master nullifier public key hash - The account address or master nullifier public key hash for which to retrieve the application nullifier secret key. * @param app - The application address to retrieve the nullifier secret key for. * @returns A Promise that resolves to the application nullifier secret key. */ getAppNullifierSecretKey(account: AztecAddress, app: AztecAddress): Promise; - /** - * Retrieves application nullifier secret key. - * @throws If the masterNullifierPublicKeyHash does not exist in the key store. - * @param masterNullifierPublicKeyHash - The account to retrieve the application nullifier secret key for. - * @param app - The application address to retrieve the nullifier secret key for. - * @returns A Promise that resolves to the application nullifier secret key. - */ - getAppNullifierSecretKeyWithMasterNullifierPublicKeyHash( - masterNullifierPublicKeyHash: Fr, - app: AztecAddress, - ): Promise; - /** * Retrieves application incoming viewing secret key. * @throws If the account does not exist in the key store. diff --git a/yarn-project/circuits.js/src/types/public_key.ts b/yarn-project/circuits.js/src/types/public_key.ts index 0109de4c8ea..e4d135d88ee 100644 --- a/yarn-project/circuits.js/src/types/public_key.ts +++ b/yarn-project/circuits.js/src/types/public_key.ts @@ -2,3 +2,10 @@ import { type Point } from '@aztec/foundation/fields'; /** Represents a user public key. */ export type PublicKey = Point; + +export type PublicKeys = { + masterNullifierPublicKey: Point, + masterIncomingViewingPublicKey: Point, + masterOutgoingViewingPublicKey: Point, + masterTaggingPublicKey: Point, +} 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 index b801beed9e4..007b1e7797e 100644 --- a/yarn-project/end-to-end/src/e2e_key_registry.test.ts +++ b/yarn-project/end-to-end/src/e2e_key_registry.test.ts @@ -305,12 +305,12 @@ describe('Key Registry', () => { .wait(); // TODO: (#5834) Refactor complete address to move the public keys - await pxe.registerRecipient(CompleteAddress.create(accountAddedToRegistry, Point.ZERO, partialAddress), [ - new Point(Fr.random(), Fr.random()), + await pxe.registerRecipient(CompleteAddress.create(accountAddedToRegistry, Point.ZERO, partialAddress), { + masterNullifierPublicKey: new Point(Fr.random(), Fr.random()), masterIncomingViewingPublicKey, masterOutgoingViewingPublicKey, masterTaggingPublicKey, - ]); + }); // Our check should still succeed even if our pxe gives conflicting information, taking the registry as the source of truth. await testContract.methods @@ -352,12 +352,12 @@ describe('Key Registry', () => { it('should fail when we try to check the public keys for a invalid address', async () => { const randAddress = AztecAddress.random(); // TODO: (#5834) Refactor complete address to move the public keys - await pxe.registerRecipient(CompleteAddress.create(randAddress, Point.ZERO, partialAddress), [ + await pxe.registerRecipient(CompleteAddress.create(randAddress, Point.ZERO, partialAddress), { masterNullifierPublicKey, masterIncomingViewingPublicKey, masterOutgoingViewingPublicKey, masterTaggingPublicKey, - ]); + }); await expect( testContract.methods.test_nullifier_key_freshness(randAddress, masterNullifierPublicKey).send().wait(), @@ -366,12 +366,12 @@ describe('Key Registry', () => { it('adds a recipient to our pxe, and checks the key freshness with and without adding an entry to our key registry', async () => { // TODO: (#5834) Refactor complete address to move the public keys - await pxe.registerRecipient(CompleteAddress.create(accountAddedToRegistry, Point.ZERO, partialAddress), [ + await pxe.registerRecipient(CompleteAddress.create(accountAddedToRegistry, Point.ZERO, partialAddress), { masterNullifierPublicKey, masterIncomingViewingPublicKey, masterOutgoingViewingPublicKey, masterTaggingPublicKey, - ]); + }); // The check should succeed because we register our recipient manually and the lib checks our pxe await testContract.methods diff --git a/yarn-project/key-store/src/test_key_store.ts b/yarn-project/key-store/src/test_key_store.ts index 0bbb07c2f21..c086db4aaaa 100644 --- a/yarn-project/key-store/src/test_key_store.ts +++ b/yarn-project/key-store/src/test_key_store.ts @@ -61,23 +61,17 @@ export class TestKeyStore implements KeyStore { // We save the keys to db associated with the account address await this.#keys.set(`${accountAddress.toString()}-public_keys_hash`, publicKeysHash.toBuffer()); - await this.#keys.set(`${accountAddress.toString()}-nsk_m-account`, masterNullifierSecretKey.toBuffer()); + // Naming of keys is as follows ${from}-${to}_${any modifiers (m = master, h = hash)} + await this.#keys.set(`${accountAddress.toString()}-nsk_m`, masterNullifierSecretKey.toBuffer()); await this.#keys.set(`${accountAddress.toString()}-ivsk_m`, masterIncomingViewingSecretKey.toBuffer()); await this.#keys.set(`${accountAddress.toString()}-ovsk_m`, masterOutgoingViewingSecretKey.toBuffer()); await this.#keys.set(`${accountAddress.toString()}-tsk_m`, masterTaggingSecretKey.toBuffer()); - await this.#keys.set(`${accountAddress.toString()}-npk_m-account`, masterNullifierPublicKey.toBuffer()); + await this.#keys.set(`${accountAddress.toString()}-npk_m`, masterNullifierPublicKey.toBuffer()); await this.#keys.set(`${accountAddress.toString()}-ivpk_m`, masterIncomingViewingPublicKey.toBuffer()); await this.#keys.set(`${accountAddress.toString()}-ovpk_m`, masterOutgoingViewingPublicKey.toBuffer()); await this.#keys.set(`${accountAddress.toString()}-tpk_m`, masterTaggingPublicKey.toBuffer()); - const masterNullifierPublicKeyHash = poseidon2Hash(masterNullifierPublicKey.toFields()); - - // We save nullifier keys and account address to db under the master nullifier key hash - await this.#keys.set(`${masterNullifierPublicKeyHash.toString()}-nsk_m-mnpkh`, masterNullifierSecretKey.toBuffer()); - await this.#keys.set(`${masterNullifierPublicKeyHash.toString()}-npk_m-mnpkh`, masterNullifierPublicKey.toBuffer()); - await this.#keys.set(`${masterNullifierPublicKeyHash.toString()}-accountAddress`, accountAddress.toBuffer()); - // At last, we return the newly derived account address return Promise.resolve(accountAddress); } @@ -88,37 +82,24 @@ export class TestKeyStore implements KeyStore { */ public getAccounts(): Promise { const allMapKeys = Array.from(this.#keys.keys()); - // We return account addresses based on the map keys that end with '-nsk_m-account' - const accounts = allMapKeys.filter(key => key.endsWith('-nsk_m-account')).map(key => key.split('-')[0]); + // We return account addresses based on the map keys that end with '-nsk_m' + const accounts = allMapKeys.filter(key => key.endsWith('-nsk_m')).map(key => key.split('-')[0]); return Promise.resolve(accounts.map(account => AztecAddress.fromString(account))); } /** - * Gets the master nullifier public key for a given account. + * Gets the master nullifier public key for a given account or master nullifier public key hash. * @throws If the account does not exist in the key store. - * @param account - The account address for which to retrieve the master nullifier public key. - * @returns The master nullifier public key for the account. - */ - public async getMasterNullifierPublicKey(account: AztecAddress): Promise { - const masterNullifierPublicKeyBuffer = this.#keys.get(`${account.toString()}-npk_m-account`); - if (!masterNullifierPublicKeyBuffer) { - throw new Error( - `Account ${account.toString()} does not exist. Registered accounts: ${await this.getAccounts()}.`, - ); - } - return Promise.resolve(Point.fromBuffer(masterNullifierPublicKeyBuffer)); - } - - /** - * Gets the master nullifier public key for a given master nullifier public key hash. - * @throws If the master nullifier public key hash does not exist in the key store. - * @param masterNullifierPublicKeyHash - The master nullifier public key hash for which to retrieve the master nullifier public key. + * @param account or master nullifier public key hash - The account address or master nullifier public key hash for which to retrieve the master nullifier public key. * @returns The master nullifier public key for the account. */ - getMasterNullifierPublicKeyWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr): Promise { - const masterNullifierPublicKeyBuffer = this.#keys.get(`${masterNullifierPublicKeyHash.toString()}-npk_m-mnpkh`); + public async getMasterNullifierPublicKey(accountOrMasterNullifierPublicKeyHash: AztecAddress | Fr): Promise { + const masterNullifierPublicKeyBuffer = this.#keys.get(`${accountOrMasterNullifierPublicKeyHash.toString()}-npk_m`) ?? + this.#keys.get(`${this.getAccountAddressForMasterNullifierPublicKeyHashInternal(accountOrMasterNullifierPublicKeyHash)?.toString()}-npk_m`); if (!masterNullifierPublicKeyBuffer) { - throw new Error(`Master nullifier public keys hash ${masterNullifierPublicKeyHash.toString()} does not exist.`); + throw new Error( + `Account or master nullifier public key hash ${accountOrMasterNullifierPublicKeyHash.toString()} does not exist. Registered accounts: ${await this.getAccounts()}.`, + ); } return Promise.resolve(Point.fromBuffer(masterNullifierPublicKeyBuffer)); } @@ -172,38 +153,22 @@ export class TestKeyStore implements KeyStore { } /** - * Retrieves application nullifier secret key. + * Derives and returns the application nullifier secret key for a given account or master nullifier public key hash. * @throws If the account does not exist in the key store. - * @param account - The account to retrieve the application nullifier secret key for. + * @param account or master nullifier public key hash - The account address or master nullifier public key hash for which to retrieve the application nullifier secret key. * @param app - The application address to retrieve the nullifier secret key for. * @returns A Promise that resolves to the application nullifier secret key. */ - public async getAppNullifierSecretKey(account: AztecAddress, app: AztecAddress): Promise { - const masterNullifierSecretKeyBuffer = this.#keys.get(`${account.toString()}-nsk_m-account`); - if (!masterNullifierSecretKeyBuffer) { - throw new Error( - `Account ${account.toString()} does not exist. Registered accounts: ${await this.getAccounts()}.`, - ); - } - const masterNullifierSecretKey = GrumpkinScalar.fromBuffer(masterNullifierSecretKeyBuffer); - const appNullifierSecretKey = computeAppNullifierSecretKey(masterNullifierSecretKey, app); - return Promise.resolve(appNullifierSecretKey); - } - - /** - * Retrieves application nullifier secret key. - * @throws If the masterNullifierPublicKeyHash does not exist in the key store. - * @param masterNullifierPublicKeyHash - The account to retrieve the application nullifier secret key for. - * @param app - The application address to retrieve the nullifier secret key for. - * @returns A Promise that resolves to the application nullifier secret key. - */ - getAppNullifierSecretKeyWithMasterNullifierPublicKeyHash( - masterNullifierPublicKeyHash: Fr, + public async getAppNullifierSecretKey( + accountOrMasterNullifierPublicKeyHash: AztecAddress | Fr, app: AztecAddress, ): Promise { - const masterNullifierSecretKeyBuffer = this.#keys.get(`${masterNullifierPublicKeyHash.toString()}-nsk_m-mnpkh`); + const masterNullifierSecretKeyBuffer = this.#keys.get(`${accountOrMasterNullifierPublicKeyHash.toString()}-nsk_m`) ?? + this.#keys.get(`${this.getAccountAddressForMasterNullifierPublicKeyHashInternal(accountOrMasterNullifierPublicKeyHash)?.toString()}-nsk_m`); if (!masterNullifierSecretKeyBuffer) { - throw new Error(`Master nullifier public keys hash ${masterNullifierPublicKeyHash.toString()} does not exist.`); + throw new Error( + `Account or master nullifier public key hash ${accountOrMasterNullifierPublicKeyHash.toString()} does not exist. Registered accounts: ${await this.getAccounts()}.`, + ); } const masterNullifierSecretKey = GrumpkinScalar.fromBuffer(masterNullifierSecretKeyBuffer); const appNullifierSecretKey = computeAppNullifierSecretKey(masterNullifierSecretKey, app); @@ -273,11 +238,11 @@ export class TestKeyStore implements KeyStore { public getMasterNullifierSecretKeyForPublicKey(masterNullifierPublicKey: PublicKey): Promise { // We iterate over the map keys to find the account address that corresponds to the provided public key for (const [key, value] of this.#keys.entries()) { - if (value.equals(masterNullifierPublicKey.toBuffer()) && key.endsWith('account')) { + if (value.equals(masterNullifierPublicKey.toBuffer()) && key.endsWith('-npk_m')) { // We extract the account address from the map key const accountAddress = key.split('-')[0]; // We fetch the secret key and return it - const masterNullifierSecretKeyBuffer = this.#keys.get(`${accountAddress.toString()}-nsk_m-account`); + const masterNullifierSecretKeyBuffer = this.#keys.get(`${accountAddress.toString()}-nsk_m`); if (!masterNullifierSecretKeyBuffer) { throw new Error(`Could not find master nullifier secret key for account ${accountAddress.toString()}`); } @@ -340,14 +305,15 @@ export class TestKeyStore implements KeyStore { * @param masterNullifierPublicKeyHash - The master nullifier public key hash for which to retrieve the address. * @returns The address for the account. */ - public getAccountAddressForMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr): AztecAddress { - const accountAddressBuffer = this.#keys.get(`${masterNullifierPublicKeyHash.toString()}-accountAddress`); - - if (!accountAddressBuffer) { - throw new Error(`Master nullifier public key hash ${masterNullifierPublicKeyHash.toString()} does not exist.`); + // TODO(#5834): Re-add separation between recipients and accounts in keystore. Refactor this utilizing getAccounts. + public getAccountAddressForMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr) { + const account = this.getAccountAddressForMasterNullifierPublicKeyHashInternal(masterNullifierPublicKeyHash); + if (!account) { + throw new Error( + `Master nullifier public key hash ${masterNullifierPublicKeyHash.toString()} does not exist.`, + ); } - - return AztecAddress.fromBuffer(accountAddressBuffer); + return account; } /** @@ -367,16 +333,24 @@ export class TestKeyStore implements KeyStore { masterOutgoingViewingPublicKey: Point, masterTaggingPublicKey: Point, ): Promise { - await this.#keys.set(`${accountAddress.toString()}-npk_m-account`, masterNullifierPublicKey.toBuffer()); + await this.#keys.set(`${accountAddress.toString()}-npk_m`, masterNullifierPublicKey.toBuffer()); await this.#keys.set(`${accountAddress.toString()}-ivpk_m`, masterIncomingViewingPublicKey.toBuffer()); await this.#keys.set(`${accountAddress.toString()}-ovpk_m`, masterOutgoingViewingPublicKey.toBuffer()); await this.#keys.set(`${accountAddress.toString()}-tpk_m`, masterTaggingPublicKey.toBuffer()); + } - //! This is especially disgusting / hacky, and will be refactored. - const masterNullifierPublicKeyHash = poseidon2Hash(masterNullifierPublicKey.toFields()); + getAccountAddressForMasterNullifierPublicKeyHashInternal(masterNullifierPublicKeyHash: Fr): AztecAddress | undefined { + for (const [key, value] of this.#keys.entries()) { + if (key.endsWith('-npk_m')) { + const computedMasterNullifierPublicKeyHash = poseidon2Hash(Point.fromBuffer(value).toFields()); + if (computedMasterNullifierPublicKeyHash.equals(masterNullifierPublicKeyHash)) { + // We extract the account address from the map key + const accountAddress = key.split('-')[0]; + return AztecAddress.fromString(accountAddress); + } + } + } - // We save nullifier keys and account address to db under the master nullifier key hash - await this.#keys.set(`${masterNullifierPublicKeyHash.toString()}-npk_m-mnpkh`, masterNullifierPublicKey.toBuffer()); - await this.#keys.set(`${masterNullifierPublicKeyHash.toString()}-accountAddress`, accountAddress.toBuffer()); + return undefined; } } diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index 721f84f875f..48004ae8180 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -33,6 +33,7 @@ import { type PublicCallRequest, computeContractClassId, getContractClassFromArtifact, + PublicKeys, } from '@aztec/circuits.js'; import { computeCommitmentNonce, siloNullifier } from '@aztec/circuits.js/hash'; import { type ContractArtifact, type DecodedReturn, FunctionSelector, encodeArguments } from '@aztec/foundation/abi'; @@ -211,30 +212,31 @@ export class PXEService implements PXE { return this.keyStore.getPublicKeysHash(address); } - public async getRegisteredAccountPublicKeys(address: AztecAddress): Promise { + public async getRegisteredAccountPublicKeys(address: AztecAddress): Promise { const accounts = await this.keyStore.getAccounts(); if (!accounts.some(account => account.equals(address))) { return undefined; } - return Promise.all([ - this.keyStore.getMasterNullifierPublicKey(address), - this.keyStore.getMasterIncomingViewingPublicKey(address), - this.keyStore.getMasterOutgoingViewingPublicKey(address), - this.keyStore.getMasterTaggingPublicKey(address), - ]); + + return { + masterNullifierPublicKey: await this.keyStore.getMasterNullifierPublicKey(address), + masterIncomingViewingPublicKey: await this.keyStore.getMasterIncomingViewingPublicKey(address), + masterOutgoingViewingPublicKey: await this.keyStore.getMasterOutgoingViewingPublicKey(address), + masterTaggingPublicKey: await this.keyStore.getMasterTaggingPublicKey(address), + } } - public async registerRecipient(recipient: CompleteAddress, publicKeys: Point[] = []): Promise { + public async registerRecipient(recipient: CompleteAddress, publicKeys?: PublicKeys): Promise { const wasAdded = await this.db.addCompleteAddress(recipient); // TODO #5834: This should be refactored to be okay with only adding complete address - if (publicKeys.length !== 0) { + if (publicKeys !== undefined) { await this.keyStore.addPublicKeysForAccount( recipient.address, - publicKeys[0], - publicKeys[1], - publicKeys[2], - publicKeys[3], + publicKeys.masterNullifierPublicKey, + publicKeys.masterIncomingViewingPublicKey, + publicKeys.masterOutgoingViewingPublicKey, + publicKeys.masterTaggingPublicKey, ); } diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index ff0dcd28648..99814643e93 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -48,10 +48,10 @@ export class SimulatorOracle implements DBOracle { masterNullifierPublicKeyHash: AztecAddress, contractAddress: AztecAddress, ): Promise { - const masterNullifierPublicKey = await this.keyStore.getMasterNullifierPublicKeyWithMasterNullifierPublicKeyHash( + const masterNullifierPublicKey = await this.keyStore.getMasterNullifierPublicKey( masterNullifierPublicKeyHash, ); - const appNullifierSecretKey = await this.keyStore.getAppNullifierSecretKeyWithMasterNullifierPublicKeyHash( + const appNullifierSecretKey = await this.keyStore.getAppNullifierSecretKey( masterNullifierPublicKeyHash, contractAddress, ); From f5659f52eb96cf9b1e9685f0a02446be99545bec Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 3 May 2024 15:34:10 +0000 Subject: [PATCH 43/93] format --- .../aztec.js/src/wallet/base_wallet.ts | 8 ++++- .../circuit-types/src/interfaces/pxe.ts | 8 ++++- .../circuits.js/src/types/public_key.ts | 10 +++--- yarn-project/key-store/src/test_key_store.ts | 32 ++++++++++++------- .../pxe/src/pxe_service/pxe_service.ts | 6 ++-- .../pxe/src/simulator_oracle/index.ts | 4 +-- 6 files changed, 44 insertions(+), 24 deletions(-) diff --git a/yarn-project/aztec.js/src/wallet/base_wallet.ts b/yarn-project/aztec.js/src/wallet/base_wallet.ts index bf6c6aeaef5..bc48e904a7e 100644 --- a/yarn-project/aztec.js/src/wallet/base_wallet.ts +++ b/yarn-project/aztec.js/src/wallet/base_wallet.ts @@ -15,7 +15,13 @@ import { type TxHash, type TxReceipt, } from '@aztec/circuit-types'; -import { PublicKeys, type AztecAddress, type CompleteAddress, type Fr, type PartialAddress, type Point } from '@aztec/circuits.js'; +import { + type AztecAddress, + type CompleteAddress, + type Fr, + type PartialAddress, + type PublicKeys, +} from '@aztec/circuits.js'; import { type ContractArtifact } from '@aztec/foundation/abi'; import { type ContractClassWithId, type ContractInstanceWithAddress } from '@aztec/types/contracts'; import { type NodeInfo } from '@aztec/types/interfaces'; diff --git a/yarn-project/circuit-types/src/interfaces/pxe.ts b/yarn-project/circuit-types/src/interfaces/pxe.ts index db5cc4274f4..e15d1ae0334 100644 --- a/yarn-project/circuit-types/src/interfaces/pxe.ts +++ b/yarn-project/circuit-types/src/interfaces/pxe.ts @@ -1,4 +1,10 @@ -import { type PublicKeys, type AztecAddress, type CompleteAddress, type Fr, type PartialAddress } from '@aztec/circuits.js'; +import { + type AztecAddress, + type CompleteAddress, + type Fr, + type PartialAddress, + type PublicKeys, +} from '@aztec/circuits.js'; import { type ContractArtifact } from '@aztec/foundation/abi'; import { type ContractClassWithId, type ContractInstanceWithAddress } from '@aztec/types/contracts'; import { type NodeInfo } from '@aztec/types/interfaces'; diff --git a/yarn-project/circuits.js/src/types/public_key.ts b/yarn-project/circuits.js/src/types/public_key.ts index e4d135d88ee..817e08f1e51 100644 --- a/yarn-project/circuits.js/src/types/public_key.ts +++ b/yarn-project/circuits.js/src/types/public_key.ts @@ -4,8 +4,8 @@ import { type Point } from '@aztec/foundation/fields'; export type PublicKey = Point; export type PublicKeys = { - masterNullifierPublicKey: Point, - masterIncomingViewingPublicKey: Point, - masterOutgoingViewingPublicKey: Point, - masterTaggingPublicKey: Point, -} + masterNullifierPublicKey: Point; + masterIncomingViewingPublicKey: Point; + masterOutgoingViewingPublicKey: Point; + masterTaggingPublicKey: Point; +}; diff --git a/yarn-project/key-store/src/test_key_store.ts b/yarn-project/key-store/src/test_key_store.ts index c086db4aaaa..76284099f8e 100644 --- a/yarn-project/key-store/src/test_key_store.ts +++ b/yarn-project/key-store/src/test_key_store.ts @@ -93,13 +93,20 @@ export class TestKeyStore implements KeyStore { * @param account or master nullifier public key hash - The account address or master nullifier public key hash for which to retrieve the master nullifier public key. * @returns The master nullifier public key for the account. */ - public async getMasterNullifierPublicKey(accountOrMasterNullifierPublicKeyHash: AztecAddress | Fr): Promise { - const masterNullifierPublicKeyBuffer = this.#keys.get(`${accountOrMasterNullifierPublicKeyHash.toString()}-npk_m`) ?? - this.#keys.get(`${this.getAccountAddressForMasterNullifierPublicKeyHashInternal(accountOrMasterNullifierPublicKeyHash)?.toString()}-npk_m`); + public async getMasterNullifierPublicKey( + accountOrMasterNullifierPublicKeyHash: AztecAddress | Fr, + ): Promise { + const masterNullifierPublicKeyBuffer = + this.#keys.get(`${accountOrMasterNullifierPublicKeyHash.toString()}-npk_m`) ?? + this.#keys.get( + `${this.getAccountAddressForMasterNullifierPublicKeyHashInternal( + accountOrMasterNullifierPublicKeyHash, + )?.toString()}-npk_m`, + ); if (!masterNullifierPublicKeyBuffer) { - throw new Error( - `Account or master nullifier public key hash ${accountOrMasterNullifierPublicKeyHash.toString()} does not exist. Registered accounts: ${await this.getAccounts()}.`, - ); + throw new Error( + `Account or master nullifier public key hash ${accountOrMasterNullifierPublicKeyHash.toString()} does not exist. Registered accounts: ${await this.getAccounts()}.`, + ); } return Promise.resolve(Point.fromBuffer(masterNullifierPublicKeyBuffer)); } @@ -163,8 +170,13 @@ export class TestKeyStore implements KeyStore { accountOrMasterNullifierPublicKeyHash: AztecAddress | Fr, app: AztecAddress, ): Promise { - const masterNullifierSecretKeyBuffer = this.#keys.get(`${accountOrMasterNullifierPublicKeyHash.toString()}-nsk_m`) ?? - this.#keys.get(`${this.getAccountAddressForMasterNullifierPublicKeyHashInternal(accountOrMasterNullifierPublicKeyHash)?.toString()}-nsk_m`); + const masterNullifierSecretKeyBuffer = + this.#keys.get(`${accountOrMasterNullifierPublicKeyHash.toString()}-nsk_m`) ?? + this.#keys.get( + `${this.getAccountAddressForMasterNullifierPublicKeyHashInternal( + accountOrMasterNullifierPublicKeyHash, + )?.toString()}-nsk_m`, + ); if (!masterNullifierSecretKeyBuffer) { throw new Error( `Account or master nullifier public key hash ${accountOrMasterNullifierPublicKeyHash.toString()} does not exist. Registered accounts: ${await this.getAccounts()}.`, @@ -309,9 +321,7 @@ export class TestKeyStore implements KeyStore { public getAccountAddressForMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr) { const account = this.getAccountAddressForMasterNullifierPublicKeyHashInternal(masterNullifierPublicKeyHash); if (!account) { - throw new Error( - `Master nullifier public key hash ${masterNullifierPublicKeyHash.toString()} does not exist.`, - ); + throw new Error(`Master nullifier public key hash ${masterNullifierPublicKeyHash.toString()} does not exist.`); } return account; } diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index 48004ae8180..f937fe5b3c5 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -31,14 +31,14 @@ import { type PartialAddress, type PrivateKernelTailCircuitPublicInputs, type PublicCallRequest, + type PublicKeys, computeContractClassId, getContractClassFromArtifact, - PublicKeys, } from '@aztec/circuits.js'; import { computeCommitmentNonce, siloNullifier } from '@aztec/circuits.js/hash'; import { type ContractArtifact, type DecodedReturn, FunctionSelector, encodeArguments } from '@aztec/foundation/abi'; import { arrayNonEmptyLength, padArrayEnd } from '@aztec/foundation/collection'; -import { Fr, type Point } from '@aztec/foundation/fields'; +import { Fr } from '@aztec/foundation/fields'; import { SerialQueue } from '@aztec/foundation/fifo'; import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { Timer } from '@aztec/foundation/timer'; @@ -223,7 +223,7 @@ export class PXEService implements PXE { masterIncomingViewingPublicKey: await this.keyStore.getMasterIncomingViewingPublicKey(address), masterOutgoingViewingPublicKey: await this.keyStore.getMasterOutgoingViewingPublicKey(address), masterTaggingPublicKey: await this.keyStore.getMasterTaggingPublicKey(address), - } + }; } public async registerRecipient(recipient: CompleteAddress, publicKeys?: PublicKeys): Promise { diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index 99814643e93..427a5e796c7 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -48,9 +48,7 @@ export class SimulatorOracle implements DBOracle { masterNullifierPublicKeyHash: AztecAddress, contractAddress: AztecAddress, ): Promise { - const masterNullifierPublicKey = await this.keyStore.getMasterNullifierPublicKey( - masterNullifierPublicKeyHash, - ); + const masterNullifierPublicKey = await this.keyStore.getMasterNullifierPublicKey(masterNullifierPublicKeyHash); const appNullifierSecretKey = await this.keyStore.getAppNullifierSecretKey( masterNullifierPublicKeyHash, contractAddress, From c8901ff60bd7cea6c6b382c257cee32e57d2c0f4 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 3 May 2024 15:55:49 +0000 Subject: [PATCH 44/93] Adding comments --- noir-projects/aztec-nr/aztec/src/context/private_context.nr | 2 +- noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index 3ff5011afbf..48f6a9216f1 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -224,7 +224,7 @@ impl PrivateContext { keys.app_nullifier_secret_key } - // TODO(ek): Replace request_app_nullifier_secret_key above with this once we no longer get app nullifier secret key with address + // TODO: (#6176) Replace request_app_nullifier_secret_key above with this once we no longer get app nullifier secret key with address pub fn request_app_nullifier_secret_key_with_master_public_nullifying_key_hash(&mut self, master_public_nullifying_key_hash: Field) -> Field { let keys = if self.nullifier_key.is_none() { let keys = get_nullifier_keys_with_master_nullifier_public_key_hash(master_public_nullifying_key_hash); diff --git a/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr b/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr index 13d3184e845..5b8c16ea49b 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr @@ -19,6 +19,7 @@ pub fn get_public_key(address: AztecAddress) -> GrumpkinPoint { pub_key } +// TODO(#5901 -> #5834): This should be refactored, would be most effective to do it after new encrypted log scheme, as well as key store pxe separation. #[oracle(getPublicKeyAndPartialAddressWithMasterNullifierPublicKeyHash)] fn get_public_key_and_partial_address_with_master_nullifier_public_key_hash_oracle(master_nullifier_public_key_hash: Field) -> [Field; 3] {} From ec75986141acfcaeaf705d8ae1fe34a87ef40773 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 3 May 2024 16:04:21 +0000 Subject: [PATCH 45/93] comments --- noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr | 2 +- yarn-project/circuit-types/src/keys/key_store.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr b/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr index 077672399ee..1af61f659a5 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr @@ -2,7 +2,7 @@ use dep::protocol_types::{address::AztecAddress, grumpkin_point::GrumpkinPoint, // Nullifier keys pertaining to a specific account struct NullifierKeys { - // TODO: (ek) Replace this with master_nullifier_public_key_hash + // TODO (#6176): Replace get_nullifier_keys above with this once we no longer get nullifier keys with address account: AztecAddress, master_nullifier_public_key: GrumpkinPoint, app_nullifier_secret_key: Field, diff --git a/yarn-project/circuit-types/src/keys/key_store.ts b/yarn-project/circuit-types/src/keys/key_store.ts index 06a6e55042a..c804eb87006 100644 --- a/yarn-project/circuit-types/src/keys/key_store.ts +++ b/yarn-project/circuit-types/src/keys/key_store.ts @@ -70,7 +70,7 @@ export interface KeyStore { * @param app - The application address to retrieve the nullifier secret key for. * @returns A Promise that resolves to the application nullifier secret key. */ - getAppNullifierSecretKey(account: AztecAddress, app: AztecAddress): Promise; + getAppNullifierSecretKey(accountOrMasterNullifierPublicKeyHash: AztecAddress | Fr, app: AztecAddress): Promise; /** * Retrieves application incoming viewing secret key. From 4bfaefaafa6c8ff64f949a727636885f02bd43a1 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 3 May 2024 16:09:30 +0000 Subject: [PATCH 46/93] why --- barretenberg/ts/src/examples/simple.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/barretenberg/ts/src/examples/simple.test.ts b/barretenberg/ts/src/examples/simple.test.ts index 4af243a631d..0b2ad74c523 100644 --- a/barretenberg/ts/src/examples/simple.test.ts +++ b/barretenberg/ts/src/examples/simple.test.ts @@ -14,7 +14,7 @@ describe('simple', () => { const crs = await Crs.new(2 ** 19 + 1); await api.srsInitSrs(new RawBuffer(crs.getG1Data()), crs.numPoints, new RawBuffer(crs.getG2Data())); - }, 30000); + }, 60_000); afterAll(async () => { await api.destroy(); From d9704abe0fe6babdcb46e7b8a91d31c407730f26 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Sat, 4 May 2024 12:04:24 +0000 Subject: [PATCH 47/93] fix --- noir-projects/aztec-nr/aztec/src/context/private_context.nr | 2 +- yarn-project/pxe/src/pxe_service/pxe_service.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index 2329abf3af5..7b0a92ba2b3 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -9,7 +9,7 @@ use crate::{ nullifier_key::{get_nullifier_keys, get_nullifier_keys_with_master_nullifier_public_key_hash, NullifierKeys}, enqueue_public_function_call::{ enqueue_public_function_call_internal, set_public_teardown_function_call_internal, - parse_public_call_stack_item_from_oracle + parse_public_call_stack_item_from_oracle}, }, }; use dep::protocol_types::{ diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index d46a75d57b8..3d7a3e682a8 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -30,7 +30,7 @@ import { MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, type PartialAddress, type PrivateKernelTailCircuitPublicInputs, - type PublicCallRequest, + PublicCallRequest, type PublicKeys, computeContractClassId, getContractClassFromArtifact, From b9733a0ab59ad738266de311163843882eeddc3b Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Mon, 6 May 2024 10:58:48 +0000 Subject: [PATCH 48/93] Fix --- noir-projects/aztec-nr/aztec/src/keys/getters.nr | 6 +++++- .../token_contract/src/types/balances_map.nr | 6 +++--- yarn-project/end-to-end/src/e2e_key_registry.test.ts | 12 ++++++------ 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/keys/getters.nr b/noir-projects/aztec-nr/aztec/src/keys/getters.nr index b6fc2759fb7..f06f4b0ce5c 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/getters.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/getters.nr @@ -1,4 +1,4 @@ -use dep::protocol_types::{address::AztecAddress, constants::CANONICAL_KEY_REGISTRY_ADDRESS, grumpkin_point::GrumpkinPoint}; +use dep::protocol_types::{address::AztecAddress, constants::CANONICAL_KEY_REGISTRY_ADDRESS, grumpkin_point::GrumpkinPoint, hash::poseidon2_hash}; use crate::{ context::PrivateContext, oracle::keys::get_public_keys_and_partial_address, state_vars::{ @@ -22,6 +22,10 @@ pub fn get_npk_m(context: &mut PrivateContext, address: AztecAddress) -> Grumpki get_master_key(context, address, NULLIFIER_INDEX) } +pub fn get_npk_m_hash(context: &mut PrivateContext, address: AztecAddress) -> Field { + poseidon2_hash(get_master_key(context, address, NULLIFIER_INDEX).serialize()) +} + pub fn get_ivpk_m(context: &mut PrivateContext, address: AztecAddress) -> GrumpkinPoint { get_master_key(context, address, INCOMING_INDEX) } diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr index 249a5f5ed7c..9cbd4530aaa 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr @@ -4,9 +4,9 @@ use dep::aztec::prelude::{ }; use dep::aztec::{ context::{PublicContext, Context}, hash::pedersen_hash, - protocol_types::constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, + protocol_types::{constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, hash::poseidon2_hash}, note::{note_getter::view_notes, note_getter_options::SortOrder}, - keys::getters::get_fresh_nullifier_public_key_hash, + keys::getters::get_npk_m_hash, }; use crate::types::token_note::{TokenNote, OwnedNote}; @@ -62,7 +62,7 @@ impl BalancesMap { addend: U128 ) where T: NoteInterface + OwnedNote { // We fetch the nullifier public key hash in the registry / from our PXE - let nullifier_public_key_hash = get_fresh_nullifier_public_key_hash(self.map.context.private.unwrap(), owner); + let nullifier_public_key_hash = get_npk_m_hash(self.map.context.private.unwrap(), owner); let mut addend_note = T::new(addend, nullifier_public_key_hash); 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 index 48fb1fa90ab..dbb3119e448 100644 --- a/yarn-project/end-to-end/src/e2e_key_registry.test.ts +++ b/yarn-project/end-to-end/src/e2e_key_registry.test.ts @@ -113,12 +113,12 @@ describe('Key Registry', () => { newAccountPartialAddress, ); - await pxe.registerRecipient(newAccountCompleteAddress, [ - newAccountKeys.masterNullifierPublicKey, - newAccountKeys.masterIncomingViewingPublicKey, - newAccountKeys.masterOutgoingViewingPublicKey, - newAccountKeys.masterTaggingPublicKey, - ]); + await pxe.registerRecipient(newAccountCompleteAddress, { + masterNullifierPublicKey: newAccountKeys.masterNullifierPublicKey, + masterIncomingViewingPublicKey: newAccountKeys.masterIncomingViewingPublicKey, + masterOutgoingViewingPublicKey: newAccountKeys.masterOutgoingViewingPublicKey, + masterTaggingPublicKey: newAccountKeys.masterTaggingPublicKey, + }); // Should succeed as the account is now registered as a recipient in PXE await testContract.methods From 9a3829cad35ee4c13220c25913ad6c4dd544af98 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Mon, 6 May 2024 11:05:13 +0000 Subject: [PATCH 49/93] fix --- yarn-project/end-to-end/src/e2e_key_registry.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index dbb3119e448..8ab96d0d1dc 100644 --- a/yarn-project/end-to-end/src/e2e_key_registry.test.ts +++ b/yarn-project/end-to-end/src/e2e_key_registry.test.ts @@ -118,7 +118,7 @@ describe('Key Registry', () => { masterIncomingViewingPublicKey: newAccountKeys.masterIncomingViewingPublicKey, masterOutgoingViewingPublicKey: newAccountKeys.masterOutgoingViewingPublicKey, masterTaggingPublicKey: newAccountKeys.masterTaggingPublicKey, - }); + }); // Should succeed as the account is now registered as a recipient in PXE await testContract.methods From b432ad23c245ce191bb1d772986836e9ef41c516 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Wed, 8 May 2024 10:02:04 +0000 Subject: [PATCH 50/93] Fix naming --- .../aztec/src/context/private_context.nr | 10 ++++----- .../aztec-nr/aztec/src/keys/getters.nr | 2 +- .../aztec/src/oracle/get_public_key.nr | 10 ++++----- .../aztec/src/oracle/nullifier_key.nr | 14 ++++++------ .../token_contract/src/types/balances_map.nr | 4 ++-- .../token_contract/src/types/token_note.nr | 22 +++++++++---------- 6 files changed, 30 insertions(+), 32 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index 7b0a92ba2b3..b6ca4d8f84e 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -6,7 +6,7 @@ use crate::{ arguments, returns, call_private_function::call_private_function_internal, header::get_header_at, logs::emit_encrypted_log, logs_traits::{LensForEncryptedLog, ToBytesForUnencryptedLog}, - nullifier_key::{get_nullifier_keys, get_nullifier_keys_with_master_nullifier_public_key_hash, NullifierKeys}, + nullifier_key::{get_nullifier_keys, get_nk_with_npk_m_h, NullifierKeys}, enqueue_public_function_call::{ enqueue_public_function_call_internal, set_public_teardown_function_call_internal, parse_public_call_stack_item_from_oracle}, @@ -227,10 +227,9 @@ impl PrivateContext { } // TODO: (#6176) Replace request_app_nullifier_secret_key above with this once we no longer get app nullifier secret key with address - pub fn request_app_nullifier_secret_key_with_master_public_nullifying_key_hash(&mut self, master_public_nullifying_key_hash: Field) -> Field { + pub fn request_nsk_app_with_npk_m_h(&mut self, master_public_nullifying_key_hash: Field) -> Field { let keys = if self.nullifier_key.is_none() { - let keys = get_nullifier_keys_with_master_nullifier_public_key_hash(master_public_nullifying_key_hash); - assert_eq(poseidon2_hash(keys.master_nullifier_public_key.serialize()), master_public_nullifying_key_hash); + let keys = get_nk_with_npk_m_h(master_public_nullifying_key_hash); let request = NullifierKeyValidationRequest { master_nullifier_public_key: keys.master_nullifier_public_key, app_nullifier_secret_key: keys.app_nullifier_secret_key @@ -245,8 +244,7 @@ impl PrivateContext { keys }; - // TODO: (#6176) (ek) Enable this after we nuke the account in all notes and when NullifierKeys has a reference to master_nullifier_public_key_hash - // assert_eq(keys.master_nullifier_public_key_hash, master_public_nullifying_key_hash); + assert_eq(poseidon2_hash(keys.master_nullifier_public_key.serialize()), master_public_nullifying_key_hash); keys.app_nullifier_secret_key } diff --git a/noir-projects/aztec-nr/aztec/src/keys/getters.nr b/noir-projects/aztec-nr/aztec/src/keys/getters.nr index f06f4b0ce5c..5371272bada 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/getters.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/getters.nr @@ -22,7 +22,7 @@ pub fn get_npk_m(context: &mut PrivateContext, address: AztecAddress) -> Grumpki get_master_key(context, address, NULLIFIER_INDEX) } -pub fn get_npk_m_hash(context: &mut PrivateContext, address: AztecAddress) -> Field { +pub fn get_npk_m_h(context: &mut PrivateContext, address: AztecAddress) -> Field { poseidon2_hash(get_master_key(context, address, NULLIFIER_INDEX).serialize()) } diff --git a/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr b/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr index 5b8c16ea49b..3af70b10c91 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr @@ -21,16 +21,16 @@ pub fn get_public_key(address: AztecAddress) -> GrumpkinPoint { // TODO(#5901 -> #5834): This should be refactored, would be most effective to do it after new encrypted log scheme, as well as key store pxe separation. #[oracle(getPublicKeyAndPartialAddressWithMasterNullifierPublicKeyHash)] -fn get_public_key_and_partial_address_with_master_nullifier_public_key_hash_oracle(master_nullifier_public_key_hash: Field) -> [Field; 3] {} +fn get_public_key_and_partial_address_with_npk_m_h_oracle(master_nullifier_public_key_hash: Field) -> [Field; 3] {} -unconstrained fn get_public_key_and_partial_address_with_master_nullifier_public_key_hash_internal(master_nullifier_public_key_hash: Field) -> [Field; 3] { - get_public_key_and_partial_address_with_master_nullifier_public_key_hash_oracle(master_nullifier_public_key_hash) +unconstrained fn get_public_key_and_partial_address_with_npk_m_h_internal(master_nullifier_public_key_hash: Field) -> [Field; 3] { + get_public_key_and_partial_address_with_npk_m_h_oracle(master_nullifier_public_key_hash) } // TODO (#5901): This is used when we emit encrypted logs and will be changed. // TODO (#6178): This function should not be contraining things here. -pub fn get_public_key_with_master_nullifier_public_key_hash(master_nullifier_public_key_hash: Field) -> GrumpkinPoint { - let result = get_public_key_and_partial_address_with_master_nullifier_public_key_hash_internal(master_nullifier_public_key_hash); +pub fn get_public_key_with_npk_m_h(master_nullifier_public_key_hash: Field) -> GrumpkinPoint { + let result = get_public_key_and_partial_address_with_npk_m_h_internal(master_nullifier_public_key_hash); let pub_key = GrumpkinPoint::new(result[0], result[1]); let partial_address = PartialAddress::from_field(result[2]); diff --git a/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr b/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr index 1af61f659a5..cf0117268f3 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr @@ -30,10 +30,10 @@ pub fn get_app_nullifier_secret_key(account: AztecAddress) -> Field { // TODO (#6176): Replace get_nullifier_keys above with this once we no longer get nullifier keys with address #[oracle(getNullifierKeysWithMasterNullifierPublicKeyHash)] -fn get_nullifier_keys_with_master_nullifier_public_key_hash_oracle(_master_nullifier_public_key_hash: Field) -> [Field; 3] {} +fn get_nk_with_npk_m_h_oracle(_master_nullifier_public_key_hash: Field) -> [Field; 3] {} -unconstrained fn get_nullifier_keys_with_master_nullifier_public_key_hash_internal(master_nullifier_public_key_hash: Field) -> NullifierKeys { - let result = get_nullifier_keys_with_master_nullifier_public_key_hash_oracle(master_nullifier_public_key_hash); +unconstrained fn get_nk_with_npk_m_h_internal(master_nullifier_public_key_hash: Field) -> NullifierKeys { + let result = get_nk_with_npk_m_h_oracle(master_nullifier_public_key_hash); NullifierKeys { account: AztecAddress::zero(), master_nullifier_public_key: GrumpkinPoint { x: result[0], y: result[1] }, @@ -42,11 +42,11 @@ unconstrained fn get_nullifier_keys_with_master_nullifier_public_key_hash_intern } // We get the full struct Nullifier Keys here -pub fn get_nullifier_keys_with_master_nullifier_public_key_hash(master_nullifier_public_key_hash: Field) -> NullifierKeys { - get_nullifier_keys_with_master_nullifier_public_key_hash_internal(master_nullifier_public_key_hash) +pub fn get_nk_with_npk_m_h(master_nullifier_public_key_hash: Field) -> NullifierKeys { + get_nk_with_npk_m_h_internal(master_nullifier_public_key_hash) } // We are only getting the app_nullifier_secret_key here -pub fn get_app_nullifier_secret_key_with_master_nullifier_public_key_hash(master_nullifier_public_key_hash: Field) -> Field { - get_nullifier_keys_with_master_nullifier_public_key_hash_internal(master_nullifier_public_key_hash).app_nullifier_secret_key +pub fn get_nsk_app_with_npk_m_h(master_nullifier_public_key_hash: Field) -> Field { + get_nk_with_npk_m_h_internal(master_nullifier_public_key_hash).app_nullifier_secret_key } diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr index 9cbd4530aaa..ad8f7ff0dca 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr @@ -6,7 +6,7 @@ use dep::aztec::{ context::{PublicContext, Context}, hash::pedersen_hash, protocol_types::{constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, hash::poseidon2_hash}, note::{note_getter::view_notes, note_getter_options::SortOrder}, - keys::getters::get_npk_m_hash, + keys::getters::get_npk_m_h, }; use crate::types::token_note::{TokenNote, OwnedNote}; @@ -62,7 +62,7 @@ impl BalancesMap { addend: U128 ) where T: NoteInterface + OwnedNote { // We fetch the nullifier public key hash in the registry / from our PXE - let nullifier_public_key_hash = get_npk_m_hash(self.map.context.private.unwrap(), owner); + let nullifier_public_key_hash = get_npk_m_h(self.map.context.private.unwrap(), owner); let mut addend_note = T::new(addend, nullifier_public_key_hash); diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr index e408237fd09..5e64fcfdac3 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr @@ -2,13 +2,13 @@ use dep::aztec::{ prelude::{AztecAddress, NoteHeader, NoteInterface, PrivateContext}, protocol_types::constants::GENERATOR_INDEX__NOTE_NULLIFIER, note::utils::compute_note_hash_for_consumption, hash::poseidon2_hash, - oracle::{unsafe_rand::unsafe_rand, nullifier_key::get_app_nullifier_secret_key_with_master_nullifier_public_key_hash, get_public_key::get_public_key_with_master_nullifier_public_key_hash} + oracle::{unsafe_rand::unsafe_rand, nullifier_key::get_nsk_app_with_npk_m_h, get_public_key::get_public_key_with_npk_m_h} }; trait OwnedNote { - fn new(amount: U128, owner_nullifying_public_key_hash: Field) -> Self; + fn new(amount: U128, owner_npk_m_h: Field) -> Self; fn get_amount(self) -> U128; - fn get_owner_nullifying_public_key_hash(self) -> Field; + fn get_owner_npk_m_h(self) -> Field; } global TOKEN_NOTE_LEN: Field = 3; // 3 plus a header. @@ -19,7 +19,7 @@ struct TokenNote { amount: U128, // The nullifying public key hash of the person who owns the note. // This is used with the app_nullifier_secret_key to ensure that the note can be privately spent. - owner_nullifying_public_key_hash: Field, + owner_npk_m_h: Field, // Randomness of the note to hide its contents randomness: Field, } @@ -28,7 +28,7 @@ impl NoteInterface for TokenNote { // docs:start:nullifier fn compute_nullifier(self, context: &mut PrivateContext) -> Field { let note_hash_for_nullify = compute_note_hash_for_consumption(self); - let secret = context.request_app_nullifier_secret_key_with_master_public_nullifying_key_hash(self.owner_nullifying_public_key_hash); + let secret = context.request_nsk_app_with_npk_m_h(self.owner_npk_m_h); poseidon2_hash([ note_hash_for_nullify, secret, @@ -39,7 +39,7 @@ impl NoteInterface for TokenNote { fn compute_nullifier_without_context(self) -> Field { let note_hash_for_nullify = compute_note_hash_for_consumption(self); - let secret = get_app_nullifier_secret_key_with_master_nullifier_public_key_hash(self.owner_nullifying_public_key_hash); + let secret = get_nsk_app_with_npk_m_h(self.owner_npk_m_h); poseidon2_hash([ note_hash_for_nullify, secret, @@ -52,7 +52,7 @@ impl NoteInterface for TokenNote { // We only bother inserting the note if non-empty to save funds on gas. // TODO: (#5901) This will be changed a lot, as it should use the updated encrypted log format if !(self.amount == U128::from_integer(0)) { - let encryption_pub_key = get_public_key_with_master_nullifier_public_key_hash(self.owner_nullifying_public_key_hash); + let encryption_pub_key = get_public_key_with_npk_m_h(self.owner_npk_m_h); context.emit_encrypted_log( (*context).this_address(), slot, @@ -65,10 +65,10 @@ impl NoteInterface for TokenNote { } impl OwnedNote for TokenNote { - fn new(amount: U128, owner_nullifying_public_key_hash: Field) -> Self { + fn new(amount: U128, owner_npk_m_h: Field) -> Self { Self { amount, - owner_nullifying_public_key_hash, + owner_npk_m_h, randomness: unsafe_rand(), header: NoteHeader::empty(), } @@ -78,7 +78,7 @@ impl OwnedNote for TokenNote { self.amount } - fn get_owner_nullifying_public_key_hash(self) -> Field { - self.owner_nullifying_public_key_hash + fn get_owner_npk_m_h(self) -> Field { + self.owner_npk_m_h } } From f734d3fcd9ea61ade3f1cdba7e3bd6b534f833cf Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Wed, 8 May 2024 10:16:42 +0000 Subject: [PATCH 51/93] address comments --- .../aztec-nr/aztec/src/oracle/get_public_key.nr | 2 +- .../aztec-nr/aztec/src/oracle/nullifier_key.nr | 2 +- yarn-project/pxe/src/simulator_oracle/index.ts | 6 +++--- yarn-project/simulator/src/acvm/oracle/oracle.ts | 15 ++++++--------- .../simulator/src/acvm/oracle/typed_oracle.ts | 8 ++++---- yarn-project/simulator/src/client/db_oracle.ts | 7 ++----- .../simulator/src/client/simulator.test.ts | 2 +- .../simulator/src/client/view_data_oracle.ts | 12 ++++-------- 8 files changed, 22 insertions(+), 32 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr b/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr index 3af70b10c91..08ff0f5a97a 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr @@ -20,7 +20,7 @@ pub fn get_public_key(address: AztecAddress) -> GrumpkinPoint { } // TODO(#5901 -> #5834): This should be refactored, would be most effective to do it after new encrypted log scheme, as well as key store pxe separation. -#[oracle(getPublicKeyAndPartialAddressWithMasterNullifierPublicKeyHash)] +#[oracle(getPublicKeyAndPartialAddressWithNpkMH)] fn get_public_key_and_partial_address_with_npk_m_h_oracle(master_nullifier_public_key_hash: Field) -> [Field; 3] {} unconstrained fn get_public_key_and_partial_address_with_npk_m_h_internal(master_nullifier_public_key_hash: Field) -> [Field; 3] { diff --git a/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr b/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr index cf0117268f3..fdee2cebcf0 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr @@ -29,7 +29,7 @@ pub fn get_app_nullifier_secret_key(account: AztecAddress) -> Field { } // TODO (#6176): Replace get_nullifier_keys above with this once we no longer get nullifier keys with address -#[oracle(getNullifierKeysWithMasterNullifierPublicKeyHash)] +#[oracle(getNullifierKeysWithNpkMH)] fn get_nk_with_npk_m_h_oracle(_master_nullifier_public_key_hash: Field) -> [Field; 3] {} unconstrained fn get_nk_with_npk_m_h_internal(master_nullifier_public_key_hash: Field) -> NullifierKeys { diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index 3b2f3a6a34c..328e40a835e 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -44,7 +44,7 @@ export class SimulatorOracle implements DBOracle { return { masterNullifierPublicKey, appNullifierSecretKey }; } - async getNullifierKeysWithMasterNullifierPublicKeyHash( + async getNullifierKeysWithNpkMH( masterNullifierPublicKeyHash: AztecAddress, contractAddress: AztecAddress, ): Promise { @@ -68,8 +68,8 @@ export class SimulatorOracle implements DBOracle { } // TODO: #5834 - getCompleteAddressWithMasterNullifierPublicKey(masterNullifierPublicKey: Fr): Promise { - const address = this.keyStore.getAccountAddressForMasterNullifierPublicKeyHash(masterNullifierPublicKey); + getCompleteAddressWithNpkMH(masterNullifierPublicKeyHash: Fr): Promise { + const address = this.keyStore.getAccountAddressForMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash); return this.getCompleteAddress(address); } diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index 955e2d06b9a..02f696f1b77 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -53,13 +53,10 @@ export class Oracle { ]; } - async getNullifierKeysWithMasterNullifierPublicKeyHash([masterNullifierPublicKeyHash]: ACVMField[]): Promise< - ACVMField[] - > { - const { masterNullifierPublicKey, appNullifierSecretKey } = - await this.typedOracle.getNullifierKeysWithMasterNullifierPublicKeyHash( - fromACVMField(masterNullifierPublicKeyHash), - ); + async getNullifierKeysWithNpkMH([masterNullifierPublicKeyHash]: ACVMField[]): Promise { + const { masterNullifierPublicKey, appNullifierSecretKey } = await this.typedOracle.getNullifierKeysWithNpkMH( + fromACVMField(masterNullifierPublicKeyHash), + ); return [ toACVMField(masterNullifierPublicKey.x), toACVMField(masterNullifierPublicKey.y), @@ -76,8 +73,8 @@ export class Oracle { } // TODO: #5834 Nuke this - async getPublicKeyAndPartialAddressWithMasterNullifierPublicKeyHash([masterNullifierPublicKeyHash]: ACVMField[]) { - const { publicKey, partialAddress } = await this.typedOracle.getCompleteAddressWithMasterNullifierPublicKey( + async getPublicKeyAndPartialAddressWithNpkMH([masterNullifierPublicKeyHash]: ACVMField[]) { + const { publicKey, partialAddress } = await this.typedOracle.getCompleteAddressWithNpkMH( fromACVMField(masterNullifierPublicKeyHash), ); return [publicKey.x, publicKey.y, partialAddress].map(toACVMField); diff --git a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts index 314029a12e8..5ea9023698f 100644 --- a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts @@ -93,8 +93,8 @@ export abstract class TypedOracle { throw new OracleMethodNotAvailableError('getNullifierKeys'); } - getNullifierKeysWithMasterNullifierPublicKeyHash(_masterNullifierPublicKeyHash: Fr): Promise { - throw new OracleMethodNotAvailableError('getNullifierKeysWithMasterNullifierPublicKeyHash'); + getNullifierKeysWithNpkMH(_masterNullifierPublicKeyHash: Fr): Promise { + throw new OracleMethodNotAvailableError('getNullifierKeysWithNpkMH'); } getPublicKeyAndPartialAddress(_address: AztecAddress): Promise { @@ -136,8 +136,8 @@ export abstract class TypedOracle { throw new OracleMethodNotAvailableError('getCompleteAddress'); } - getCompleteAddressWithMasterNullifierPublicKey(_masterNullifierPublicKeyHash: Fr): Promise { - throw new OracleMethodNotAvailableError('getCompleteAddressWithMasterNullifierPublicKey'); + getCompleteAddressWithNpkMH(_masterNullifierPublicKeyHash: Fr): Promise { + throw new OracleMethodNotAvailableError('getCompleteAddressWithNpkMH'); } getAuthWitness(_messageHash: Fr): Promise { diff --git a/yarn-project/simulator/src/client/db_oracle.ts b/yarn-project/simulator/src/client/db_oracle.ts index 028bae9a303..b517a53c9fe 100644 --- a/yarn-project/simulator/src/client/db_oracle.ts +++ b/yarn-project/simulator/src/client/db_oracle.ts @@ -55,7 +55,7 @@ export interface DBOracle extends CommitmentsDB { * @param masterNullifierPublicKeyHash - Master nullifier public key hash to fetch the complete address for. * @returns A complete address associated with the input master nullifier public key hash. */ - getCompleteAddressWithMasterNullifierPublicKey(masterNullifierPublicKey: Fr): Promise; + getCompleteAddressWithNpkMH(masterNullifierPublicKeyHash: Fr): Promise; /** * Retrieve the auth witness for a given message hash. @@ -97,10 +97,7 @@ export interface DBOracle extends CommitmentsDB { * @returns A Promise that resolves to nullifier keys of a requested account and contract. * @throws An error if the account is not registered in the database. */ - getNullifierKeysWithMasterNullifierPublicKeyHash( - masterNullifierPublicKeyHash: Fr, - contractAddress: AztecAddress, - ): Promise; + getNullifierKeysWithNpkMH(masterNullifierPublicKeyHash: Fr, contractAddress: AztecAddress): Promise; /** * Retrieves a set of notes stored in the database for a given contract address and storage slot. diff --git a/yarn-project/simulator/src/client/simulator.test.ts b/yarn-project/simulator/src/client/simulator.test.ts index a4c6f419232..cb22aa7eed9 100644 --- a/yarn-project/simulator/src/client/simulator.test.ts +++ b/yarn-project/simulator/src/client/simulator.test.ts @@ -43,7 +43,7 @@ describe('Simulator', () => { oracle = mock(); node = mock(); - oracle.getNullifierKeysWithMasterNullifierPublicKeyHash.mockResolvedValue({ + oracle.getNullifierKeysWithNpkMH.mockResolvedValue({ masterNullifierPublicKey: ownerMasterNullifierPublicKey, appNullifierSecretKey, }); diff --git a/yarn-project/simulator/src/client/view_data_oracle.ts b/yarn-project/simulator/src/client/view_data_oracle.ts index 7e0b27a1726..3f4c63ae8e5 100644 --- a/yarn-project/simulator/src/client/view_data_oracle.ts +++ b/yarn-project/simulator/src/client/view_data_oracle.ts @@ -50,10 +50,8 @@ export class ViewDataOracle extends TypedOracle { * @returns A Promise that resolves to nullifier keys of a requested account and contract. * @throws An error if the account is not registered in the database. */ - public override getNullifierKeysWithMasterNullifierPublicKeyHash( - masterNullifierPublicKeyHash: Fr, - ): Promise { - return this.db.getNullifierKeysWithMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash, this.contractAddress); + public override getNullifierKeysWithNpkMH(masterNullifierPublicKeyHash: Fr): Promise { + return this.db.getNullifierKeysWithNpkMH(masterNullifierPublicKeyHash, this.contractAddress); } /** @@ -152,10 +150,8 @@ export class ViewDataOracle extends TypedOracle { * @param masterNullifierPublicKeyHash - Master nullifier public key hash to fetch the complete address for. * @returns A complete address associated with the input master nullifier public key hash. */ - public override getCompleteAddressWithMasterNullifierPublicKey( - masterNullifierPublicKeyHash: Fr, - ): Promise { - return this.db.getCompleteAddressWithMasterNullifierPublicKey(masterNullifierPublicKeyHash); + public override getCompleteAddressWithNpkMH(masterNullifierPublicKeyHash: Fr): Promise { + return this.db.getCompleteAddressWithNpkMH(masterNullifierPublicKeyHash); } /** From 04f058f8be3d6f79adde20883070d839014786d7 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Wed, 8 May 2024 10:56:49 +0000 Subject: [PATCH 52/93] fix --- noir-projects/aztec-nr/aztec/src/context/private_context.nr | 1 + 1 file changed, 1 insertion(+) diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index b6ca4d8f84e..f8053bff359 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -244,6 +244,7 @@ impl PrivateContext { keys }; + // We have to check if the key that was requested or cached corresponds to the one we request for assert_eq(poseidon2_hash(keys.master_nullifier_public_key.serialize()), master_public_nullifying_key_hash); keys.app_nullifier_secret_key } From 76850bdcd52782263438cd63d426d84e85d1e36c Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Wed, 8 May 2024 11:07:49 +0000 Subject: [PATCH 53/93] fix --- .../aztec-nr/aztec/src/context/private_context.nr | 4 ++-- .../aztec-nr/aztec/src/oracle/nullifier_key.nr | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index f8053bff359..49ea7ed44ac 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -6,7 +6,7 @@ use crate::{ arguments, returns, call_private_function::call_private_function_internal, header::get_header_at, logs::emit_encrypted_log, logs_traits::{LensForEncryptedLog, ToBytesForUnencryptedLog}, - nullifier_key::{get_nullifier_keys, get_nk_with_npk_m_h, NullifierKeys}, + nullifier_key::{get_nullifier_keys, get_nullifier_keys_with_npk_m_h, NullifierKeys}, enqueue_public_function_call::{ enqueue_public_function_call_internal, set_public_teardown_function_call_internal, parse_public_call_stack_item_from_oracle}, @@ -229,7 +229,7 @@ impl PrivateContext { // TODO: (#6176) Replace request_app_nullifier_secret_key above with this once we no longer get app nullifier secret key with address pub fn request_nsk_app_with_npk_m_h(&mut self, master_public_nullifying_key_hash: Field) -> Field { let keys = if self.nullifier_key.is_none() { - let keys = get_nk_with_npk_m_h(master_public_nullifying_key_hash); + let keys = get_nullifier_keys_with_npk_m_h(master_public_nullifying_key_hash); let request = NullifierKeyValidationRequest { master_nullifier_public_key: keys.master_nullifier_public_key, app_nullifier_secret_key: keys.app_nullifier_secret_key diff --git a/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr b/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr index fdee2cebcf0..4040633ca34 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr @@ -30,10 +30,10 @@ pub fn get_app_nullifier_secret_key(account: AztecAddress) -> Field { // TODO (#6176): Replace get_nullifier_keys above with this once we no longer get nullifier keys with address #[oracle(getNullifierKeysWithNpkMH)] -fn get_nk_with_npk_m_h_oracle(_master_nullifier_public_key_hash: Field) -> [Field; 3] {} +fn get_nullifier_keys_with_npk_m_h_oracle(_master_nullifier_public_key_hash: Field) -> [Field; 3] {} -unconstrained fn get_nk_with_npk_m_h_internal(master_nullifier_public_key_hash: Field) -> NullifierKeys { - let result = get_nk_with_npk_m_h_oracle(master_nullifier_public_key_hash); +unconstrained fn get_nullifier_keys_with_npk_m_h_internal(master_nullifier_public_key_hash: Field) -> NullifierKeys { + let result = get_nullifier_keys_with_npk_m_h_oracle(master_nullifier_public_key_hash); NullifierKeys { account: AztecAddress::zero(), master_nullifier_public_key: GrumpkinPoint { x: result[0], y: result[1] }, @@ -42,11 +42,11 @@ unconstrained fn get_nk_with_npk_m_h_internal(master_nullifier_public_key_hash: } // We get the full struct Nullifier Keys here -pub fn get_nk_with_npk_m_h(master_nullifier_public_key_hash: Field) -> NullifierKeys { - get_nk_with_npk_m_h_internal(master_nullifier_public_key_hash) +pub fn get_nullifier_keys_with_npk_m_h(master_nullifier_public_key_hash: Field) -> NullifierKeys { + get_nullifier_keys_with_npk_m_h_internal(master_nullifier_public_key_hash) } // We are only getting the app_nullifier_secret_key here pub fn get_nsk_app_with_npk_m_h(master_nullifier_public_key_hash: Field) -> Field { - get_nk_with_npk_m_h_internal(master_nullifier_public_key_hash).app_nullifier_secret_key + get_nullifier_keys_with_npk_m_h_internal(master_nullifier_public_key_hash).app_nullifier_secret_key } From 4f86276fb194ac407119a602c33df2945a0346b2 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Wed, 8 May 2024 11:11:05 +0000 Subject: [PATCH 54/93] fix --- .../contracts/token_contract/src/types/balances_map.nr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr index ad8f7ff0dca..82a76f4b792 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr @@ -62,9 +62,9 @@ impl BalancesMap { addend: U128 ) where T: NoteInterface + OwnedNote { // We fetch the nullifier public key hash in the registry / from our PXE - let nullifier_public_key_hash = get_npk_m_h(self.map.context.private.unwrap(), owner); + let owner_npk_m_h = get_npk_m_h(self.map.context.private.unwrap(), owner); - let mut addend_note = T::new(addend, nullifier_public_key_hash); + let mut addend_note = T::new(addend, owner_npk_m_h); // docs:start:insert self.map.at(owner).insert(&mut addend_note, true); From b85388dc5cda86013f17d0a08746f3a357c9dd6e Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Wed, 8 May 2024 19:14:38 +0000 Subject: [PATCH 55/93] fix formatting --- .../contracts/token_contract/src/types/balances_map.nr | 3 +-- .../contracts/token_contract/src/types/token_note.nr | 5 ++++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr index 82a76f4b792..ffe373fc501 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr @@ -5,8 +5,7 @@ use dep::aztec::prelude::{ use dep::aztec::{ context::{PublicContext, Context}, hash::pedersen_hash, protocol_types::{constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, hash::poseidon2_hash}, - note::{note_getter::view_notes, note_getter_options::SortOrder}, - keys::getters::get_npk_m_h, + note::{note_getter::view_notes, note_getter_options::SortOrder}, keys::getters::get_npk_m_h }; use crate::types::token_note::{TokenNote, OwnedNote}; diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr index 5e64fcfdac3..917d98136f0 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr @@ -2,7 +2,10 @@ use dep::aztec::{ prelude::{AztecAddress, NoteHeader, NoteInterface, PrivateContext}, protocol_types::constants::GENERATOR_INDEX__NOTE_NULLIFIER, note::utils::compute_note_hash_for_consumption, hash::poseidon2_hash, - oracle::{unsafe_rand::unsafe_rand, nullifier_key::get_nsk_app_with_npk_m_h, get_public_key::get_public_key_with_npk_m_h} + oracle::{ + unsafe_rand::unsafe_rand, nullifier_key::get_nsk_app_with_npk_m_h, + get_public_key::get_public_key_with_npk_m_h +} }; trait OwnedNote { From 29f422572a7ca55cbdf5e1b1107bd82603d14419 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Wed, 8 May 2024 19:26:54 +0000 Subject: [PATCH 56/93] nargo fmt --- .../aztec-nr/aztec/src/context/private_context.nr | 15 ++++++++------- noir-projects/aztec-nr/aztec/src/keys/getters.nr | 5 ++++- .../aztec-nr/aztec/src/oracle/nullifier_key.nr | 2 +- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index 167786cb70b..7f31e14f856 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -3,14 +3,14 @@ use crate::{ messaging::process_l1_to_l2_message, hash::{hash_args_array, ArgsHasher, compute_encrypted_log_hash, compute_unencrypted_log_hash}, oracle::{ - arguments, returns, call_private_function::call_private_function_internal, - header::get_header_at, + arguments, returns, call_private_function::call_private_function_internal, header::get_header_at, logs::emit_encrypted_log, logs_traits::{LensForEncryptedLog, ToBytesForUnencryptedLog}, nullifier_key::{get_nullifier_keys, get_nullifier_keys_with_npk_m_h, NullifierKeys}, enqueue_public_function_call::{ enqueue_public_function_call_internal, set_public_teardown_function_call_internal, - parse_public_call_stack_item_from_oracle}, - }, + parse_public_call_stack_item_from_oracle +} +} }; use dep::protocol_types::{ abis::{ @@ -31,8 +31,7 @@ use dep::protocol_types::{ contrakt::{storage_read::StorageRead, storage_update_request::StorageUpdateRequest}, grumpkin_private_key::GrumpkinPrivateKey, grumpkin_point::GrumpkinPoint, header::Header, messaging::l2_to_l1_message::L2ToL1Message, utils::reader::Reader, - traits::{is_empty, Deserialize, Empty}, - hash::poseidon2_hash + traits::{is_empty, Deserialize, Empty}, hash::poseidon2_hash }; // When finished, one can call .finish() to convert back to the abi @@ -241,7 +240,9 @@ impl PrivateContext { }; // We have to check if the key that was requested or cached corresponds to the one we request for - assert_eq(poseidon2_hash(keys.master_nullifier_public_key.serialize()), master_public_nullifying_key_hash); + assert_eq( + poseidon2_hash(keys.master_nullifier_public_key.serialize()), master_public_nullifying_key_hash + ); keys.app_nullifier_secret_key } diff --git a/noir-projects/aztec-nr/aztec/src/keys/getters.nr b/noir-projects/aztec-nr/aztec/src/keys/getters.nr index 5371272bada..142dd835eeb 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/getters.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/getters.nr @@ -1,4 +1,7 @@ -use dep::protocol_types::{address::AztecAddress, constants::CANONICAL_KEY_REGISTRY_ADDRESS, grumpkin_point::GrumpkinPoint, hash::poseidon2_hash}; +use dep::protocol_types::{ + address::AztecAddress, constants::CANONICAL_KEY_REGISTRY_ADDRESS, grumpkin_point::GrumpkinPoint, + hash::poseidon2_hash +}; use crate::{ context::PrivateContext, oracle::keys::get_public_keys_and_partial_address, state_vars::{ diff --git a/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr b/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr index 6ecd924d9ad..84f9be06612 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr @@ -37,7 +37,7 @@ unconstrained fn get_nullifier_keys_with_npk_m_h_internal(master_nullifier_publi NullifierKeys { account: AztecAddress::zero(), master_nullifier_public_key: GrumpkinPoint { x: result[0], y: result[1] }, - app_nullifier_secret_key: result[2], + app_nullifier_secret_key: result[2] } } From 05f8fefeb736e9b8e1e9e66358ccecefa290bf04 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Wed, 8 May 2024 22:09:25 +0000 Subject: [PATCH 57/93] Fix --- .../pxe/src/simulator_oracle/index.ts | 19 ++++++++++++------- .../simulator/src/acvm/oracle/typed_oracle.ts | 5 +++-- .../simulator/src/client/db_oracle.ts | 6 +++--- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index 328e40a835e..6a53667bd7a 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -15,7 +15,7 @@ import { type FunctionSelector, type Header, type L1_TO_L2_MSG_TREE_HEIGHT, - type Point, + type PublicKeys, } from '@aztec/circuits.js'; import { computeL1ToL2MessageNullifier } from '@aztec/circuits.js/hash'; import { type FunctionArtifact, getFunctionArtifact } from '@aztec/foundation/abi'; @@ -98,13 +98,18 @@ export class SimulatorOracle implements DBOracle { } // TODO: #5834 - async getPublicKeysForAddress(address: AztecAddress): Promise { - const nullifierPublicKey = await this.keyStore.getMasterNullifierPublicKey(address); - const incomingViewingPublicKey = await this.keyStore.getMasterIncomingViewingPublicKey(address); - const outgoingViewingPublicKey = await this.keyStore.getMasterOutgoingViewingPublicKey(address); - const taggingPublicKey = await this.keyStore.getMasterTaggingPublicKey(address); + async getPublicKeysForAddress(address: AztecAddress): Promise { + const masterNullifierPublicKey = await this.keyStore.getMasterNullifierPublicKey(address); + const masterIncomingViewingPublicKey = await this.keyStore.getMasterIncomingViewingPublicKey(address); + const masterOutgoingViewingPublicKey = await this.keyStore.getMasterOutgoingViewingPublicKey(address); + const masterTaggingPublicKey = await this.keyStore.getMasterTaggingPublicKey(address); - return [nullifierPublicKey, incomingViewingPublicKey, outgoingViewingPublicKey, taggingPublicKey]; + return { + masterNullifierPublicKey, + masterIncomingViewingPublicKey, + masterOutgoingViewingPublicKey, + masterTaggingPublicKey, + }; } async getNotes(contractAddress: AztecAddress, storageSlot: Fr, status: NoteStatus) { diff --git a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts index 5ea9023698f..0f78e67550f 100644 --- a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts @@ -14,10 +14,11 @@ import { type L1_TO_L2_MSG_TREE_HEIGHT, type PrivateCallStackItem, type PublicCallRequest, + type PublicKeys, } from '@aztec/circuits.js'; import { type FunctionSelector } from '@aztec/foundation/abi'; import { type AztecAddress } from '@aztec/foundation/aztec-address'; -import { Fr, type Point } from '@aztec/foundation/fields'; +import { Fr } from '@aztec/foundation/fields'; import { type ContractInstance } from '@aztec/types/contracts'; /** Nullifier keys which both correspond to the same master nullifier secret key. */ @@ -148,7 +149,7 @@ export abstract class TypedOracle { throw new OracleMethodNotAvailableError('popCapsule'); } - getPublicKeysForAddress(_address: AztecAddress): Promise { + getPublicKeysForAddress(_address: AztecAddress): Promise { throw new OracleMethodNotAvailableError('getPublicKeysForAddress'); } diff --git a/yarn-project/simulator/src/client/db_oracle.ts b/yarn-project/simulator/src/client/db_oracle.ts index b517a53c9fe..28ff000f85a 100644 --- a/yarn-project/simulator/src/client/db_oracle.ts +++ b/yarn-project/simulator/src/client/db_oracle.ts @@ -5,10 +5,10 @@ import { type NullifierMembershipWitness, type PublicDataWitness, } from '@aztec/circuit-types'; -import { type CompleteAddress, type Header } from '@aztec/circuits.js'; +import { type CompleteAddress, type Header, type PublicKeys } from '@aztec/circuits.js'; import { type FunctionArtifact, type FunctionSelector } from '@aztec/foundation/abi'; import { type AztecAddress } from '@aztec/foundation/aztec-address'; -import { type Fr, type Point } from '@aztec/foundation/fields'; +import { type Fr } from '@aztec/foundation/fields'; import { type ContractInstance } from '@aztec/types/contracts'; import { type NoteData, type NullifierKeys } from '../acvm/index.js'; @@ -77,7 +77,7 @@ export interface DBOracle extends CommitmentsDB { * @returns The public keys for a specific address * TODO(#5834): Replace with `getCompleteAddress`. */ - getPublicKeysForAddress(address: AztecAddress): Promise; + getPublicKeysForAddress(address: AztecAddress): Promise; /** * Retrieve nullifier keys associated with a specific account and app/contract address. From f8f27a74a799945c257d18dfe4831c21cdd5bf7a Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Wed, 8 May 2024 22:35:42 +0000 Subject: [PATCH 58/93] fix --- .../simulator/src/acvm/oracle/oracle.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index 02f696f1b77..66f25b06e70 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -1,5 +1,5 @@ import { MerkleTreeId, UnencryptedL2Log } from '@aztec/circuit-types'; -import { type PartialAddress, acvmFieldMessageToString, oracleDebugCallToFormattedStr } from '@aztec/circuits.js'; +import { type PartialAddress, acvmFieldMessageToString, oracleDebugCallToFormattedStr, PublicKeys } from '@aztec/circuits.js'; import { EventSelector, FunctionSelector } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr, Point } from '@aztec/foundation/fields'; @@ -192,7 +192,7 @@ export class Oracle { } async getPublicKeysAndPartialAddress([address]: ACVMField[]): Promise { - let publicKeys: Point[] | undefined; + let publicKeys: PublicKeys; let partialAddress: PartialAddress; // TODO #5834: This should be reworked to return the public keys as well @@ -205,10 +205,20 @@ export class Oracle { try { publicKeys = await this.typedOracle.getPublicKeysForAddress(AztecAddress.fromField(fromACVMField(address))); } catch (err) { - publicKeys = Array(4).fill(Point.ZERO); + publicKeys = { + masterNullifierPublicKey: Point.ZERO, + masterIncomingViewingPublicKey: Point.ZERO, + masterOutgoingViewingPublicKey: Point.ZERO, + masterTaggingPublicKey: Point.ZERO, + }; } - const acvmPublicKeys = publicKeys.flatMap(key => key.toFields()); + const acvmPublicKeys = [ + publicKeys.masterNullifierPublicKey.toFields(), + publicKeys.masterIncomingViewingPublicKey.toFields(), + publicKeys.masterOutgoingViewingPublicKey.toFields(), + publicKeys.masterTaggingPublicKey.toFields(), + ].flat(); return [...acvmPublicKeys, partialAddress].map(toACVMField); } From ded1ee3957bd26b10670f38a325bd80453858a5e Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Wed, 8 May 2024 22:54:45 +0000 Subject: [PATCH 59/93] format --- yarn-project/simulator/src/acvm/oracle/oracle.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index 66f25b06e70..a41d4fd5274 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -1,5 +1,10 @@ import { MerkleTreeId, UnencryptedL2Log } from '@aztec/circuit-types'; -import { type PartialAddress, acvmFieldMessageToString, oracleDebugCallToFormattedStr, PublicKeys } from '@aztec/circuits.js'; +import { + type PartialAddress, + type PublicKeys, + acvmFieldMessageToString, + oracleDebugCallToFormattedStr, +} from '@aztec/circuits.js'; import { EventSelector, FunctionSelector } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr, Point } from '@aztec/foundation/fields'; From 2f76913fb88921bdcda74556e1053fb577a36cd3 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Thu, 9 May 2024 12:52:05 +0000 Subject: [PATCH 60/93] migration notes --- docs/docs/misc/migration_notes.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/docs/misc/migration_notes.md b/docs/docs/misc/migration_notes.md index c792470b0b5..0ca193b2299 100644 --- a/docs/docs/misc/migration_notes.md +++ b/docs/docs/misc/migration_notes.md @@ -6,6 +6,22 @@ keywords: [sandbox, cli, aztec, notes, migration, updating, upgrading] Aztec is in full-speed development. Literally every version breaks compatibility with the previous ones. This page attempts to target errors and difficulties you might encounter when upgrading, and how to resolve them. +## TBD + +### [Aztec.nr] Keys: Token note now stores an owner master nullifying public key hash instead of an owner address. + +i.e. + +struct TokenNote { + ```diff + - owner: AztecAddress, + + owner_npk_m_h: Field, + ``` + randomness: Field, +} + +Computing the nullifier similarly changes to use this master nullifying public key hash. + ## 0.38.0 ### [Aztec.nr] Emmiting encrypted logs From 1ce4d637b7190873778a64db7e0c5a9499e3dcd8 Mon Sep 17 00:00:00 2001 From: esau <152162806+sklppy88@users.noreply.github.com> Date: Thu, 9 May 2024 08:38:32 -0500 Subject: [PATCH 61/93] Update migration_notes.md --- docs/docs/misc/migration_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/docs/misc/migration_notes.md b/docs/docs/misc/migration_notes.md index 0ca193b2299..fc45a8fd1c8 100644 --- a/docs/docs/misc/migration_notes.md +++ b/docs/docs/misc/migration_notes.md @@ -13,6 +13,7 @@ Aztec is in full-speed development. Literally every version breaks compatibility i.e. struct TokenNote { + amount: U128, ```diff - owner: AztecAddress, + owner_npk_m_h: Field, From 113b1e9002f6361bde22653cff3ebf096a607098 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Thu, 9 May 2024 21:15:50 +0000 Subject: [PATCH 62/93] fmt --- yarn-project/pxe/src/pxe_service/pxe_service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index 9c8c24b438d..60b803e153f 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -30,7 +30,7 @@ import { MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, type PartialAddress, type PrivateKernelTailCircuitPublicInputs, - PublicCallRequest, + type PublicCallRequest, type PublicKeys, computeContractClassId, getContractClassFromArtifact, From e9f232619d5afb6833d48c828d4b53131208cb60 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 10 May 2024 18:09:35 +0000 Subject: [PATCH 63/93] Adapting --- docs/docs/misc/migration_notes.md | 2 +- .../aztec/src/context/private_context.nr | 2 +- .../aztec-nr/aztec/src/keys/getters.nr | 12 +++++--- .../aztec/src/oracle/get_public_key.nr | 26 ++++------------- .../aztec-nr/aztec/src/oracle/keys.nr | 19 ++++++++++++ .../aztec/src/oracle/nullifier_key.nr | 14 ++++----- .../token_contract/src/types/balances_map.nr | 6 ++-- .../token_contract/src/types/token_note.nr | 26 ++++++++--------- .../aztec.js/src/wallet/base_wallet.ts | 3 -- .../circuit-types/src/interfaces/pxe.ts | 10 ------- .../end-to-end/src/e2e_2_pxes.test.ts | 29 +++++-------------- .../pxe/src/pxe_service/pxe_service.ts | 14 --------- .../simulator/src/acvm/oracle/oracle.ts | 29 ++++++++++++++----- 13 files changed, 84 insertions(+), 108 deletions(-) diff --git a/docs/docs/misc/migration_notes.md b/docs/docs/misc/migration_notes.md index d7046b8e3af..7bd56836bfd 100644 --- a/docs/docs/misc/migration_notes.md +++ b/docs/docs/misc/migration_notes.md @@ -16,7 +16,7 @@ struct TokenNote { amount: U128, ```diff - owner: AztecAddress, - + owner_npk_m_h: Field, + + npk_m_hash: Field, ``` randomness: Field, } diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index a6362b4019e..fbf2ac6dfab 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -222,7 +222,7 @@ impl PrivateContext { } // TODO: (#6176) Replace request_app_nullifier_secret_key above with this once we no longer get app nullifier secret key with address - pub fn request_nsk_app_with_npk_m_h(&mut self, master_public_nullifying_key_hash: Field) -> Field { + pub fn request_nsk_app_with_npk_m_hash(&mut self, master_public_nullifying_key_hash: Field) -> Field { let keys = if self.nullifier_key.is_none() { let keys = get_nullifier_keys_with_npk_m_h(master_public_nullifying_key_hash); let request = NullifierKeyValidationRequest { diff --git a/noir-projects/aztec-nr/aztec/src/keys/getters.nr b/noir-projects/aztec-nr/aztec/src/keys/getters.nr index cd027771574..a08b9069b53 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/getters.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/getters.nr @@ -1,11 +1,10 @@ use dep::protocol_types::{ - address::AztecAddress, constants::CANONICAL_KEY_REGISTRY_ADDRESS, grumpkin_point::GrumpkinPoint, - hash::poseidon2_hash address::{AztecAddress, PublicKeysHash}, constants::CANONICAL_KEY_REGISTRY_ADDRESS, grumpkin_point::GrumpkinPoint, hash::poseidon2_hash }; use crate::{ - context::PrivateContext, oracle::keys::get_public_keys_and_partial_address, + context::PrivateContext, + oracle::keys::{get_public_keys_and_partial_address, get_public_keys_and_partial_address_with_npk_m_hash}, state_vars::{ map::derive_storage_slot_in_map, shared_mutable::shared_mutable_private_getter::SharedMutablePrivateGetter @@ -27,7 +26,7 @@ pub fn get_npk_m(context: &mut PrivateContext, address: AztecAddress) -> Grumpki get_master_key(context, address, NULLIFIER_INDEX) } -pub fn get_npk_m_h(context: &mut PrivateContext, address: AztecAddress) -> Field { +pub fn get_npk_m_hash(context: &mut PrivateContext, address: AztecAddress) -> Field { poseidon2_hash(get_master_key(context, address, NULLIFIER_INDEX).serialize()) } @@ -101,3 +100,8 @@ fn fetch_and_constrain_keys(address: AztecAddress) -> [GrumpkinPoint; 4] { [npk_m, ivpk_m, ovpk_m, tpk_m] } + +pub fn get_ivpk_m_with_npk_m_hash(npk_m_hash: Field) -> GrumpkinPoint { + let result = get_public_keys_and_partial_address_with_npk_m_hash(npk_m_hash); + result.0[1] +} diff --git a/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr b/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr index 1028114dc80..c1cf3665a83 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr @@ -1,5 +1,5 @@ -use dep::protocol_types::{address::AztecAddress, grumpkin_point::GrumpkinPoint}; -use crate::oracle::keys::get_public_keys_and_partial_address; +use dep::protocol_types::{address::{AztecAddress, PartialAddress}, grumpkin_point::GrumpkinPoint}; +use crate::oracle::keys::{get_public_keys_and_partial_address, get_public_keys_and_partial_address_with_npk_m_hash}; // To be nuked in my next PR: https://github.com/AztecProtocol/aztec-packages/pull/6219 pub fn get_public_key(address: AztecAddress) -> GrumpkinPoint { @@ -8,23 +8,7 @@ pub fn get_public_key(address: AztecAddress) -> GrumpkinPoint { } // TODO(#5901 -> #5834): This should be refactored, would be most effective to do it after new encrypted log scheme, as well as key store pxe separation. -#[oracle(getPublicKeyAndPartialAddressWithNpkMH)] -fn get_public_key_and_partial_address_with_npk_m_h_oracle(master_nullifier_public_key_hash: Field) -> [Field; 3] {} - -unconstrained fn get_public_key_and_partial_address_with_npk_m_h_internal(master_nullifier_public_key_hash: Field) -> [Field; 3] { - get_public_key_and_partial_address_with_npk_m_h_oracle(master_nullifier_public_key_hash) -} - -// TODO (#5901): This is used when we emit encrypted logs and will be changed. -// TODO (#6178): This function should not be contraining things here. -pub fn get_public_key_with_npk_m_h(master_nullifier_public_key_hash: Field) -> GrumpkinPoint { - let result = get_public_key_and_partial_address_with_npk_m_h_internal(master_nullifier_public_key_hash); - let pub_key = GrumpkinPoint::new(result[0], result[1]); - let partial_address = PartialAddress::from_field(result[2]); - - // TODO(#5830): disabling the following constraint until we update the oracle according to the new key scheme - // let calculated_address = AztecAddress::compute(PublicKeysHash::compute(pub_key), partial_address); - // assert(calculated_address.eq(address)); - - pub_key +pub fn get_public_key_with_npk_m_hash(npk_m_hash: Field) -> GrumpkinPoint { + let result = get_public_keys_and_partial_address_with_npk_m_hash(npk_m_hash); + result.0[1] } diff --git a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr index a985e385e81..3aa89274571 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr @@ -20,3 +20,22 @@ fn get_public_keys_and_partial_address(address: AztecAddress) -> ([GrumpkinPoint ([nullifier_pub_key, incoming_pub_key, outgoing_pub_key, tagging_pub_key], partial_address) } + +#[oracle(getPublicKeysAndPartialAddressWithNpkMH)] +fn get_public_keys_and_partial_address_with_npk_m_hash_oracle(_npk_m_hash: Field) -> [Field; 9] {} + +unconstrained fn get_public_keys_and_partial_address_with_npk_m_hash_oracle_wrapper(npk_m_hash: Field) -> [Field; 9] { + get_public_keys_and_partial_address_with_npk_m_hash_oracle(npk_m_hash) +} + +fn get_public_keys_and_partial_address_with_npk_m_hash(npk_m_hash: Field) -> ([GrumpkinPoint; 4], PartialAddress) { + let result = get_public_keys_and_partial_address_with_npk_m_hash_oracle_wrapper(npk_m_hash); + + let nullifier_pub_key = GrumpkinPoint::new(result[0], result[1]); + let incoming_pub_key = GrumpkinPoint::new(result[2], result[3]); + let outgoing_pub_key = GrumpkinPoint::new(result[4], result[5]); + let tagging_pub_key = GrumpkinPoint::new(result[6], result[7]); + let partial_address = PartialAddress::from_field(result[8]); + + ([nullifier_pub_key, incoming_pub_key, outgoing_pub_key, tagging_pub_key], partial_address) +} diff --git a/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr b/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr index 84f9be06612..4a749c033ad 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr @@ -30,10 +30,10 @@ pub fn get_app_nullifier_secret_key(account: AztecAddress) -> Field { // TODO (#6176): Replace get_nullifier_keys above with this once we no longer get nullifier keys with address #[oracle(getNullifierKeysWithNpkMH)] -fn get_nullifier_keys_with_npk_m_h_oracle(_master_nullifier_public_key_hash: Field) -> [Field; 3] {} +fn get_nullifier_keys_with_npk_m_h_oracle(_npk_m_hash: Field) -> [Field; 3] {} -unconstrained fn get_nullifier_keys_with_npk_m_h_internal(master_nullifier_public_key_hash: Field) -> NullifierKeys { - let result = get_nullifier_keys_with_npk_m_h_oracle(master_nullifier_public_key_hash); +unconstrained fn get_nullifier_keys_with_npk_m_h_internal(npk_m_hash: Field) -> NullifierKeys { + let result = get_nullifier_keys_with_npk_m_h_oracle(npk_m_hash); NullifierKeys { account: AztecAddress::zero(), master_nullifier_public_key: GrumpkinPoint { x: result[0], y: result[1] }, @@ -42,11 +42,11 @@ unconstrained fn get_nullifier_keys_with_npk_m_h_internal(master_nullifier_publi } // We get the full struct Nullifier Keys here -pub fn get_nullifier_keys_with_npk_m_h(master_nullifier_public_key_hash: Field) -> NullifierKeys { - get_nullifier_keys_with_npk_m_h_internal(master_nullifier_public_key_hash) +pub fn get_nullifier_keys_with_npk_m_h(npk_m_hash: Field) -> NullifierKeys { + get_nullifier_keys_with_npk_m_h_internal(npk_m_hash) } // We are only getting the app_nullifier_secret_key here -pub fn get_nsk_app_with_npk_m_h(master_nullifier_public_key_hash: Field) -> Field { - get_nullifier_keys_with_npk_m_h_internal(master_nullifier_public_key_hash).app_nullifier_secret_key +pub fn get_nsk_app_with_npk_m_hash(npk_m_hash: Field) -> Field { + get_nullifier_keys_with_npk_m_h_internal(npk_m_hash).app_nullifier_secret_key } diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr index ffe373fc501..6ae314da25c 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr @@ -5,7 +5,7 @@ use dep::aztec::prelude::{ use dep::aztec::{ context::{PublicContext, Context}, hash::pedersen_hash, protocol_types::{constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, hash::poseidon2_hash}, - note::{note_getter::view_notes, note_getter_options::SortOrder}, keys::getters::get_npk_m_h + note::{note_getter::view_notes, note_getter_options::SortOrder}, keys::getters::get_npk_m_hash }; use crate::types::token_note::{TokenNote, OwnedNote}; @@ -61,9 +61,9 @@ impl BalancesMap { addend: U128 ) where T: NoteInterface + OwnedNote { // We fetch the nullifier public key hash in the registry / from our PXE - let owner_npk_m_h = get_npk_m_h(self.map.context.private.unwrap(), owner); + let owner_npk_m_hash = get_npk_m_hash(self.map.context.private.unwrap(), owner); - let mut addend_note = T::new(addend, owner_npk_m_h); + let mut addend_note = T::new(addend, owner_npk_m_hash); // docs:start:insert self.map.at(owner).insert(&mut addend_note, true); diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr index 917d98136f0..ef225dc0378 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr @@ -2,16 +2,14 @@ use dep::aztec::{ prelude::{AztecAddress, NoteHeader, NoteInterface, PrivateContext}, protocol_types::constants::GENERATOR_INDEX__NOTE_NULLIFIER, note::utils::compute_note_hash_for_consumption, hash::poseidon2_hash, - oracle::{ - unsafe_rand::unsafe_rand, nullifier_key::get_nsk_app_with_npk_m_h, - get_public_key::get_public_key_with_npk_m_h -} + keys::getters::get_ivpk_m_with_npk_m_hash, + oracle::{unsafe_rand::unsafe_rand, nullifier_key::get_nsk_app_with_npk_m_hash} }; trait OwnedNote { - fn new(amount: U128, owner_npk_m_h: Field) -> Self; + fn new(amount: U128, owner_npk_m_hash: Field) -> Self; fn get_amount(self) -> U128; - fn get_owner_npk_m_h(self) -> Field; + fn get_owner_npk_m_hash(self) -> Field; } global TOKEN_NOTE_LEN: Field = 3; // 3 plus a header. @@ -22,7 +20,7 @@ struct TokenNote { amount: U128, // The nullifying public key hash of the person who owns the note. // This is used with the app_nullifier_secret_key to ensure that the note can be privately spent. - owner_npk_m_h: Field, + npk_m_hash: Field, // Randomness of the note to hide its contents randomness: Field, } @@ -31,7 +29,7 @@ impl NoteInterface for TokenNote { // docs:start:nullifier fn compute_nullifier(self, context: &mut PrivateContext) -> Field { let note_hash_for_nullify = compute_note_hash_for_consumption(self); - let secret = context.request_nsk_app_with_npk_m_h(self.owner_npk_m_h); + let secret = context.request_nsk_app_with_npk_m_hash(self.npk_m_hash); poseidon2_hash([ note_hash_for_nullify, secret, @@ -42,7 +40,7 @@ impl NoteInterface for TokenNote { fn compute_nullifier_without_context(self) -> Field { let note_hash_for_nullify = compute_note_hash_for_consumption(self); - let secret = get_nsk_app_with_npk_m_h(self.owner_npk_m_h); + let secret = get_nsk_app_with_npk_m_hash(self.npk_m_hash); poseidon2_hash([ note_hash_for_nullify, secret, @@ -55,7 +53,7 @@ impl NoteInterface for TokenNote { // We only bother inserting the note if non-empty to save funds on gas. // TODO: (#5901) This will be changed a lot, as it should use the updated encrypted log format if !(self.amount == U128::from_integer(0)) { - let encryption_pub_key = get_public_key_with_npk_m_h(self.owner_npk_m_h); + let encryption_pub_key = get_ivpk_m_with_npk_m_hash(self.npk_m_hash); context.emit_encrypted_log( (*context).this_address(), slot, @@ -68,10 +66,10 @@ impl NoteInterface for TokenNote { } impl OwnedNote for TokenNote { - fn new(amount: U128, owner_npk_m_h: Field) -> Self { + fn new(amount: U128, owner_npk_m_hash: Field) -> Self { Self { amount, - owner_npk_m_h, + npk_m_hash: owner_npk_m_hash, randomness: unsafe_rand(), header: NoteHeader::empty(), } @@ -81,7 +79,7 @@ impl OwnedNote for TokenNote { self.amount } - fn get_owner_npk_m_h(self) -> Field { - self.owner_npk_m_h + fn get_owner_npk_m_hash(self) -> Field { + self.npk_m_hash } } diff --git a/yarn-project/aztec.js/src/wallet/base_wallet.ts b/yarn-project/aztec.js/src/wallet/base_wallet.ts index a85dfe7ada0..9a2f1aec30f 100644 --- a/yarn-project/aztec.js/src/wallet/base_wallet.ts +++ b/yarn-project/aztec.js/src/wallet/base_wallet.ts @@ -84,9 +84,6 @@ export abstract class BaseWallet implements Wallet { getRegisteredAccount(address: AztecAddress): Promise { return this.pxe.getRegisteredAccount(address); } - getRegisteredAccountPublicKeys(address: AztecAddress): Promise { - return this.pxe.getRegisteredAccountPublicKeys(address); - } getRecipients(): Promise { return this.pxe.getRecipients(); } diff --git a/yarn-project/circuit-types/src/interfaces/pxe.ts b/yarn-project/circuit-types/src/interfaces/pxe.ts index 760580b2ca4..0d26e226e4a 100644 --- a/yarn-project/circuit-types/src/interfaces/pxe.ts +++ b/yarn-project/circuit-types/src/interfaces/pxe.ts @@ -97,16 +97,6 @@ export interface PXE { */ getRegisteredAccount(address: AztecAddress): Promise; - /** - * Retrieves the public keys of the account corresponding to the provided aztec address. - * - * @param address - The address of account. - * @returns The public keys of the requested account if found. - * TODO(#5834): refactor complete address and merge with getRegisteredAccount? - * This will change after the re enabling separation of keystore and pxe. We shouldn't need both this function and the above one - */ - getRegisteredAccountPublicKeys(address: AztecAddress): Promise; - /** * Retrieves the recipients added to this PXE Service. * @returns An array of recipients registered on this PXE Service. diff --git a/yarn-project/end-to-end/src/e2e_2_pxes.test.ts b/yarn-project/end-to-end/src/e2e_2_pxes.test.ts index 79167951f39..6ab0f85dbca 100644 --- a/yarn-project/end-to-end/src/e2e_2_pxes.test.ts +++ b/yarn-project/end-to-end/src/e2e_2_pxes.test.ts @@ -119,14 +119,10 @@ describe('e2e_2_pxes', () => { const tokenInstance = await deployTokenContract(initialBalance, walletA.getAddress(), pxeA); const tokenAddress = tokenInstance.address; - // Get public keys of both accounts - const walletAPublicKeys = await pxeA.getRegisteredAccountPublicKeys(walletA.getAddress()); - const walletBPublicKeys = await pxeB.getRegisteredAccountPublicKeys(walletB.getAddress()); - // Add account B to wallet A - await pxeA.registerRecipient(walletB.getCompleteAddress(), walletBPublicKeys); + await pxeA.registerRecipient(walletB.getCompleteAddress()); // Add account A to wallet B - await pxeB.registerRecipient(walletA.getCompleteAddress(), walletAPublicKeys); + await pxeB.registerRecipient(walletA.getCompleteAddress()); // Add token to PXE B (PXE A already has it because it was deployed through it) await pxeB.registerContract({ @@ -219,14 +215,10 @@ describe('e2e_2_pxes', () => { const tokenInstance = await deployTokenContract(userABalance, walletA.getAddress(), pxeA); const contractWithWalletA = await TokenContract.at(tokenInstance.address, walletA); - // Get public keys of both accounts - const walletAPublicKeys = await pxeA.getRegisteredAccountPublicKeys(walletA.getAddress()); - const walletBPublicKeys = await pxeB.getRegisteredAccountPublicKeys(walletB.getAddress()); - // Add account B to wallet A - await pxeA.registerRecipient(walletB.getCompleteAddress(), walletBPublicKeys); + await pxeA.registerRecipient(walletB.getCompleteAddress()); // Add account A to wallet B - await pxeB.registerRecipient(walletA.getCompleteAddress(), walletAPublicKeys); + await pxeB.registerRecipient(walletA.getCompleteAddress()); // Add token to PXE B (PXE A already has it because it was deployed through it) await pxeB.registerContract({ @@ -276,14 +268,10 @@ describe('e2e_2_pxes', () => { const tokenInstance = await deployTokenContract(initialBalance, walletA.getAddress(), pxeA); const tokenAddress = tokenInstance.address; - // Get public keys of both accounts - const walletAPublicKeys = await pxeA.getRegisteredAccountPublicKeys(walletA.getAddress()); - const walletBPublicKeys = await pxeB.getRegisteredAccountPublicKeys(walletB.getAddress()); - // Add account B to wallet A - await pxeA.registerRecipient(walletB.getCompleteAddress(), walletBPublicKeys); + await pxeA.registerRecipient(walletB.getCompleteAddress()); // Add account A to wallet B - await pxeB.registerRecipient(walletA.getCompleteAddress(), walletAPublicKeys); + await pxeB.registerRecipient(walletA.getCompleteAddress()); // Check initial balances and logs are as expected await expectTokenBalance(walletA, tokenAddress, walletA.getAddress(), initialBalance); @@ -323,11 +311,8 @@ describe('e2e_2_pxes', () => { await sharedAccountOnB.register(); const sharedWalletOnB = await sharedAccountOnB.getWallet(); - // Get the public keys of wallet B - const walletBPublicKeys = await pxeB.getRegisteredAccountPublicKeys(walletB.getAddress()); - // Register wallet B in the pxe of wallet A - await pxeA.registerRecipient(walletB.getCompleteAddress(), walletBPublicKeys); + await pxeA.registerRecipient(walletB.getCompleteAddress()); // deploy the contract on PXE A const tokenInstance = await deployTokenContract(initialBalance, walletA.getAddress(), pxeA); diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index 7244157d4fd..1e2e136a3a4 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -204,20 +204,6 @@ export class PXEService implements PXE { return Promise.resolve(account); } - public async getRegisteredAccountPublicKeys(address: AztecAddress): Promise { - const accounts = await this.keyStore.getAccounts(); - if (!accounts.some(account => account.equals(address))) { - return undefined; - } - - return { - masterNullifierPublicKey: await this.keyStore.getMasterNullifierPublicKey(address), - masterIncomingViewingPublicKey: await this.keyStore.getMasterIncomingViewingPublicKey(address), - masterOutgoingViewingPublicKey: await this.keyStore.getMasterOutgoingViewingPublicKey(address), - masterTaggingPublicKey: await this.keyStore.getMasterTaggingPublicKey(address), - }; - } - public async registerRecipient(recipient: CompleteAddress): Promise { const wasAdded = await this.db.addCompleteAddress(recipient); diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index a66ad99ca7b..e27b63d6c9f 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -64,14 +64,6 @@ export class Oracle { ]; } - // TODO: #5834 Nuke this - async getPublicKeyAndPartialAddressWithNpkMH([masterNullifierPublicKeyHash]: ACVMField[]) { - const { publicKey, partialAddress } = await this.typedOracle.getCompleteAddressWithNpkMH( - fromACVMField(masterNullifierPublicKeyHash), - ); - return [publicKey.x, publicKey.y, partialAddress].map(toACVMField); - } - async getContractInstance([address]: ACVMField[]) { const instance = await this.typedOracle.getContractInstance(AztecAddress.fromField(fromACVMField(address))); @@ -202,6 +194,27 @@ export class Oracle { ].map(toACVMField); } + // TODO: #5834 + async getPublicKeysAndPartialAddressWithNpkMH([masterNullifierPublicKeyHash]: ACVMField[]) { + const parsedNpkMH = fromACVMField(masterNullifierPublicKeyHash); + + const { + masterNullifierPublicKey, + masterIncomingViewingPublicKey, + masterOutgoingViewingPublicKey, + masterTaggingPublicKey, + partialAddress, + } = await this.typedOracle.getCompleteAddressWithNpkMH(parsedNpkMH); + + return [ + ...masterNullifierPublicKey.toFields(), + ...masterIncomingViewingPublicKey.toFields(), + ...masterOutgoingViewingPublicKey.toFields(), + ...masterTaggingPublicKey.toFields(), + partialAddress, + ].map(toACVMField); + } + async getNotes( [storageSlot]: ACVMField[], [numSelects]: ACVMField[], From fe73adba61697c62ec7569cae06b8cf22b66c43c Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 10 May 2024 18:22:15 +0000 Subject: [PATCH 64/93] fix --- .../contracts/token_contract/src/types/token_note.nr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr index 79d93eacbab..1e91e25121c 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr @@ -52,7 +52,7 @@ impl NoteInterface for TokenNote { // We only bother inserting the note if non-empty to save funds on gas. // TODO: (#5901) This will be changed a lot, as it should use the updated encrypted log format if !(self.amount == U128::from_integer(0)) { - let ivpk_m = get_ivpk_m_with_npk_m_hash(context, self.owner); + let ivpk_m = get_ivpk_m_with_npk_m_hash(self.owner); context.emit_encrypted_log( (*context).this_address(), slot, From eb53c4442e049f3ac91757be1ebdb5ab2a27265a Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 10 May 2024 18:26:34 +0000 Subject: [PATCH 65/93] fix --- .../contracts/token_contract/src/types/token_note.nr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr index 1e91e25121c..dc997924faf 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr @@ -52,7 +52,7 @@ impl NoteInterface for TokenNote { // We only bother inserting the note if non-empty to save funds on gas. // TODO: (#5901) This will be changed a lot, as it should use the updated encrypted log format if !(self.amount == U128::from_integer(0)) { - let ivpk_m = get_ivpk_m_with_npk_m_hash(self.owner); + let ivpk_m = get_ivpk_m_with_npk_m_hash(self.npk_m_hash); context.emit_encrypted_log( (*context).this_address(), slot, From b6b6969a26d218a16ecf5f7934f8a681b4411306 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 10 May 2024 18:34:50 +0000 Subject: [PATCH 66/93] Fixes --- yarn-project/aztec.js/src/wallet/base_wallet.ts | 1 - yarn-project/circuit-types/src/interfaces/pxe.ts | 1 - yarn-project/circuits.js/src/types/public_key.ts | 7 ------- yarn-project/pxe/src/pxe_service/pxe_service.ts | 1 - yarn-project/simulator/src/acvm/oracle/typed_oracle.ts | 1 - yarn-project/simulator/src/client/db_oracle.ts | 2 +- 6 files changed, 1 insertion(+), 12 deletions(-) diff --git a/yarn-project/aztec.js/src/wallet/base_wallet.ts b/yarn-project/aztec.js/src/wallet/base_wallet.ts index 9a2f1aec30f..89e99c4d2e4 100644 --- a/yarn-project/aztec.js/src/wallet/base_wallet.ts +++ b/yarn-project/aztec.js/src/wallet/base_wallet.ts @@ -20,7 +20,6 @@ import { type CompleteAddress, type Fr, type PartialAddress, - type PublicKeys, } from '@aztec/circuits.js'; import { type ContractArtifact } from '@aztec/foundation/abi'; import { type ContractClassWithId, type ContractInstanceWithAddress } from '@aztec/types/contracts'; diff --git a/yarn-project/circuit-types/src/interfaces/pxe.ts b/yarn-project/circuit-types/src/interfaces/pxe.ts index 0d26e226e4a..2c6f8010523 100644 --- a/yarn-project/circuit-types/src/interfaces/pxe.ts +++ b/yarn-project/circuit-types/src/interfaces/pxe.ts @@ -3,7 +3,6 @@ import { type CompleteAddress, type Fr, type PartialAddress, - type PublicKeys, } from '@aztec/circuits.js'; import { type ContractArtifact } from '@aztec/foundation/abi'; import { type ContractClassWithId, type ContractInstanceWithAddress } from '@aztec/types/contracts'; diff --git a/yarn-project/circuits.js/src/types/public_key.ts b/yarn-project/circuits.js/src/types/public_key.ts index 817e08f1e51..0109de4c8ea 100644 --- a/yarn-project/circuits.js/src/types/public_key.ts +++ b/yarn-project/circuits.js/src/types/public_key.ts @@ -2,10 +2,3 @@ import { type Point } from '@aztec/foundation/fields'; /** Represents a user public key. */ export type PublicKey = Point; - -export type PublicKeys = { - masterNullifierPublicKey: Point; - masterIncomingViewingPublicKey: Point; - masterOutgoingViewingPublicKey: Point; - masterTaggingPublicKey: Point; -}; diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index 1e2e136a3a4..8769a2d68db 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -31,7 +31,6 @@ import { type PartialAddress, type PrivateKernelTailCircuitPublicInputs, type PublicCallRequest, - type PublicKeys, computeContractClassId, getContractClassFromArtifact, } from '@aztec/circuits.js'; diff --git a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts index 1cb66667b79..208d690909d 100644 --- a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts @@ -14,7 +14,6 @@ import { type L1_TO_L2_MSG_TREE_HEIGHT, type PrivateCallStackItem, type PublicCallRequest, - type PublicKeys, } from '@aztec/circuits.js'; import { type FunctionSelector } from '@aztec/foundation/abi'; import { type AztecAddress } from '@aztec/foundation/aztec-address'; diff --git a/yarn-project/simulator/src/client/db_oracle.ts b/yarn-project/simulator/src/client/db_oracle.ts index 03eabedf1f8..6b55630fc77 100644 --- a/yarn-project/simulator/src/client/db_oracle.ts +++ b/yarn-project/simulator/src/client/db_oracle.ts @@ -5,7 +5,7 @@ import { type NullifierMembershipWitness, type PublicDataWitness, } from '@aztec/circuit-types'; -import { type CompleteAddress, type Header, type PublicKeys } from '@aztec/circuits.js'; +import { type CompleteAddress, type Header } from '@aztec/circuits.js'; import { type FunctionArtifact, type FunctionSelector } from '@aztec/foundation/abi'; import { type AztecAddress } from '@aztec/foundation/aztec-address'; import { type Fr } from '@aztec/foundation/fields'; From 8ecec72be5f78fdc677e9a8af380b81097ce46c2 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 10 May 2024 18:35:18 +0000 Subject: [PATCH 67/93] fix --- docs/docs/misc/migration_notes.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/docs/misc/migration_notes.md b/docs/docs/misc/migration_notes.md index fab1e9d45a1..bc839e42426 100644 --- a/docs/docs/misc/migration_notes.md +++ b/docs/docs/misc/migration_notes.md @@ -29,7 +29,6 @@ Computing the nullifier similarly changes to use this master nullifying public k The type signature for `SharedMutable` changed from `SharedMutable` to `SharedMutable`. The behavior is the same as before, except the delay can now be changed after deployment by calling `schedule_delay_change`. - ### [Aztec.nr] get_public_key oracle replaced with get_ivpk_m When implementing changes according to a [new key scheme](https://yp-aztec.netlify.app/docs/addresses-and-keys/keys) we had to change oracles. From 730c842ef0ff18bddc0cdc24900deb32f6763b51 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 10 May 2024 18:46:42 +0000 Subject: [PATCH 68/93] Changes --- .../pxe/src/simulator_oracle/index.ts | 4 ++-- .../simulator/src/acvm/oracle/oracle.ts | 6 +++--- .../simulator/src/acvm/oracle/typed_oracle.ts | 8 ++++---- .../simulator/src/client/db_oracle.ts | 4 ++-- .../simulator/src/client/simulator.test.ts | 2 +- .../simulator/src/client/view_data_oracle.ts | 19 ++++++++++--------- 6 files changed, 22 insertions(+), 21 deletions(-) diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index bc760337b1f..6cfa3c20492 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -43,7 +43,7 @@ export class SimulatorOracle implements DBOracle { return { masterNullifierPublicKey, appNullifierSecretKey }; } - async getNullifierKeysWithNpkMH( + async getNullifierKeysWithNpkMHash( masterNullifierPublicKeyHash: AztecAddress, contractAddress: AztecAddress, ): Promise { @@ -66,7 +66,7 @@ export class SimulatorOracle implements DBOracle { } // TODO: #5834 - getCompleteAddressWithNpkMH(masterNullifierPublicKeyHash: Fr): Promise { + getCompleteAddressWithNpkMHash(masterNullifierPublicKeyHash: Fr): Promise { const address = this.keyStore.getAccountAddressForMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash); return this.getCompleteAddress(address); } diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index e27b63d6c9f..a5d06e3c9a4 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -53,8 +53,8 @@ export class Oracle { ]; } - async getNullifierKeysWithNpkMH([masterNullifierPublicKeyHash]: ACVMField[]): Promise { - const { masterNullifierPublicKey, appNullifierSecretKey } = await this.typedOracle.getNullifierKeysWithNpkMH( + async getNullifierKeysWithNpkMHash([masterNullifierPublicKeyHash]: ACVMField[]): Promise { + const { masterNullifierPublicKey, appNullifierSecretKey } = await this.typedOracle.getNullifierKeysWithNpkMHash( fromACVMField(masterNullifierPublicKeyHash), ); return [ @@ -204,7 +204,7 @@ export class Oracle { masterOutgoingViewingPublicKey, masterTaggingPublicKey, partialAddress, - } = await this.typedOracle.getCompleteAddressWithNpkMH(parsedNpkMH); + } = await this.typedOracle.getCompleteAddressWithNpkMHash(parsedNpkMH); return [ ...masterNullifierPublicKey.toFields(), diff --git a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts index 208d690909d..01e811c514e 100644 --- a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts @@ -93,8 +93,8 @@ export abstract class TypedOracle { throw new OracleMethodNotAvailableError('getNullifierKeys'); } - getNullifierKeysWithNpkMH(_masterNullifierPublicKeyHash: Fr): Promise { - throw new OracleMethodNotAvailableError('getNullifierKeysWithNpkMH'); + getNullifierKeysWithNpkMHash(_masterNullifierPublicKeyHash: Fr): Promise { + throw new OracleMethodNotAvailableError('getNullifierKeysWithNpkMHash'); } getContractInstance(_address: AztecAddress): Promise { @@ -132,8 +132,8 @@ export abstract class TypedOracle { throw new OracleMethodNotAvailableError('getCompleteAddress'); } - getCompleteAddressWithNpkMH(_masterNullifierPublicKeyHash: Fr): Promise { - throw new OracleMethodNotAvailableError('getCompleteAddressWithNpkMH'); + getCompleteAddressWithNpkMHash(_masterNullifierPublicKeyHash: Fr): Promise { + throw new OracleMethodNotAvailableError('getCompleteAddressWithNpkMHash'); } getAuthWitness(_messageHash: Fr): Promise { diff --git a/yarn-project/simulator/src/client/db_oracle.ts b/yarn-project/simulator/src/client/db_oracle.ts index 6b55630fc77..f8e073d4a77 100644 --- a/yarn-project/simulator/src/client/db_oracle.ts +++ b/yarn-project/simulator/src/client/db_oracle.ts @@ -55,7 +55,7 @@ export interface DBOracle extends CommitmentsDB { * @param masterNullifierPublicKeyHash - Master nullifier public key hash to fetch the complete address for. * @returns A complete address associated with the input master nullifier public key hash. */ - getCompleteAddressWithNpkMH(masterNullifierPublicKeyHash: Fr): Promise; + getCompleteAddressWithNpkMHash(masterNullifierPublicKeyHash: Fr): Promise; /** * Retrieve the auth witness for a given message hash. @@ -89,7 +89,7 @@ export interface DBOracle extends CommitmentsDB { * @returns A Promise that resolves to nullifier keys of a requested account and contract. * @throws An error if the account is not registered in the database. */ - getNullifierKeysWithNpkMH(masterNullifierPublicKeyHash: Fr, contractAddress: AztecAddress): Promise; + getNullifierKeysWithNpkMHash(masterNullifierPublicKeyHash: Fr, contractAddress: AztecAddress): Promise; /** * Retrieves a set of notes stored in the database for a given contract address and storage slot. diff --git a/yarn-project/simulator/src/client/simulator.test.ts b/yarn-project/simulator/src/client/simulator.test.ts index 389c9815f87..eabff3637ae 100644 --- a/yarn-project/simulator/src/client/simulator.test.ts +++ b/yarn-project/simulator/src/client/simulator.test.ts @@ -43,7 +43,7 @@ describe('Simulator', () => { oracle = mock(); node = mock(); - oracle.getNullifierKeysWithNpkMH.mockResolvedValue({ + oracle.getNullifierKeysWithNpkMHash.mockResolvedValue({ masterNullifierPublicKey: ownerMasterNullifierPublicKey, appNullifierSecretKey, }); diff --git a/yarn-project/simulator/src/client/view_data_oracle.ts b/yarn-project/simulator/src/client/view_data_oracle.ts index 5a1fbb7744a..819abd1f7bf 100644 --- a/yarn-project/simulator/src/client/view_data_oracle.ts +++ b/yarn-project/simulator/src/client/view_data_oracle.ts @@ -45,13 +45,13 @@ export class ViewDataOracle extends TypedOracle { } /** - * Retrieve nullifier keys associated with a specific masterNullifierPublicKeyHash and app/contract address. - * @param masterNullifierPublicKeyHash - The master nullifer public key hash. - * @returns A Promise that resolves to nullifier keys of a requested account and contract. - * @throws An error if the account is not registered in the database. + * Retrieve nullifier keys associated with a specific master nullifier public key hash and app/contract address. + * @param npkMHash - The master nullifer public key hash. + * @returns The nullifier keys of an account (specified by a master nullifier public key hash) and contract. + * @throws if the aster nullifier public key hash / account is not registered in the database. */ - public override getNullifierKeysWithNpkMH(masterNullifierPublicKeyHash: Fr): Promise { - return this.db.getNullifierKeysWithNpkMH(masterNullifierPublicKeyHash, this.contractAddress); + public override getNullifierKeysWithNpkMHash(npkMHash: Fr): Promise { + return this.db.getNullifierKeysWithNpkMHash(npkMHash, this.contractAddress); } /** @@ -147,11 +147,12 @@ export class ViewDataOracle extends TypedOracle { /** * Retrieve the complete address associated to a given master nullifier public key hash. - * @param masterNullifierPublicKeyHash - Master nullifier public key hash to fetch the complete address for. + * @param npkMHash - The master nullifer public key hash. * @returns A complete address associated with the input master nullifier public key hash. + * @throws if the aster nullifier public key hash / account is not registered in the database. */ - public override getCompleteAddressWithNpkMH(masterNullifierPublicKeyHash: Fr): Promise { - return this.db.getCompleteAddressWithNpkMH(masterNullifierPublicKeyHash); + public override getCompleteAddressWithNpkMHash(npkMHash: Fr): Promise { + return this.db.getCompleteAddressWithNpkMHash(npkMHash); } /** From 1deda941238a08d7bf62d2fa91d1858e9d3f3480 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 10 May 2024 18:48:44 +0000 Subject: [PATCH 69/93] asfd --- yarn-project/simulator/src/client/view_data_oracle.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn-project/simulator/src/client/view_data_oracle.ts b/yarn-project/simulator/src/client/view_data_oracle.ts index 819abd1f7bf..86ea41af6cb 100644 --- a/yarn-project/simulator/src/client/view_data_oracle.ts +++ b/yarn-project/simulator/src/client/view_data_oracle.ts @@ -148,7 +148,7 @@ export class ViewDataOracle extends TypedOracle { /** * Retrieve the complete address associated to a given master nullifier public key hash. * @param npkMHash - The master nullifer public key hash. - * @returns A complete address associated with the input master nullifier public key hash. + * @returns The complete address associated with the input master nullifier public key hash. * @throws if the aster nullifier public key hash / account is not registered in the database. */ public override getCompleteAddressWithNpkMHash(npkMHash: Fr): Promise { From 851c53ecab16b84c9962a21caa2384d7f7f6aeb1 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 10 May 2024 18:51:42 +0000 Subject: [PATCH 70/93] asdf --- yarn-project/simulator/src/client/db_oracle.ts | 12 ++++++------ .../simulator/src/client/view_data_oracle.ts | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn-project/simulator/src/client/db_oracle.ts b/yarn-project/simulator/src/client/db_oracle.ts index f8e073d4a77..f9f97cc5684 100644 --- a/yarn-project/simulator/src/client/db_oracle.ts +++ b/yarn-project/simulator/src/client/db_oracle.ts @@ -52,8 +52,9 @@ export interface DBOracle extends CommitmentsDB { /** * Retrieve the complete address associated to a given master nullifier public key hash. - * @param masterNullifierPublicKeyHash - Master nullifier public key hash to fetch the complete address for. - * @returns A complete address associated with the input master nullifier public key hash. + * @param npkMHash - The master nullifer public key hash. + * @returns The complete address associated with the input master nullifier public key hash. + * @throws if the master nullifier public key hash / account is not registered in the database. */ getCompleteAddressWithNpkMHash(masterNullifierPublicKeyHash: Fr): Promise; @@ -83,11 +84,10 @@ export interface DBOracle extends CommitmentsDB { /** * Retrieve nullifier keys associated with a specific master nullifier public key hash and app/contract address. - * - * @param masterNullifierPublicKeyHash - The master nullifer public key hash. + * @param npkMHash - The master nullifer public key hash. * @param contractAddress - The contract address. - * @returns A Promise that resolves to nullifier keys of a requested account and contract. - * @throws An error if the account is not registered in the database. + * @returns The nullifier keys of an account (specified by a master nullifier public key hash) and contract. + * @throws if the master nullifier public key hash / account is not registered in the database. */ getNullifierKeysWithNpkMHash(masterNullifierPublicKeyHash: Fr, contractAddress: AztecAddress): Promise; diff --git a/yarn-project/simulator/src/client/view_data_oracle.ts b/yarn-project/simulator/src/client/view_data_oracle.ts index 86ea41af6cb..9e044dc21b7 100644 --- a/yarn-project/simulator/src/client/view_data_oracle.ts +++ b/yarn-project/simulator/src/client/view_data_oracle.ts @@ -48,7 +48,7 @@ export class ViewDataOracle extends TypedOracle { * Retrieve nullifier keys associated with a specific master nullifier public key hash and app/contract address. * @param npkMHash - The master nullifer public key hash. * @returns The nullifier keys of an account (specified by a master nullifier public key hash) and contract. - * @throws if the aster nullifier public key hash / account is not registered in the database. + * @throws if the master nullifier public key hash / account is not registered in the database. */ public override getNullifierKeysWithNpkMHash(npkMHash: Fr): Promise { return this.db.getNullifierKeysWithNpkMHash(npkMHash, this.contractAddress); @@ -149,7 +149,7 @@ export class ViewDataOracle extends TypedOracle { * Retrieve the complete address associated to a given master nullifier public key hash. * @param npkMHash - The master nullifer public key hash. * @returns The complete address associated with the input master nullifier public key hash. - * @throws if the aster nullifier public key hash / account is not registered in the database. + * @throws if the master nullifier public key hash / account is not registered in the database. */ public override getCompleteAddressWithNpkMHash(npkMHash: Fr): Promise { return this.db.getCompleteAddressWithNpkMHash(npkMHash); From 5cee1ce14df0b6bb4127960d085268757a0e0d0e Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 10 May 2024 19:20:37 +0000 Subject: [PATCH 71/93] Fixes --- .../circuit-types/src/interfaces/pxe.ts | 1 - .../circuit-types/src/keys/key_store.ts | 8 ------- yarn-project/key-store/src/test_key_store.ts | 21 +++---------------- .../pxe/src/database/kv_pxe_database.ts | 13 +++++++++++- yarn-project/pxe/src/database/pxe_database.ts | 7 +++++++ .../pxe/src/simulator_oracle/index.ts | 10 ++++++--- 6 files changed, 29 insertions(+), 31 deletions(-) diff --git a/yarn-project/circuit-types/src/interfaces/pxe.ts b/yarn-project/circuit-types/src/interfaces/pxe.ts index 2c6f8010523..218fcada69d 100644 --- a/yarn-project/circuit-types/src/interfaces/pxe.ts +++ b/yarn-project/circuit-types/src/interfaces/pxe.ts @@ -73,7 +73,6 @@ export interface PXE { * in order to be able to encrypt data for this recipient. * * @param recipient - The complete address of the recipient - * @param publicKeys - The public keys of the recipient (see #5834) * @remarks Called recipient because we can only send notes to this account and not receive them via this PXE Service. * This is because we don't have the associated private key and for this reason we can't decrypt * the recipient's notes. We can send notes to this account because we can encrypt them with the recipient's diff --git a/yarn-project/circuit-types/src/keys/key_store.ts b/yarn-project/circuit-types/src/keys/key_store.ts index dc34a788672..176c323f7c9 100644 --- a/yarn-project/circuit-types/src/keys/key_store.ts +++ b/yarn-project/circuit-types/src/keys/key_store.ts @@ -117,12 +117,4 @@ export interface KeyStore { * @returns A Promise that resolves to the public keys hash. */ getPublicKeysHash(account: AztecAddress): Promise; - - /** - * Gets the account address for a given master nullifier public key hash. - * @throws If the master nullifier public key hash does not exist in the key store. - * @param masterNullifierPublicKeyHash - The master nullifier public key hash for which to retrieve the address. - * @returns The address for the account. - */ - getAccountAddressForMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr): AztecAddress; } diff --git a/yarn-project/key-store/src/test_key_store.ts b/yarn-project/key-store/src/test_key_store.ts index 36d727bafa8..0fc60354bc3 100644 --- a/yarn-project/key-store/src/test_key_store.ts +++ b/yarn-project/key-store/src/test_key_store.ts @@ -107,7 +107,7 @@ export class TestKeyStore implements KeyStore { const masterNullifierPublicKeyBuffer = this.#keys.get(`${accountOrMasterNullifierPublicKeyHash.toString()}-npk_m`) ?? this.#keys.get( - `${this.getAccountAddressForMasterNullifierPublicKeyHashInternal( + `${this.#getAccountAddressForMasterNullifierPublicKeyHash( accountOrMasterNullifierPublicKeyHash, )?.toString()}-npk_m`, ); @@ -181,7 +181,7 @@ export class TestKeyStore implements KeyStore { const masterNullifierSecretKeyBuffer = this.#keys.get(`${accountOrMasterNullifierPublicKeyHash.toString()}-nsk_m`) ?? this.#keys.get( - `${this.getAccountAddressForMasterNullifierPublicKeyHashInternal( + `${this.#getAccountAddressForMasterNullifierPublicKeyHash( accountOrMasterNullifierPublicKeyHash, )?.toString()}-nsk_m`, ); @@ -319,22 +319,7 @@ export class TestKeyStore implements KeyStore { return Promise.resolve(Fr.fromBuffer(publicKeysHashBuffer)); } - /** - * Gets the account address for a given master nullifier public key hash. - * @throws If the master nullifier public key hash does not exist in the key store. - * @param masterNullifierPublicKeyHash - The master nullifier public key hash for which to retrieve the address. - * @returns The address for the account. - */ - // TODO(#5834): Re-add separation between recipients and accounts in keystore. Refactor this utilizing getAccounts. - public getAccountAddressForMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr) { - const account = this.getAccountAddressForMasterNullifierPublicKeyHashInternal(masterNullifierPublicKeyHash); - if (!account) { - throw new Error(`Master nullifier public key hash ${masterNullifierPublicKeyHash.toString()} does not exist.`); - } - return account; - } - - getAccountAddressForMasterNullifierPublicKeyHashInternal(masterNullifierPublicKeyHash: Fr): AztecAddress | undefined { + #getAccountAddressForMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash: Fr): AztecAddress | undefined { for (const [key, value] of this.#keys.entries()) { if (key.endsWith('-npk_m')) { const computedMasterNullifierPublicKeyHash = poseidon2Hash(Point.fromBuffer(value).toFields()); diff --git a/yarn-project/pxe/src/database/kv_pxe_database.ts b/yarn-project/pxe/src/database/kv_pxe_database.ts index 7452f98f5b9..1d7a4455c60 100644 --- a/yarn-project/pxe/src/database/kv_pxe_database.ts +++ b/yarn-project/pxe/src/database/kv_pxe_database.ts @@ -389,8 +389,19 @@ export class KVPxeDatabase implements PxeDatabase { return Promise.resolve(this.#getCompleteAddress(address)); } + getCompleteAddressByNpkMHash(npkMHash: Fr): Promise { + const completeAddresses = this.#getCompleteAddresses(); + + const completeAddress = completeAddresses.find((completeAddress) => poseidon2Hash(completeAddress.masterNullifierPublicKey.toFields()).equals(npkMHash)); + return Promise.resolve(completeAddress); + } + + #getCompleteAddresses(): CompleteAddress[] { + return Array.from(this.#addresses).map(v => CompleteAddress.fromBuffer(v)); + } + getCompleteAddresses(): Promise { - return Promise.resolve(Array.from(this.#addresses).map(v => CompleteAddress.fromBuffer(v))); + return Promise.resolve(this.#getCompleteAddresses()); } getSynchedBlockNumberForPublicKey(publicKey: Point): number | undefined { diff --git a/yarn-project/pxe/src/database/pxe_database.ts b/yarn-project/pxe/src/database/pxe_database.ts index b95d5e01d8c..1c18fa5e937 100644 --- a/yarn-project/pxe/src/database/pxe_database.ts +++ b/yarn-project/pxe/src/database/pxe_database.ts @@ -139,6 +139,13 @@ export interface PxeDatabase extends ContractArtifactDatabase, ContractInstanceD */ getCompleteAddress(address: AztecAddress): Promise; + /** + * Retrieves the complete address corresponding to the provided aztec address. + * @param address - The aztec address of the complete address contract. + * @returns A promise that resolves to a CompleteAddress instance if the address is found, or undefined if not found. + */ + getCompleteAddressByNpkMHash(npkMHash: Fr): Promise; + /** * Retrieves the list of complete address added to this database * @returns A promise that resolves to an array of AztecAddress instances. diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index 6cfa3c20492..d4271a88fe0 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -65,10 +65,14 @@ export class SimulatorOracle implements DBOracle { return completeAddress; } - // TODO: #5834 getCompleteAddressWithNpkMHash(masterNullifierPublicKeyHash: Fr): Promise { - const address = this.keyStore.getAccountAddressForMasterNullifierPublicKeyHash(masterNullifierPublicKeyHash); - return this.getCompleteAddress(address); + const completeAddress = this.db.getCompleteAddressByNpkMHash(masterNullifierPublicKeyHash); + if (!completeAddress) { + throw new Error( + `No public key registered for master nullifier public key hash ${masterNullifierPublicKeyHash.toString()}. Register it by calling pxe.registerRecipient(...) or pxe.registerAccount(...).\nSee docs for context: https://docs.aztec.network/developers/debugging/aztecnr-errors#simulation-error-No-public-key-registered-for-address-0x0-Register-it-by-calling-pxeregisterRecipient-or-pxeregisterAccount`, + ); + } + return completeAddress; } async getContractInstance(address: AztecAddress): Promise { From a2eed7cc03a5e5516a41ae151733bf562fa1ed43 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 10 May 2024 19:24:27 +0000 Subject: [PATCH 72/93] fix --- yarn-project/pxe/src/database/kv_pxe_database.ts | 1 + yarn-project/pxe/src/simulator_oracle/index.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/yarn-project/pxe/src/database/kv_pxe_database.ts b/yarn-project/pxe/src/database/kv_pxe_database.ts index 1d7a4455c60..e26d7f4eaba 100644 --- a/yarn-project/pxe/src/database/kv_pxe_database.ts +++ b/yarn-project/pxe/src/database/kv_pxe_database.ts @@ -16,6 +16,7 @@ import { type ContractInstanceWithAddress, SerializableContractInstance } from ' import { DeferredNoteDao } from './deferred_note_dao.js'; import { NoteDao } from './note_dao.js'; import { type PxeDatabase } from './pxe_database.js'; +import { poseidon2Hash } from '@aztec/foundation/crypto'; /** * A PXE database backed by LMDB. diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index d4271a88fe0..5da3b4c5b86 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -65,8 +65,8 @@ export class SimulatorOracle implements DBOracle { return completeAddress; } - getCompleteAddressWithNpkMHash(masterNullifierPublicKeyHash: Fr): Promise { - const completeAddress = this.db.getCompleteAddressByNpkMHash(masterNullifierPublicKeyHash); + async getCompleteAddressWithNpkMHash(masterNullifierPublicKeyHash: Fr): Promise { + const completeAddress = await this.db.getCompleteAddressByNpkMHash(masterNullifierPublicKeyHash); if (!completeAddress) { throw new Error( `No public key registered for master nullifier public key hash ${masterNullifierPublicKeyHash.toString()}. Register it by calling pxe.registerRecipient(...) or pxe.registerAccount(...).\nSee docs for context: https://docs.aztec.network/developers/debugging/aztecnr-errors#simulation-error-No-public-key-registered-for-address-0x0-Register-it-by-calling-pxeregisterRecipient-or-pxeregisterAccount`, From 1d52a382848419f4829ffa566caa2d717333ed04 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 10 May 2024 19:27:15 +0000 Subject: [PATCH 73/93] format --- yarn-project/aztec.js/src/wallet/base_wallet.ts | 7 +------ yarn-project/circuit-types/src/interfaces/pxe.ts | 7 +------ yarn-project/pxe/src/database/kv_pxe_database.ts | 6 ++++-- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/yarn-project/aztec.js/src/wallet/base_wallet.ts b/yarn-project/aztec.js/src/wallet/base_wallet.ts index 89e99c4d2e4..200ad930dee 100644 --- a/yarn-project/aztec.js/src/wallet/base_wallet.ts +++ b/yarn-project/aztec.js/src/wallet/base_wallet.ts @@ -15,12 +15,7 @@ import { type TxHash, type TxReceipt, } from '@aztec/circuit-types'; -import { - type AztecAddress, - type CompleteAddress, - type Fr, - type PartialAddress, -} from '@aztec/circuits.js'; +import { type AztecAddress, type CompleteAddress, type Fr, type PartialAddress } from '@aztec/circuits.js'; import { type ContractArtifact } from '@aztec/foundation/abi'; import { type ContractClassWithId, type ContractInstanceWithAddress } from '@aztec/types/contracts'; import { type NodeInfo } from '@aztec/types/interfaces'; diff --git a/yarn-project/circuit-types/src/interfaces/pxe.ts b/yarn-project/circuit-types/src/interfaces/pxe.ts index 218fcada69d..9e01820e4f7 100644 --- a/yarn-project/circuit-types/src/interfaces/pxe.ts +++ b/yarn-project/circuit-types/src/interfaces/pxe.ts @@ -1,9 +1,4 @@ -import { - type AztecAddress, - type CompleteAddress, - type Fr, - type PartialAddress, -} from '@aztec/circuits.js'; +import { type AztecAddress, type CompleteAddress, type Fr, type PartialAddress } from '@aztec/circuits.js'; import { type ContractArtifact } from '@aztec/foundation/abi'; import { type ContractClassWithId, type ContractInstanceWithAddress } from '@aztec/types/contracts'; import { type NodeInfo } from '@aztec/types/interfaces'; diff --git a/yarn-project/pxe/src/database/kv_pxe_database.ts b/yarn-project/pxe/src/database/kv_pxe_database.ts index e26d7f4eaba..4b14070ea55 100644 --- a/yarn-project/pxe/src/database/kv_pxe_database.ts +++ b/yarn-project/pxe/src/database/kv_pxe_database.ts @@ -2,6 +2,7 @@ import { MerkleTreeId, type NoteFilter, NoteStatus, type PublicKey } from '@azte import { AztecAddress, CompleteAddress, Header } from '@aztec/circuits.js'; import { type ContractArtifact } from '@aztec/foundation/abi'; import { toBufferBE } from '@aztec/foundation/bigint-buffer'; +import { poseidon2Hash } from '@aztec/foundation/crypto'; import { Fr, type Point } from '@aztec/foundation/fields'; import { type AztecArray, @@ -16,7 +17,6 @@ import { type ContractInstanceWithAddress, SerializableContractInstance } from ' import { DeferredNoteDao } from './deferred_note_dao.js'; import { NoteDao } from './note_dao.js'; import { type PxeDatabase } from './pxe_database.js'; -import { poseidon2Hash } from '@aztec/foundation/crypto'; /** * A PXE database backed by LMDB. @@ -393,7 +393,9 @@ export class KVPxeDatabase implements PxeDatabase { getCompleteAddressByNpkMHash(npkMHash: Fr): Promise { const completeAddresses = this.#getCompleteAddresses(); - const completeAddress = completeAddresses.find((completeAddress) => poseidon2Hash(completeAddress.masterNullifierPublicKey.toFields()).equals(npkMHash)); + const completeAddress = completeAddresses.find(completeAddress => + poseidon2Hash(completeAddress.masterNullifierPublicKey.toFields()).equals(npkMHash), + ); return Promise.resolve(completeAddress); } From 679891756b347c20390b6652314a3211598ed773 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 10 May 2024 19:34:13 +0000 Subject: [PATCH 74/93] fix --- yarn-project/pxe/src/database/pxe_database.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yarn-project/pxe/src/database/pxe_database.ts b/yarn-project/pxe/src/database/pxe_database.ts index 1c18fa5e937..8868ef37cd3 100644 --- a/yarn-project/pxe/src/database/pxe_database.ts +++ b/yarn-project/pxe/src/database/pxe_database.ts @@ -140,8 +140,8 @@ export interface PxeDatabase extends ContractArtifactDatabase, ContractInstanceD getCompleteAddress(address: AztecAddress): Promise; /** - * Retrieves the complete address corresponding to the provided aztec address. - * @param address - The aztec address of the complete address contract. + * Retrieves the complete address corresponding to the provided master nullifier public key hash. + * @param npkMHash - The master nullifier public key hash of the account. * @returns A promise that resolves to a CompleteAddress instance if the address is found, or undefined if not found. */ getCompleteAddressByNpkMHash(npkMHash: Fr): Promise; From 0a523d4ae358d0986fb530dcc4615f166877a321 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 10 May 2024 19:40:19 +0000 Subject: [PATCH 75/93] fix --- yarn-project/simulator/src/acvm/oracle/oracle.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index a5d06e3c9a4..a5d57529511 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -194,7 +194,6 @@ export class Oracle { ].map(toACVMField); } - // TODO: #5834 async getPublicKeysAndPartialAddressWithNpkMH([masterNullifierPublicKeyHash]: ACVMField[]) { const parsedNpkMH = fromACVMField(masterNullifierPublicKeyHash); From 06c4cc2d9969869fbabb173d1228b0ea67604114 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 10 May 2024 19:41:32 +0000 Subject: [PATCH 76/93] fix --- noir-projects/aztec-nr/aztec/src/context/private_context.nr | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index dc4d31aa48e..8627d4bd4e4 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -222,9 +222,9 @@ impl PrivateContext { } // TODO: (#6176) Replace request_app_nullifier_secret_key above with this once we no longer get app nullifier secret key with address - pub fn request_nsk_app_with_npk_m_hash(&mut self, master_public_nullifying_key_hash: Field) -> Field { + pub fn request_nsk_app_with_npk_m_hash(&mut self, npk_m_hash: Field) -> Field { let keys = if self.nullifier_key.is_none() { - let keys = get_nullifier_keys_with_npk_m_h(master_public_nullifying_key_hash); + let keys = get_nullifier_keys_with_npk_m_h(npk_m_hash); let request = NullifierKeyValidationRequest { master_nullifier_public_key: keys.master_nullifier_public_key, app_nullifier_secret_key: keys.app_nullifier_secret_key @@ -241,7 +241,7 @@ impl PrivateContext { // We have to check if the key that was requested or cached corresponds to the one we request for assert_eq( - poseidon2_hash(keys.master_nullifier_public_key.serialize()), master_public_nullifying_key_hash + poseidon2_hash(keys.master_nullifier_public_key.serialize()), npk_m_hash ); keys.app_nullifier_secret_key } From a765ec72d681aca571b64b3c546db016221e734f Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 10 May 2024 19:43:40 +0000 Subject: [PATCH 77/93] asdf --- noir-projects/aztec-nr/aztec/src/oracle/keys.nr | 2 +- yarn-project/simulator/src/acvm/oracle/oracle.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr index 68c302d86b0..ad092525287 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr @@ -19,7 +19,7 @@ fn get_public_keys_and_partial_address(address: AztecAddress) -> ([GrumpkinPoint ([nullifier_pub_key, incoming_pub_key, outgoing_pub_key, tagging_pub_key], partial_address) } -#[oracle(getPublicKeysAndPartialAddressWithNpkMH)] +#[oracle(getPublicKeysAndPartialAddressWithNpkMHash)] fn get_public_keys_and_partial_address_with_npk_m_hash_oracle(_npk_m_hash: Field) -> [Field; 9] {} unconstrained fn get_public_keys_and_partial_address_with_npk_m_hash_oracle_wrapper(npk_m_hash: Field) -> [Field; 9] { diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index a5d57529511..eeb4c7c3cc2 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -194,7 +194,7 @@ export class Oracle { ].map(toACVMField); } - async getPublicKeysAndPartialAddressWithNpkMH([masterNullifierPublicKeyHash]: ACVMField[]) { + async getPublicKeysAndPartialAddressWithNpkMHash([masterNullifierPublicKeyHash]: ACVMField[]) { const parsedNpkMH = fromACVMField(masterNullifierPublicKeyHash); const { From 5c634807e530ddb3a57e92f8707fc1368b4b171d Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 10 May 2024 19:46:29 +0000 Subject: [PATCH 78/93] fix --- .../aztec-nr/aztec/src/context/private_context.nr | 4 ++-- .../aztec-nr/aztec/src/oracle/nullifier_key.nr | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index 8627d4bd4e4..ecf11bdc305 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -5,7 +5,7 @@ use crate::{ oracle::{ arguments, returns, call_private_function::call_private_function_internal, header::get_header_at, logs::emit_encrypted_log, logs_traits::{LensForEncryptedLog, ToBytesForUnencryptedLog}, - nullifier_key::{get_nullifier_keys, get_nullifier_keys_with_npk_m_h, NullifierKeys}, + nullifier_key::{get_nullifier_keys, get_nullifier_keys_with_npk_m_hash, NullifierKeys}, enqueue_public_function_call::{ enqueue_public_function_call_internal, set_public_teardown_function_call_internal, parse_public_call_stack_item_from_oracle @@ -224,7 +224,7 @@ impl PrivateContext { // TODO: (#6176) Replace request_app_nullifier_secret_key above with this once we no longer get app nullifier secret key with address pub fn request_nsk_app_with_npk_m_hash(&mut self, npk_m_hash: Field) -> Field { let keys = if self.nullifier_key.is_none() { - let keys = get_nullifier_keys_with_npk_m_h(npk_m_hash); + let keys = get_nullifier_keys_with_npk_m_hash(npk_m_hash); let request = NullifierKeyValidationRequest { master_nullifier_public_key: keys.master_nullifier_public_key, app_nullifier_secret_key: keys.app_nullifier_secret_key diff --git a/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr b/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr index 4a749c033ad..469b4ff6cc3 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr @@ -29,11 +29,11 @@ pub fn get_app_nullifier_secret_key(account: AztecAddress) -> Field { } // TODO (#6176): Replace get_nullifier_keys above with this once we no longer get nullifier keys with address -#[oracle(getNullifierKeysWithNpkMH)] -fn get_nullifier_keys_with_npk_m_h_oracle(_npk_m_hash: Field) -> [Field; 3] {} +#[oracle(getNullifierKeysWithNpkMHash)] +fn get_nullifier_keys_with_npk_m_hash_oracle(_npk_m_hash: Field) -> [Field; 3] {} -unconstrained fn get_nullifier_keys_with_npk_m_h_internal(npk_m_hash: Field) -> NullifierKeys { - let result = get_nullifier_keys_with_npk_m_h_oracle(npk_m_hash); +unconstrained fn get_nullifier_keys_with_npk_m_hash_internal(npk_m_hash: Field) -> NullifierKeys { + let result = get_nullifier_keys_with_npk_m_hash_oracle(npk_m_hash); NullifierKeys { account: AztecAddress::zero(), master_nullifier_public_key: GrumpkinPoint { x: result[0], y: result[1] }, @@ -42,11 +42,11 @@ unconstrained fn get_nullifier_keys_with_npk_m_h_internal(npk_m_hash: Field) -> } // We get the full struct Nullifier Keys here -pub fn get_nullifier_keys_with_npk_m_h(npk_m_hash: Field) -> NullifierKeys { - get_nullifier_keys_with_npk_m_h_internal(npk_m_hash) +pub fn get_nullifier_keys_with_npk_m_hash(npk_m_hash: Field) -> NullifierKeys { + get_nullifier_keys_with_npk_m_hash_internal(npk_m_hash) } // We are only getting the app_nullifier_secret_key here pub fn get_nsk_app_with_npk_m_hash(npk_m_hash: Field) -> Field { - get_nullifier_keys_with_npk_m_h_internal(npk_m_hash).app_nullifier_secret_key + get_nullifier_keys_with_npk_m_hash_internal(npk_m_hash).app_nullifier_secret_key } From 993e33dbda7c4df21496276b47a51549f476a01b Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 10 May 2024 19:55:18 +0000 Subject: [PATCH 79/93] fix --- noir-projects/aztec-nr/aztec/src/context/private_context.nr | 4 +--- .../contracts/token_contract/src/types/token_note.nr | 3 ++- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index ecf11bdc305..1b286894f3a 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -240,9 +240,7 @@ impl PrivateContext { }; // We have to check if the key that was requested or cached corresponds to the one we request for - assert_eq( - poseidon2_hash(keys.master_nullifier_public_key.serialize()), npk_m_hash - ); + assert_eq(poseidon2_hash(keys.master_nullifier_public_key.serialize()), npk_m_hash); keys.app_nullifier_secret_key } diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr index dc997924faf..fa13976f9d5 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr @@ -1,5 +1,6 @@ use dep::aztec::{ - keys::getters::get_ivpk_m_with_npk_m_hash, prelude::{AztecAddress, NoteHeader, NoteInterface, PrivateContext}, + keys::getters::get_ivpk_m_with_npk_m_hash, + prelude::{AztecAddress, NoteHeader, NoteInterface, PrivateContext}, protocol_types::constants::GENERATOR_INDEX__NOTE_NULLIFIER, note::utils::compute_note_hash_for_consumption, hash::poseidon2_hash, oracle::{unsafe_rand::unsafe_rand, nullifier_key::get_nsk_app_with_npk_m_hash} From 31ec469a7d4fba31eb0421f565435dcbe2136d28 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 10 May 2024 20:25:18 +0000 Subject: [PATCH 80/93] Refactors --- .../circuit-types/src/keys/key_store.ts | 4 +-- yarn-project/key-store/src/test_key_store.ts | 28 +++++++-------- .../pxe/src/database/kv_pxe_database.ts | 6 ++-- yarn-project/pxe/src/database/pxe_database.ts | 2 +- .../pxe/src/simulator_oracle/index.ts | 34 ++++--------------- .../simulator/src/acvm/oracle/oracle.ts | 25 +++++++++----- .../simulator/src/acvm/oracle/typed_oracle.ts | 12 ++----- .../simulator/src/client/db_oracle.ts | 21 ++---------- .../simulator/src/client/simulator.test.ts | 2 +- .../simulator/src/client/view_data_oracle.ts | 28 +++------------ 10 files changed, 49 insertions(+), 113 deletions(-) diff --git a/yarn-project/circuit-types/src/keys/key_store.ts b/yarn-project/circuit-types/src/keys/key_store.ts index 176c323f7c9..3bee8446048 100644 --- a/yarn-project/circuit-types/src/keys/key_store.ts +++ b/yarn-project/circuit-types/src/keys/key_store.ts @@ -37,7 +37,7 @@ export interface KeyStore { * @param account or master nullifier public key hash - The account address or master nullifier public key hash for which to retrieve the master nullifier public key. * @returns The master nullifier public key for the account. */ - getMasterNullifierPublicKey(accountOrMasterNullifierPublicKeyHash: AztecAddress | Fr): Promise; + getMasterNullifierPublicKey(args: { account: AztecAddress } | { npkMHash: Fr }): Promise; /** * Gets the master incoming viewing public key for a given account. @@ -70,7 +70,7 @@ export interface KeyStore { * @param app - The application address to retrieve the nullifier secret key for. * @returns A Promise that resolves to the application nullifier secret key. */ - getAppNullifierSecretKey(accountOrMasterNullifierPublicKeyHash: AztecAddress | Fr, app: AztecAddress): Promise; + getAppNullifierSecretKey(args: { account: AztecAddress } | { npkMHash: Fr }, app: AztecAddress): Promise; /** * Retrieves application incoming viewing secret key. diff --git a/yarn-project/key-store/src/test_key_store.ts b/yarn-project/key-store/src/test_key_store.ts index 0fc60354bc3..f108bafb74a 100644 --- a/yarn-project/key-store/src/test_key_store.ts +++ b/yarn-project/key-store/src/test_key_store.ts @@ -102,18 +102,16 @@ export class TestKeyStore implements KeyStore { * @returns The master nullifier public key for the account. */ public async getMasterNullifierPublicKey( - accountOrMasterNullifierPublicKeyHash: AztecAddress | Fr, + args: { account: AztecAddress } | { npkMHash: Fr }, ): Promise { - const masterNullifierPublicKeyBuffer = - this.#keys.get(`${accountOrMasterNullifierPublicKeyHash.toString()}-npk_m`) ?? - this.#keys.get( - `${this.#getAccountAddressForMasterNullifierPublicKeyHash( - accountOrMasterNullifierPublicKeyHash, - )?.toString()}-npk_m`, - ); + const masterNullifierPublicKeyBuffer = 'account' in args ? this.#keys.get(`${args.account.toString()}-npk_m`) : this.#keys.get( + `${this.#getAccountAddressForMasterNullifierPublicKeyHash( + args.npkMHash, + )?.toString()}-npk_m`, + ); if (!masterNullifierPublicKeyBuffer) { throw new Error( - `Account or master nullifier public key hash ${accountOrMasterNullifierPublicKeyHash.toString()} does not exist. Registered accounts: ${await this.getAccounts()}.`, + `${'account' in args ? `Account ${args.account}` : `Master nullifier public key hash ${args.npkMHash}`} does not exist. Registered accounts: ${await this.getAccounts()}.`, ); } return Promise.resolve(Point.fromBuffer(masterNullifierPublicKeyBuffer)); @@ -175,19 +173,17 @@ export class TestKeyStore implements KeyStore { * @returns A Promise that resolves to the application nullifier secret key. */ public async getAppNullifierSecretKey( - accountOrMasterNullifierPublicKeyHash: AztecAddress | Fr, + args: { account: AztecAddress } | { npkMHash: Fr }, app: AztecAddress, ): Promise { - const masterNullifierSecretKeyBuffer = - this.#keys.get(`${accountOrMasterNullifierPublicKeyHash.toString()}-nsk_m`) ?? + const masterNullifierSecretKeyBuffer = 'account' in args ? + this.#keys.get(`${args.account.toString()}-nsk_m`) : this.#keys.get( - `${this.#getAccountAddressForMasterNullifierPublicKeyHash( - accountOrMasterNullifierPublicKeyHash, - )?.toString()}-nsk_m`, + `${this.#getAccountAddressForMasterNullifierPublicKeyHash(args.npkMHash)?.toString()}-nsk_m`, ); if (!masterNullifierSecretKeyBuffer) { throw new Error( - `Account or master nullifier public key hash ${accountOrMasterNullifierPublicKeyHash.toString()} does not exist. Registered accounts: ${await this.getAccounts()}.`, + `${'account' in args ? `Account ${args.account}` : `Master nullifier public key hash ${args.npkMHash}`} does not exist. Registered accounts: ${await this.getAccounts()}.`, ); } const masterNullifierSecretKey = GrumpkinScalar.fromBuffer(masterNullifierSecretKeyBuffer); diff --git a/yarn-project/pxe/src/database/kv_pxe_database.ts b/yarn-project/pxe/src/database/kv_pxe_database.ts index 4b14070ea55..a293ec69e87 100644 --- a/yarn-project/pxe/src/database/kv_pxe_database.ts +++ b/yarn-project/pxe/src/database/kv_pxe_database.ts @@ -386,11 +386,11 @@ export class KVPxeDatabase implements PxeDatabase { return value ? CompleteAddress.fromBuffer(value) : undefined; } - getCompleteAddress(address: AztecAddress): Promise { - return Promise.resolve(this.#getCompleteAddress(address)); + getCompleteAddress(args: { account: AztecAddress } | { npkMHash: Fr }): Promise { + return Promise.resolve('account' in args ? this.#getCompleteAddress(args.account) : this.#getCompleteAddressWithNpkMHash(args.npkMHash)); } - getCompleteAddressByNpkMHash(npkMHash: Fr): Promise { + #getCompleteAddressWithNpkMHash(npkMHash: Fr): Promise { const completeAddresses = this.#getCompleteAddresses(); const completeAddress = completeAddresses.find(completeAddress => diff --git a/yarn-project/pxe/src/database/pxe_database.ts b/yarn-project/pxe/src/database/pxe_database.ts index 8868ef37cd3..d85921a6ec7 100644 --- a/yarn-project/pxe/src/database/pxe_database.ts +++ b/yarn-project/pxe/src/database/pxe_database.ts @@ -137,7 +137,7 @@ export interface PxeDatabase extends ContractArtifactDatabase, ContractInstanceD * @param address - The aztec address of the complete address contract. * @returns A promise that resolves to a CompleteAddress instance if the address is found, or undefined if not found. */ - getCompleteAddress(address: AztecAddress): Promise; + getCompleteAddress(args: { account: AztecAddress } | { npkMHash: Fr }): Promise; /** * Retrieves the complete address corresponding to the provided master nullifier public key hash. diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index 5da3b4c5b86..8c10abc8aa7 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -37,39 +37,17 @@ export class SimulatorOracle implements DBOracle { private log = createDebugLogger('aztec:pxe:simulator_oracle'), ) {} - async getNullifierKeys(accountAddress: AztecAddress, contractAddress: AztecAddress): Promise { - const masterNullifierPublicKey = await this.keyStore.getMasterNullifierPublicKey(accountAddress); - const appNullifierSecretKey = await this.keyStore.getAppNullifierSecretKey(accountAddress, contractAddress); + async getNullifierKeys(args: { account: AztecAddress } | { npkMHash: Fr }, contractAddress: AztecAddress): Promise { + const masterNullifierPublicKey = await this.keyStore.getMasterNullifierPublicKey(args); + const appNullifierSecretKey = await this.keyStore.getAppNullifierSecretKey(args, contractAddress); return { masterNullifierPublicKey, appNullifierSecretKey }; } - async getNullifierKeysWithNpkMHash( - masterNullifierPublicKeyHash: AztecAddress, - contractAddress: AztecAddress, - ): Promise { - const masterNullifierPublicKey = await this.keyStore.getMasterNullifierPublicKey(masterNullifierPublicKeyHash); - const appNullifierSecretKey = await this.keyStore.getAppNullifierSecretKey( - masterNullifierPublicKeyHash, - contractAddress, - ); - return { masterNullifierPublicKey, appNullifierSecretKey }; - } - - async getCompleteAddress(address: AztecAddress): Promise { - const completeAddress = await this.db.getCompleteAddress(address); - if (!completeAddress) { - throw new Error( - `No public key registered for address ${address.toString()}. Register it by calling pxe.registerRecipient(...) or pxe.registerAccount(...).\nSee docs for context: https://docs.aztec.network/developers/debugging/aztecnr-errors#simulation-error-No-public-key-registered-for-address-0x0-Register-it-by-calling-pxeregisterRecipient-or-pxeregisterAccount`, - ); - } - return completeAddress; - } - - async getCompleteAddressWithNpkMHash(masterNullifierPublicKeyHash: Fr): Promise { - const completeAddress = await this.db.getCompleteAddressByNpkMHash(masterNullifierPublicKeyHash); + async getCompleteAddress(args: { account: AztecAddress } | { npkMHash: Fr }): Promise { + const completeAddress = await this.db.getCompleteAddress(args); if (!completeAddress) { throw new Error( - `No public key registered for master nullifier public key hash ${masterNullifierPublicKeyHash.toString()}. Register it by calling pxe.registerRecipient(...) or pxe.registerAccount(...).\nSee docs for context: https://docs.aztec.network/developers/debugging/aztecnr-errors#simulation-error-No-public-key-registered-for-address-0x0-Register-it-by-calling-pxeregisterRecipient-or-pxeregisterAccount`, + `No public key registered for ${'account' in args ? `address ${args.account}` : `master nullifier public key hash ${args.npkMHash}`}. Register it by calling pxe.registerRecipient(...) or pxe.registerAccount(...).\nSee docs for context: https://docs.aztec.network/developers/debugging/aztecnr-errors#simulation-error-No-public-key-registered-for-address-0x0-Register-it-by-calling-pxeregisterRecipient-or-pxeregisterAccount`, ); } return completeAddress; diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index eeb4c7c3cc2..0fda8ac6bb9 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -43,9 +43,9 @@ export class Oracle { } async getNullifierKeys([accountAddress]: ACVMField[]): Promise { - const { masterNullifierPublicKey, appNullifierSecretKey } = await this.typedOracle.getNullifierKeys( - fromACVMField(accountAddress), - ); + const { masterNullifierPublicKey, appNullifierSecretKey } = await this.typedOracle.getNullifierKeys({ + account: fromACVMField(accountAddress), + }); return [ toACVMField(masterNullifierPublicKey.x), toACVMField(masterNullifierPublicKey.y), @@ -53,10 +53,12 @@ export class Oracle { ]; } + // Keeping this oracle separate from above because I don't want an implicit overload in noir code async getNullifierKeysWithNpkMHash([masterNullifierPublicKeyHash]: ACVMField[]): Promise { - const { masterNullifierPublicKey, appNullifierSecretKey } = await this.typedOracle.getNullifierKeysWithNpkMHash( - fromACVMField(masterNullifierPublicKeyHash), - ); + const { masterNullifierPublicKey, appNullifierSecretKey } = await this.typedOracle.getNullifierKeys({ + npkMHash: fromACVMField(masterNullifierPublicKeyHash) + }); + return [ toACVMField(masterNullifierPublicKey.x), toACVMField(masterNullifierPublicKey.y), @@ -183,7 +185,9 @@ export class Oracle { masterOutgoingViewingPublicKey, masterTaggingPublicKey, partialAddress, - } = await this.typedOracle.getCompleteAddress(parsedAddress); + } = await this.typedOracle.getCompleteAddress({ + account: parsedAddress, + }); return [ ...masterNullifierPublicKey.toFields(), @@ -194,8 +198,9 @@ export class Oracle { ].map(toACVMField); } + // Keeping this oracle separate from above because I don't want an implicit overload in noir code async getPublicKeysAndPartialAddressWithNpkMHash([masterNullifierPublicKeyHash]: ACVMField[]) { - const parsedNpkMH = fromACVMField(masterNullifierPublicKeyHash); + const parsedNpkMHash = fromACVMField(masterNullifierPublicKeyHash); const { masterNullifierPublicKey, @@ -203,7 +208,9 @@ export class Oracle { masterOutgoingViewingPublicKey, masterTaggingPublicKey, partialAddress, - } = await this.typedOracle.getCompleteAddressWithNpkMHash(parsedNpkMH); + } = await this.typedOracle.getCompleteAddress({ + npkMHash: parsedNpkMHash, + }); return [ ...masterNullifierPublicKey.toFields(), diff --git a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts index 01e811c514e..5b050be24ab 100644 --- a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts @@ -89,14 +89,10 @@ export abstract class TypedOracle { throw new OracleMethodNotAvailableError('unpackReturns'); } - getNullifierKeys(_accountAddress: AztecAddress): Promise { + getNullifierKeys(_args: { account: AztecAddress } | { npkMHash: Fr }): Promise { throw new OracleMethodNotAvailableError('getNullifierKeys'); } - getNullifierKeysWithNpkMHash(_masterNullifierPublicKeyHash: Fr): Promise { - throw new OracleMethodNotAvailableError('getNullifierKeysWithNpkMHash'); - } - getContractInstance(_address: AztecAddress): Promise { throw new OracleMethodNotAvailableError('getContractInstance'); } @@ -128,14 +124,10 @@ export abstract class TypedOracle { throw new OracleMethodNotAvailableError('getHeader'); } - getCompleteAddress(_address: AztecAddress): Promise { + getCompleteAddress(_args: { account: AztecAddress } | { npkMHash: Fr }): Promise { throw new OracleMethodNotAvailableError('getCompleteAddress'); } - getCompleteAddressWithNpkMHash(_masterNullifierPublicKeyHash: Fr): Promise { - throw new OracleMethodNotAvailableError('getCompleteAddressWithNpkMHash'); - } - getAuthWitness(_messageHash: Fr): Promise { throw new OracleMethodNotAvailableError('getAuthWitness'); } diff --git a/yarn-project/simulator/src/client/db_oracle.ts b/yarn-project/simulator/src/client/db_oracle.ts index f9f97cc5684..479a945c7a2 100644 --- a/yarn-project/simulator/src/client/db_oracle.ts +++ b/yarn-project/simulator/src/client/db_oracle.ts @@ -48,15 +48,7 @@ export interface DBOracle extends CommitmentsDB { * @param address - Address to fetch the pubkey for. * @returns A complete address associated with the input address. */ - getCompleteAddress(address: AztecAddress): Promise; - - /** - * Retrieve the complete address associated to a given master nullifier public key hash. - * @param npkMHash - The master nullifer public key hash. - * @returns The complete address associated with the input master nullifier public key hash. - * @throws if the master nullifier public key hash / account is not registered in the database. - */ - getCompleteAddressWithNpkMHash(masterNullifierPublicKeyHash: Fr): Promise; + getCompleteAddress(args: { account: AztecAddress } | { npkMHash: Fr }): Promise; /** * Retrieve the auth witness for a given message hash. @@ -80,16 +72,7 @@ export interface DBOracle extends CommitmentsDB { * @returns A Promise that resolves to nullifier keys of a requested account and contract. * @throws An error if the account is not registered in the database. */ - getNullifierKeys(accountAddress: AztecAddress, contractAddress: AztecAddress): Promise; - - /** - * Retrieve nullifier keys associated with a specific master nullifier public key hash and app/contract address. - * @param npkMHash - The master nullifer public key hash. - * @param contractAddress - The contract address. - * @returns The nullifier keys of an account (specified by a master nullifier public key hash) and contract. - * @throws if the master nullifier public key hash / account is not registered in the database. - */ - getNullifierKeysWithNpkMHash(masterNullifierPublicKeyHash: Fr, contractAddress: AztecAddress): Promise; + getNullifierKeys(args: { account: AztecAddress } | { npkMHash: Fr }, contractAddress: AztecAddress): Promise; /** * Retrieves a set of notes stored in the database for a given contract address and storage slot. diff --git a/yarn-project/simulator/src/client/simulator.test.ts b/yarn-project/simulator/src/client/simulator.test.ts index eabff3637ae..0f34bc9cd89 100644 --- a/yarn-project/simulator/src/client/simulator.test.ts +++ b/yarn-project/simulator/src/client/simulator.test.ts @@ -43,7 +43,7 @@ describe('Simulator', () => { oracle = mock(); node = mock(); - oracle.getNullifierKeysWithNpkMHash.mockResolvedValue({ + oracle.getNullifierKeys.mockResolvedValue({ masterNullifierPublicKey: ownerMasterNullifierPublicKey, appNullifierSecretKey, }); diff --git a/yarn-project/simulator/src/client/view_data_oracle.ts b/yarn-project/simulator/src/client/view_data_oracle.ts index 9e044dc21b7..aa25e39c2d5 100644 --- a/yarn-project/simulator/src/client/view_data_oracle.ts +++ b/yarn-project/simulator/src/client/view_data_oracle.ts @@ -40,18 +40,8 @@ export class ViewDataOracle extends TypedOracle { * @returns A Promise that resolves to nullifier keys of a requested account and contract. * @throws An error if the account is not registered in the database. */ - public override getNullifierKeys(account: AztecAddress): Promise { - return this.db.getNullifierKeys(account, this.contractAddress); - } - - /** - * Retrieve nullifier keys associated with a specific master nullifier public key hash and app/contract address. - * @param npkMHash - The master nullifer public key hash. - * @returns The nullifier keys of an account (specified by a master nullifier public key hash) and contract. - * @throws if the master nullifier public key hash / account is not registered in the database. - */ - public override getNullifierKeysWithNpkMHash(npkMHash: Fr): Promise { - return this.db.getNullifierKeysWithNpkMHash(npkMHash, this.contractAddress); + public override getNullifierKeys(args: { account: AztecAddress } | { npkMHash: Fr }): Promise { + return this.db.getNullifierKeys(args, this.contractAddress); } /** @@ -141,18 +131,8 @@ export class ViewDataOracle extends TypedOracle { * @param address - Address to fetch the complete address for. * @returns A complete address associated with the input address. */ - public override getCompleteAddress(address: AztecAddress): Promise { - return this.db.getCompleteAddress(address); - } - - /** - * Retrieve the complete address associated to a given master nullifier public key hash. - * @param npkMHash - The master nullifer public key hash. - * @returns The complete address associated with the input master nullifier public key hash. - * @throws if the master nullifier public key hash / account is not registered in the database. - */ - public override getCompleteAddressWithNpkMHash(npkMHash: Fr): Promise { - return this.db.getCompleteAddressWithNpkMHash(npkMHash); + public override getCompleteAddress(args: { account: AztecAddress } | { npkMHash: Fr }): Promise { + return this.db.getCompleteAddress(args); } /** From f418d3e6fd8baf77b7474cfe5231c10aa5d764bd Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 10 May 2024 20:36:27 +0000 Subject: [PATCH 81/93] fix comments --- yarn-project/pxe/src/database/pxe_database.ts | 6 +++--- yarn-project/simulator/src/client/db_oracle.ts | 17 ++++++++--------- .../simulator/src/client/view_data_oracle.ts | 15 ++++++++------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/yarn-project/pxe/src/database/pxe_database.ts b/yarn-project/pxe/src/database/pxe_database.ts index d85921a6ec7..e4c7a351f21 100644 --- a/yarn-project/pxe/src/database/pxe_database.ts +++ b/yarn-project/pxe/src/database/pxe_database.ts @@ -133,9 +133,9 @@ export interface PxeDatabase extends ContractArtifactDatabase, ContractInstanceD addCompleteAddress(address: CompleteAddress): Promise; /** - * Retrieves the complete address corresponding to the provided aztec address. - * @param address - The aztec address of the complete address contract. - * @returns A promise that resolves to a CompleteAddress instance if the address is found, or undefined if not found. + * Retrieve the complete address associated to a given address or master nullifier public key hash. + * @param args - contains account - the address or npkMHash - the master nullifier public key hash + * @returns A promise that resolves to a CompleteAddress instance if found, or undefined if not found. */ getCompleteAddress(args: { account: AztecAddress } | { npkMHash: Fr }): Promise; diff --git a/yarn-project/simulator/src/client/db_oracle.ts b/yarn-project/simulator/src/client/db_oracle.ts index 479a945c7a2..77233eb220a 100644 --- a/yarn-project/simulator/src/client/db_oracle.ts +++ b/yarn-project/simulator/src/client/db_oracle.ts @@ -44,9 +44,10 @@ export interface DBOracle extends CommitmentsDB { getContractInstance(address: AztecAddress): Promise; /** - * Retrieve the complete address associated to a given address. - * @param address - Address to fetch the pubkey for. - * @returns A complete address associated with the input address. + * Retrieve the complete address associated to a given address or master nullifier public key hash. + * @param args - contains account - the address or npkMHash - the master nullifier public key hash + * @returns A complete address associated with the input address or master nullifier public key hash + * @throws An error if the account is not registered in the database. */ getCompleteAddress(args: { account: AztecAddress } | { npkMHash: Fr }): Promise; @@ -65,12 +66,10 @@ export interface DBOracle extends CommitmentsDB { popCapsule(): Promise; /** - * Retrieve nullifier keys associated with a specific account and app/contract address. - * - * @param accountAddress - The account address. - * @param contractAddress - The contract address. - * @returns A Promise that resolves to nullifier keys of a requested account and contract. - * @throws An error if the account is not registered in the database. + * Retrieve nullifier keys associated with a (specific account or master nullifier key hash) and app/contract address. + * @param args - contains account - the address or npkMHash - the master nullifier public key hash + * @returns A Promise that resolves to nullifier keys of a (requested account or master nullifier key hash) and contract. + * @throws An error if the nullifier keys associated to account or master nullifier public key hash is not registered in the key store. */ getNullifierKeys(args: { account: AztecAddress } | { npkMHash: Fr }, contractAddress: AztecAddress): Promise; diff --git a/yarn-project/simulator/src/client/view_data_oracle.ts b/yarn-project/simulator/src/client/view_data_oracle.ts index aa25e39c2d5..298d75406b2 100644 --- a/yarn-project/simulator/src/client/view_data_oracle.ts +++ b/yarn-project/simulator/src/client/view_data_oracle.ts @@ -35,10 +35,10 @@ export class ViewDataOracle extends TypedOracle { } /** - * Retrieve nullifier keys associated with a specific account and app/contract address. - * @param accountAddress - The account address. - * @returns A Promise that resolves to nullifier keys of a requested account and contract. - * @throws An error if the account is not registered in the database. + * Retrieve nullifier keys associated with a (specific account or master nullifier key hash) and app/contract address. + * @param args - contains account - the address or npkMHash - the master nullifier public key hash + * @returns A Promise that resolves to nullifier keys of a (requested account or master nullifier key hash) and contract. + * @throws An error if the nullifier keys associated to account or master nullifier public key hash is not registered in the key store. */ public override getNullifierKeys(args: { account: AztecAddress } | { npkMHash: Fr }): Promise { return this.db.getNullifierKeys(args, this.contractAddress); @@ -127,9 +127,10 @@ export class ViewDataOracle extends TypedOracle { } /** - * Retrieve the complete address associated to a given address. - * @param address - Address to fetch the complete address for. - * @returns A complete address associated with the input address. + * Retrieve the complete address associated to a given address or master nullifier public key hash. + * @param args - contains account - the address or npkMHash - the master nullifier public key hash + * @returns A complete address associated with the input address or master nullifier public key hash + * @throws An error if the account is not registered in the database. */ public override getCompleteAddress(args: { account: AztecAddress } | { npkMHash: Fr }): Promise { return this.db.getCompleteAddress(args); From 45119071ea3bcd2ab27a63c3519d4018fe63f9a5 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 10 May 2024 20:39:05 +0000 Subject: [PATCH 82/93] asdf --- yarn-project/pxe/src/database/pxe_database.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/yarn-project/pxe/src/database/pxe_database.ts b/yarn-project/pxe/src/database/pxe_database.ts index e4c7a351f21..8de09765e88 100644 --- a/yarn-project/pxe/src/database/pxe_database.ts +++ b/yarn-project/pxe/src/database/pxe_database.ts @@ -139,13 +139,6 @@ export interface PxeDatabase extends ContractArtifactDatabase, ContractInstanceD */ getCompleteAddress(args: { account: AztecAddress } | { npkMHash: Fr }): Promise; - /** - * Retrieves the complete address corresponding to the provided master nullifier public key hash. - * @param npkMHash - The master nullifier public key hash of the account. - * @returns A promise that resolves to a CompleteAddress instance if the address is found, or undefined if not found. - */ - getCompleteAddressByNpkMHash(npkMHash: Fr): Promise; - /** * Retrieves the list of complete address added to this database * @returns A promise that resolves to an array of AztecAddress instances. From e9a1007c37c9c2d6b60f7665a07d914ea7f8209b Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 10 May 2024 21:50:11 +0000 Subject: [PATCH 83/93] fmt --- .../key-store/src/test_key_store.test.ts | 4 +- yarn-project/key-store/src/test_key_store.ts | 30 +++++++------- .../pxe/src/database/kv_pxe_database.ts | 4 +- .../src/database/pxe_database_test_suite.ts | 4 +- .../pxe/src/pxe_service/pxe_service.ts | 2 +- .../pxe/src/simulator_oracle/index.ts | 9 ++++- .../pxe/src/synchronizer/synchronizer.ts | 2 +- .../simulator/src/acvm/oracle/oracle.ts | 2 +- .../simulator/src/client/db_oracle.ts | 5 ++- .../src/client/private_execution.test.ts | 40 ++++++++++--------- .../client/unconstrained_execution.test.ts | 6 +-- 11 files changed, 60 insertions(+), 48 deletions(-) diff --git a/yarn-project/key-store/src/test_key_store.test.ts b/yarn-project/key-store/src/test_key_store.test.ts index 2395dbf1472..79da6da8255 100644 --- a/yarn-project/key-store/src/test_key_store.test.ts +++ b/yarn-project/key-store/src/test_key_store.test.ts @@ -16,7 +16,7 @@ describe('TestKeyStore', () => { `"0x1a8a9a1d91cbb353d8df4f1bbfd0283f7fc63766f671edd9443a1270a7b2a954"`, ); - const masterNullifierPublicKey = await keyStore.getMasterNullifierPublicKey(accountAddress); + const masterNullifierPublicKey = await keyStore.getMasterNullifierPublicKey({ account: accountAddress }); expect(masterNullifierPublicKey.toString()).toMatchInlineSnapshot( `"0x2ef5d15dd65d29546680ab72846fb071f41cb9f2a0212215e6c560e29df4ff650ce764818364b376be92dc2f49577fe440e64a16012584f7c4ee94f7edbc323a"`, ); @@ -44,7 +44,7 @@ describe('TestKeyStore', () => { // Arbitrary app contract address const appAddress = AztecAddress.fromBigInt(624n); - const appNullifierSecretKey = await keyStore.getAppNullifierSecretKey(accountAddress, appAddress); + const appNullifierSecretKey = await keyStore.getAppNullifierSecretKey({ account: accountAddress }, appAddress); expect(appNullifierSecretKey.toString()).toMatchInlineSnapshot( `"0x230a44dfe7cfec7a735c89f7289c5cb5d2c3dc0bf5d3505917fd2476f67873a8"`, ); diff --git a/yarn-project/key-store/src/test_key_store.ts b/yarn-project/key-store/src/test_key_store.ts index f108bafb74a..8547b5a9a7f 100644 --- a/yarn-project/key-store/src/test_key_store.ts +++ b/yarn-project/key-store/src/test_key_store.ts @@ -101,17 +101,16 @@ export class TestKeyStore implements KeyStore { * @param account or master nullifier public key hash - The account address or master nullifier public key hash for which to retrieve the master nullifier public key. * @returns The master nullifier public key for the account. */ - public async getMasterNullifierPublicKey( - args: { account: AztecAddress } | { npkMHash: Fr }, - ): Promise { - const masterNullifierPublicKeyBuffer = 'account' in args ? this.#keys.get(`${args.account.toString()}-npk_m`) : this.#keys.get( - `${this.#getAccountAddressForMasterNullifierPublicKeyHash( - args.npkMHash, - )?.toString()}-npk_m`, - ); + public async getMasterNullifierPublicKey(args: { account: AztecAddress } | { npkMHash: Fr }): Promise { + const masterNullifierPublicKeyBuffer = + 'account' in args + ? this.#keys.get(`${args.account.toString()}-npk_m`) + : this.#keys.get(`${this.#getAccountAddressForMasterNullifierPublicKeyHash(args.npkMHash)?.toString()}-npk_m`); if (!masterNullifierPublicKeyBuffer) { throw new Error( - `${'account' in args ? `Account ${args.account}` : `Master nullifier public key hash ${args.npkMHash}`} does not exist. Registered accounts: ${await this.getAccounts()}.`, + `${ + 'account' in args ? `Account ${args.account}` : `Master nullifier public key hash ${args.npkMHash}` + } does not exist. Registered accounts: ${await this.getAccounts()}.`, ); } return Promise.resolve(Point.fromBuffer(masterNullifierPublicKeyBuffer)); @@ -176,14 +175,15 @@ export class TestKeyStore implements KeyStore { args: { account: AztecAddress } | { npkMHash: Fr }, app: AztecAddress, ): Promise { - const masterNullifierSecretKeyBuffer = 'account' in args ? - this.#keys.get(`${args.account.toString()}-nsk_m`) : - this.#keys.get( - `${this.#getAccountAddressForMasterNullifierPublicKeyHash(args.npkMHash)?.toString()}-nsk_m`, - ); + const masterNullifierSecretKeyBuffer = + 'account' in args + ? this.#keys.get(`${args.account.toString()}-nsk_m`) + : this.#keys.get(`${this.#getAccountAddressForMasterNullifierPublicKeyHash(args.npkMHash)?.toString()}-nsk_m`); if (!masterNullifierSecretKeyBuffer) { throw new Error( - `${'account' in args ? `Account ${args.account}` : `Master nullifier public key hash ${args.npkMHash}`} does not exist. Registered accounts: ${await this.getAccounts()}.`, + `${ + 'account' in args ? `Account ${args.account}` : `Master nullifier public key hash ${args.npkMHash}` + } does not exist. Registered accounts: ${await this.getAccounts()}.`, ); } const masterNullifierSecretKey = GrumpkinScalar.fromBuffer(masterNullifierSecretKeyBuffer); diff --git a/yarn-project/pxe/src/database/kv_pxe_database.ts b/yarn-project/pxe/src/database/kv_pxe_database.ts index a293ec69e87..37a03f30500 100644 --- a/yarn-project/pxe/src/database/kv_pxe_database.ts +++ b/yarn-project/pxe/src/database/kv_pxe_database.ts @@ -387,7 +387,9 @@ export class KVPxeDatabase implements PxeDatabase { } getCompleteAddress(args: { account: AztecAddress } | { npkMHash: Fr }): Promise { - return Promise.resolve('account' in args ? this.#getCompleteAddress(args.account) : this.#getCompleteAddressWithNpkMHash(args.npkMHash)); + return Promise.resolve( + 'account' in args ? this.#getCompleteAddress(args.account) : this.#getCompleteAddressWithNpkMHash(args.npkMHash), + ); } #getCompleteAddressWithNpkMHash(npkMHash: Fr): Promise { diff --git a/yarn-project/pxe/src/database/pxe_database_test_suite.ts b/yarn-project/pxe/src/database/pxe_database_test_suite.ts index 440df3db400..53572441c6d 100644 --- a/yarn-project/pxe/src/database/pxe_database_test_suite.ts +++ b/yarn-project/pxe/src/database/pxe_database_test_suite.ts @@ -209,7 +209,7 @@ export function describePxeDatabase(getDatabase: () => PxeDatabase) { it('stores and retrieves addresses', async () => { const address = CompleteAddress.random(); await expect(database.addCompleteAddress(address)).resolves.toBe(true); - await expect(database.getCompleteAddress(address.address)).resolves.toEqual(address); + await expect(database.getCompleteAddress({ account: address.address })).resolves.toEqual(address); }); it('silently ignores an address it already knows about', async () => { @@ -248,7 +248,7 @@ export function describePxeDatabase(getDatabase: () => PxeDatabase) { }); it("returns undefined if it doesn't have an address", async () => { - expect(await database.getCompleteAddress(CompleteAddress.random().address)).toBeUndefined(); + expect(await database.getCompleteAddress({ account: CompleteAddress.random().address })).toBeUndefined(); }); }); diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index 8769a2d68db..8ed1734e82c 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -297,7 +297,7 @@ export class PXEService implements PXE { } public async addNote(note: ExtendedNote) { - const { masterIncomingViewingPublicKey } = (await this.db.getCompleteAddress(note.owner)) ?? {}; + const { masterIncomingViewingPublicKey } = (await this.db.getCompleteAddress({ account: note.owner })) ?? {}; if (!masterIncomingViewingPublicKey) { throw new Error('Unknown account.'); } diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index 8c10abc8aa7..ee4fc90be3f 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -37,7 +37,10 @@ export class SimulatorOracle implements DBOracle { private log = createDebugLogger('aztec:pxe:simulator_oracle'), ) {} - async getNullifierKeys(args: { account: AztecAddress } | { npkMHash: Fr }, contractAddress: AztecAddress): Promise { + async getNullifierKeys( + args: { account: AztecAddress } | { npkMHash: Fr }, + contractAddress: AztecAddress, + ): Promise { const masterNullifierPublicKey = await this.keyStore.getMasterNullifierPublicKey(args); const appNullifierSecretKey = await this.keyStore.getAppNullifierSecretKey(args, contractAddress); return { masterNullifierPublicKey, appNullifierSecretKey }; @@ -47,7 +50,9 @@ export class SimulatorOracle implements DBOracle { const completeAddress = await this.db.getCompleteAddress(args); if (!completeAddress) { throw new Error( - `No public key registered for ${'account' in args ? `address ${args.account}` : `master nullifier public key hash ${args.npkMHash}`}. Register it by calling pxe.registerRecipient(...) or pxe.registerAccount(...).\nSee docs for context: https://docs.aztec.network/developers/debugging/aztecnr-errors#simulation-error-No-public-key-registered-for-address-0x0-Register-it-by-calling-pxeregisterRecipient-or-pxeregisterAccount`, + `No public key registered for ${ + 'account' in args ? `address ${args.account}` : `master nullifier public key hash ${args.npkMHash}` + }. Register it by calling pxe.registerRecipient(...) or pxe.registerAccount(...).\nSee docs for context: https://docs.aztec.network/developers/debugging/aztecnr-errors#simulation-error-No-public-key-registered-for-address-0x0-Register-it-by-calling-pxeregisterRecipient-or-pxeregisterAccount`, ); } return completeAddress; diff --git a/yarn-project/pxe/src/synchronizer/synchronizer.ts b/yarn-project/pxe/src/synchronizer/synchronizer.ts index d7da26c991e..5f6cf4c0715 100644 --- a/yarn-project/pxe/src/synchronizer/synchronizer.ts +++ b/yarn-project/pxe/src/synchronizer/synchronizer.ts @@ -281,7 +281,7 @@ export class Synchronizer { * @throws If checking a sync status of account which is not registered. */ public async isAccountStateSynchronized(account: AztecAddress) { - const completeAddress = await this.db.getCompleteAddress(account); + const completeAddress = await this.db.getCompleteAddress({ account }); if (!completeAddress) { throw new Error(`Checking if account is synched is not possible for ${account} because it is not registered.`); } diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index 0fda8ac6bb9..8a0448cb190 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -56,7 +56,7 @@ export class Oracle { // Keeping this oracle separate from above because I don't want an implicit overload in noir code async getNullifierKeysWithNpkMHash([masterNullifierPublicKeyHash]: ACVMField[]): Promise { const { masterNullifierPublicKey, appNullifierSecretKey } = await this.typedOracle.getNullifierKeys({ - npkMHash: fromACVMField(masterNullifierPublicKeyHash) + npkMHash: fromACVMField(masterNullifierPublicKeyHash), }); return [ diff --git a/yarn-project/simulator/src/client/db_oracle.ts b/yarn-project/simulator/src/client/db_oracle.ts index 77233eb220a..9b9e3f91743 100644 --- a/yarn-project/simulator/src/client/db_oracle.ts +++ b/yarn-project/simulator/src/client/db_oracle.ts @@ -71,7 +71,10 @@ export interface DBOracle extends CommitmentsDB { * @returns A Promise that resolves to nullifier keys of a (requested account or master nullifier key hash) and contract. * @throws An error if the nullifier keys associated to account or master nullifier public key hash is not registered in the key store. */ - getNullifierKeys(args: { account: AztecAddress } | { npkMHash: Fr }, contractAddress: AztecAddress): Promise; + getNullifierKeys( + args: { account: AztecAddress } | { npkMHash: Fr }, + contractAddress: AztecAddress, + ): Promise; /** * Retrieves a set of notes stored in the database for a given contract address and storage slot. diff --git a/yarn-project/simulator/src/client/private_execution.test.ts b/yarn-project/simulator/src/client/private_execution.test.ts index 7c9666f8317..157688dd4dd 100644 --- a/yarn-project/simulator/src/client/private_execution.test.ts +++ b/yarn-project/simulator/src/client/private_execution.test.ts @@ -190,35 +190,37 @@ describe('Private Execution test suite', () => { beforeEach(async () => { trees = {}; oracle = mock(); - oracle.getNullifierKeys.mockImplementation((accountAddress: AztecAddress, contractAddress: AztecAddress) => { - if (accountAddress.equals(ownerCompleteAddress.address)) { - return Promise.resolve({ - masterNullifierPublicKey: ownerCompleteAddress.masterNullifierPublicKey, - appNullifierSecretKey: computeAppNullifierSecretKey(ownerMasterNullifierSecretKey, contractAddress), - }); - } - if (accountAddress.equals(recipientCompleteAddress.address)) { - return Promise.resolve({ - masterNullifierPublicKey: recipientCompleteAddress.masterNullifierPublicKey, - appNullifierSecretKey: computeAppNullifierSecretKey(recipientMasterNullifierSecretKey, contractAddress), - }); - } - throw new Error(`Unknown address ${accountAddress}`); - }); + oracle.getNullifierKeys.mockImplementation( + (args: { account: AztecAddress } | { npkMHash: Fr }, contractAddress: AztecAddress) => { + if ('account' in args && args.account.equals(ownerCompleteAddress.address)) { + return Promise.resolve({ + masterNullifierPublicKey: ownerCompleteAddress.masterNullifierPublicKey, + appNullifierSecretKey: computeAppNullifierSecretKey(ownerMasterNullifierSecretKey, contractAddress), + }); + } + if ('account' in args && args.account.equals(recipientCompleteAddress.address)) { + return Promise.resolve({ + masterNullifierPublicKey: recipientCompleteAddress.masterNullifierPublicKey, + appNullifierSecretKey: computeAppNullifierSecretKey(recipientMasterNullifierSecretKey, contractAddress), + }); + } + throw new Error(`Unknown ${'account' in args ? 'address' : 'npkMHash'}`); + }, + ); // We call insertLeaves here with no leaves to populate empty public data tree root --> this is necessary to be // able to get ivpk_m during execution await insertLeaves([], 'publicData'); oracle.getHeader.mockResolvedValue(header); - oracle.getCompleteAddress.mockImplementation((address: AztecAddress) => { - if (address.equals(owner)) { + oracle.getCompleteAddress.mockImplementation((args: { account: AztecAddress } | { npkMHash: Fr }) => { + if ('account' in args && args.account.equals(owner)) { return Promise.resolve(ownerCompleteAddress); } - if (address.equals(recipient)) { + if ('account' in args && args.account.equals(recipient)) { return Promise.resolve(recipientCompleteAddress); } - throw new Error(`Unknown address ${address}`); + throw new Error(`Unknown ${'account' in args ? 'address' : 'npkMHash'}`); }); // 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 diff --git a/yarn-project/simulator/src/client/unconstrained_execution.test.ts b/yarn-project/simulator/src/client/unconstrained_execution.test.ts index fe099451a6f..871949ed2e7 100644 --- a/yarn-project/simulator/src/client/unconstrained_execution.test.ts +++ b/yarn-project/simulator/src/client/unconstrained_execution.test.ts @@ -33,11 +33,11 @@ describe('Unconstrained Execution test suite', () => { const ownerCompleteAddress = CompleteAddress.fromSecretKeyAndPartialAddress(ownerSecretKey, Fr.random()); owner = ownerCompleteAddress.address; - oracle.getCompleteAddress.mockImplementation((address: AztecAddress) => { - if (address.equals(owner)) { + oracle.getCompleteAddress.mockImplementation((args: { account: AztecAddress } | { npkMHash: Fr }) => { + if ('account' in args && args.account.equals(owner)) { return Promise.resolve(ownerCompleteAddress); } - throw new Error(`Unknown address ${address}`); + throw new Error(`Unknown ${'account' in args ? 'address' : 'npkMHash'}`); }); }); From 34b8aa124517a57fbc6852044a461d2074fba038 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Sat, 11 May 2024 12:02:24 +0000 Subject: [PATCH 84/93] bump timeouts --- yarn-project/p2p/src/service/data_store.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn-project/p2p/src/service/data_store.test.ts b/yarn-project/p2p/src/service/data_store.test.ts index e718d6737af..5c8e4c541e1 100644 --- a/yarn-project/p2p/src/service/data_store.test.ts +++ b/yarn-project/p2p/src/service/data_store.test.ts @@ -177,7 +177,7 @@ export function interfaceDatastoreTests(test: I afterEach(async () => { await cleanup(store); - }); + }, 15_000); it('simple', async () => { const k = new Key('/z/key'); From 44f8bf496eb75befd74d1ce9c469e0a4f1601994 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Sat, 11 May 2024 12:25:36 +0000 Subject: [PATCH 85/93] test --- yarn-project/p2p/src/service/data_store.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yarn-project/p2p/src/service/data_store.test.ts b/yarn-project/p2p/src/service/data_store.test.ts index 5c8e4c541e1..67567750109 100644 --- a/yarn-project/p2p/src/service/data_store.test.ts +++ b/yarn-project/p2p/src/service/data_store.test.ts @@ -177,7 +177,7 @@ export function interfaceDatastoreTests(test: I afterEach(async () => { await cleanup(store); - }, 15_000); + }); it('simple', async () => { const k = new Key('/z/key'); @@ -390,7 +390,7 @@ export function interfaceDatastoreTests(test: I afterEach(async () => { await cleanup(store); - }); + }, 15_000); it('simple', async () => { const b = store.batch(); From 3287585d5164dddb7408813155986f91dac63179 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Mon, 13 May 2024 17:18:18 +0000 Subject: [PATCH 86/93] fixing --- noir-projects/aztec-nr/aztec/src/keys/getters.nr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/keys/getters.nr b/noir-projects/aztec-nr/aztec/src/keys/getters.nr index 57f067e9209..aaaa560f061 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/getters.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/getters.nr @@ -1,6 +1,6 @@ -use dep::protocol_types::{address::AztecAddress, constants::CANONICAL_KEY_REGISTRY_ADDRESS, grumpkin_point::GrumpkinPoint}; +use dep::protocol_types::{address::AztecAddress, constants::CANONICAL_KEY_REGISTRY_ADDRESS, grumpkin_point::GrumpkinPoint, hash::poseidon2_hash}; use crate::{ - context::PrivateContext, oracle::keys::get_public_keys_and_partial_address, + context::PrivateContext, oracle::keys::{get_public_keys_and_partial_address, get_public_keys_and_partial_address_with_npk_m_hash}, keys::public_keys::{PublicKeys, NULLIFIER_INDEX, INCOMING_INDEX}, state_vars::{ map::derive_storage_slot_in_map, From dc1476a5cd3bd2a4ea31c1106baaebc447cf6d6a Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Mon, 13 May 2024 17:40:51 +0000 Subject: [PATCH 87/93] format --- noir-projects/aztec-nr/aztec/src/keys/getters.nr | 8 ++++++-- yarn-project/pxe/src/database/kv_pxe_database.ts | 2 +- yarn-project/pxe/src/pxe_service/pxe_service.ts | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/keys/getters.nr b/noir-projects/aztec-nr/aztec/src/keys/getters.nr index aaaa560f061..443700f5f60 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/getters.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/getters.nr @@ -1,6 +1,10 @@ -use dep::protocol_types::{address::AztecAddress, constants::CANONICAL_KEY_REGISTRY_ADDRESS, grumpkin_point::GrumpkinPoint, hash::poseidon2_hash}; +use dep::protocol_types::{ + address::AztecAddress, constants::CANONICAL_KEY_REGISTRY_ADDRESS, grumpkin_point::GrumpkinPoint, + hash::poseidon2_hash +}; use crate::{ - context::PrivateContext, oracle::keys::{get_public_keys_and_partial_address, get_public_keys_and_partial_address_with_npk_m_hash}, + context::PrivateContext, + oracle::keys::{get_public_keys_and_partial_address, get_public_keys_and_partial_address_with_npk_m_hash}, keys::public_keys::{PublicKeys, NULLIFIER_INDEX, INCOMING_INDEX}, state_vars::{ map::derive_storage_slot_in_map, diff --git a/yarn-project/pxe/src/database/kv_pxe_database.ts b/yarn-project/pxe/src/database/kv_pxe_database.ts index dbdd0b11034..408030b214d 100644 --- a/yarn-project/pxe/src/database/kv_pxe_database.ts +++ b/yarn-project/pxe/src/database/kv_pxe_database.ts @@ -396,7 +396,7 @@ export class KVPxeDatabase implements PxeDatabase { const completeAddresses = this.#getCompleteAddresses(); const completeAddress = completeAddresses.find(completeAddress => - poseidon2Hash(completeAddress.masterNullifierPublicKey.toFields()).equals(npkMHash), + poseidon2Hash(completeAddress.publicKeys.masterNullifierPublicKey.toFields()).equals(npkMHash), ); return Promise.resolve(completeAddress); } diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index 6a2333a71df..3475d1dc983 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -301,7 +301,7 @@ export class PXEService implements PXE { } public async addNote(note: ExtendedNote) { - const owner = await this.db.getCompleteAddress({ account: note.owner }) ?? {}; + const owner = await this.db.getCompleteAddress({ account: note.owner }); if (!owner) { throw new Error(`Unknown account: ${note.owner.toString()}`); } From f014dded6585c2912f860a374d6b9e0226f7c591 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Tue, 14 May 2024 10:10:33 +0000 Subject: [PATCH 88/93] Addressing comments --- noir-projects/aztec-nr/aztec/src/keys/getters.nr | 2 +- noir-projects/aztec-nr/aztec/src/oracle/keys.nr | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/keys/getters.nr b/noir-projects/aztec-nr/aztec/src/keys/getters.nr index 443700f5f60..41be7f71073 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/getters.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/getters.nr @@ -91,5 +91,5 @@ fn fetch_and_constrain_keys(address: AztecAddress) -> PublicKeys { pub fn get_ivpk_m_with_npk_m_hash(npk_m_hash: Field) -> GrumpkinPoint { let result = get_public_keys_and_partial_address_with_npk_m_hash(npk_m_hash); - result.0[1] + result.0.ivpk_m } diff --git a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr index 2cb9063ba53..451d9bbff63 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr @@ -30,14 +30,17 @@ unconstrained fn get_public_keys_and_partial_address_with_npk_m_hash_oracle_wrap get_public_keys_and_partial_address_with_npk_m_hash_oracle(npk_m_hash) } -fn get_public_keys_and_partial_address_with_npk_m_hash(npk_m_hash: Field) -> ([GrumpkinPoint; 4], PartialAddress) { +fn get_public_keys_and_partial_address_with_npk_m_hash(npk_m_hash: Field) -> (PublicKeys, PartialAddress) { let result = get_public_keys_and_partial_address_with_npk_m_hash_oracle_wrapper(npk_m_hash); - let nullifier_pub_key = GrumpkinPoint::new(result[0], result[1]); - let incoming_pub_key = GrumpkinPoint::new(result[2], result[3]); - let outgoing_pub_key = GrumpkinPoint::new(result[4], result[5]); - let tagging_pub_key = GrumpkinPoint::new(result[6], result[7]); + let keys = PublicKeys { + npk_m: GrumpkinPoint::new(result[0], result[1]), + ivpk_m: GrumpkinPoint::new(result[2], result[3]), + ovpk_m: GrumpkinPoint::new(result[4], result[5]), + tpk_m: GrumpkinPoint::new(result[6], result[7]) + }; + let partial_address = PartialAddress::from_field(result[8]); - ([nullifier_pub_key, incoming_pub_key, outgoing_pub_key, tagging_pub_key], partial_address) + (keys, partial_address) } From 84e53c383b0a1f731e8381b5bf990a519d3e8174 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Tue, 14 May 2024 10:53:23 +0000 Subject: [PATCH 89/93] Addressing comments --- .../circuit-types/src/keys/key_store.ts | 4 +-- .../key-store/src/test_key_store.test.ts | 4 +-- yarn-project/key-store/src/test_key_store.ts | 26 +++++++------------ .../pxe/src/database/kv_pxe_database.ts | 5 ++-- yarn-project/pxe/src/database/pxe_database.ts | 4 +-- .../src/database/pxe_database_test_suite.ts | 4 +-- .../pxe/src/pxe_service/pxe_service.ts | 2 +- .../pxe/src/simulator_oracle/index.ts | 15 +++++------ .../pxe/src/synchronizer/synchronizer.ts | 2 +- .../simulator/src/acvm/oracle/oracle.ts | 16 +++--------- .../simulator/src/acvm/oracle/typed_oracle.ts | 4 +-- .../simulator/src/client/db_oracle.ts | 8 +++--- .../src/client/private_execution.test.ts | 16 ++++++------ .../client/unconstrained_execution.test.ts | 6 ++--- .../simulator/src/client/view_data_oracle.ts | 12 ++++----- 15 files changed, 56 insertions(+), 72 deletions(-) diff --git a/yarn-project/circuit-types/src/keys/key_store.ts b/yarn-project/circuit-types/src/keys/key_store.ts index 3bee8446048..9d42da54332 100644 --- a/yarn-project/circuit-types/src/keys/key_store.ts +++ b/yarn-project/circuit-types/src/keys/key_store.ts @@ -37,7 +37,7 @@ export interface KeyStore { * @param account or master nullifier public key hash - The account address or master nullifier public key hash for which to retrieve the master nullifier public key. * @returns The master nullifier public key for the account. */ - getMasterNullifierPublicKey(args: { account: AztecAddress } | { npkMHash: Fr }): Promise; + getMasterNullifierPublicKey(accountOrNpkMHash: AztecAddress | Fr): Promise; /** * Gets the master incoming viewing public key for a given account. @@ -70,7 +70,7 @@ export interface KeyStore { * @param app - The application address to retrieve the nullifier secret key for. * @returns A Promise that resolves to the application nullifier secret key. */ - getAppNullifierSecretKey(args: { account: AztecAddress } | { npkMHash: Fr }, app: AztecAddress): Promise; + getAppNullifierSecretKey(accountOrNpkMHash: AztecAddress | Fr, app: AztecAddress): Promise; /** * Retrieves application incoming viewing secret key. diff --git a/yarn-project/key-store/src/test_key_store.test.ts b/yarn-project/key-store/src/test_key_store.test.ts index 79da6da8255..2395dbf1472 100644 --- a/yarn-project/key-store/src/test_key_store.test.ts +++ b/yarn-project/key-store/src/test_key_store.test.ts @@ -16,7 +16,7 @@ describe('TestKeyStore', () => { `"0x1a8a9a1d91cbb353d8df4f1bbfd0283f7fc63766f671edd9443a1270a7b2a954"`, ); - const masterNullifierPublicKey = await keyStore.getMasterNullifierPublicKey({ account: accountAddress }); + const masterNullifierPublicKey = await keyStore.getMasterNullifierPublicKey(accountAddress); expect(masterNullifierPublicKey.toString()).toMatchInlineSnapshot( `"0x2ef5d15dd65d29546680ab72846fb071f41cb9f2a0212215e6c560e29df4ff650ce764818364b376be92dc2f49577fe440e64a16012584f7c4ee94f7edbc323a"`, ); @@ -44,7 +44,7 @@ describe('TestKeyStore', () => { // Arbitrary app contract address const appAddress = AztecAddress.fromBigInt(624n); - const appNullifierSecretKey = await keyStore.getAppNullifierSecretKey({ account: accountAddress }, appAddress); + const appNullifierSecretKey = await keyStore.getAppNullifierSecretKey(accountAddress, appAddress); expect(appNullifierSecretKey.toString()).toMatchInlineSnapshot( `"0x230a44dfe7cfec7a735c89f7289c5cb5d2c3dc0bf5d3505917fd2476f67873a8"`, ); diff --git a/yarn-project/key-store/src/test_key_store.ts b/yarn-project/key-store/src/test_key_store.ts index 13ce01a399b..17b8486d94c 100644 --- a/yarn-project/key-store/src/test_key_store.ts +++ b/yarn-project/key-store/src/test_key_store.ts @@ -89,16 +89,13 @@ export class TestKeyStore implements KeyStore { * @param account or master nullifier public key hash - The account address or master nullifier public key hash for which to retrieve the master nullifier public key. * @returns The master nullifier public key for the account. */ - public async getMasterNullifierPublicKey(args: { account: AztecAddress } | { npkMHash: Fr }): Promise { - const masterNullifierPublicKeyBuffer = - 'account' in args - ? this.#keys.get(`${args.account.toString()}-npk_m`) - : this.#keys.get(`${this.#getAccountAddressForMasterNullifierPublicKeyHash(args.npkMHash)?.toString()}-npk_m`); + public async getMasterNullifierPublicKey(accountOrNpkMHash: AztecAddress | Fr): Promise { + const masterNullifierPublicKeyBuffer = this.#keys.get(`${accountOrNpkMHash.toString()}-npk_m`) ?? + this.#keys.get(`${this.#getAccountAddressForMasterNullifierPublicKeyHash(accountOrNpkMHash)?.toString()}-npk_m`); + if (!masterNullifierPublicKeyBuffer) { throw new Error( - `${ - 'account' in args ? `Account ${args.account}` : `Master nullifier public key hash ${args.npkMHash}` - } does not exist. Registered accounts: ${await this.getAccounts()}.`, + `Account or master nullifier public key hash ${accountOrNpkMHash} does not exist. Registered accounts: ${await this.getAccounts()}.`, ); } return Promise.resolve(Point.fromBuffer(masterNullifierPublicKeyBuffer)); @@ -160,18 +157,15 @@ export class TestKeyStore implements KeyStore { * @returns A Promise that resolves to the application nullifier secret key. */ public async getAppNullifierSecretKey( - args: { account: AztecAddress } | { npkMHash: Fr }, + accountOrNpkMHash: AztecAddress | Fr, app: AztecAddress, ): Promise { - const masterNullifierSecretKeyBuffer = - 'account' in args - ? this.#keys.get(`${args.account.toString()}-nsk_m`) - : this.#keys.get(`${this.#getAccountAddressForMasterNullifierPublicKeyHash(args.npkMHash)?.toString()}-nsk_m`); + const masterNullifierSecretKeyBuffer = this.#keys.get(`${accountOrNpkMHash.toString()}-nsk_m`) ?? + this.#keys.get(`${this.#getAccountAddressForMasterNullifierPublicKeyHash(accountOrNpkMHash)?.toString()}-nsk_m`); + if (!masterNullifierSecretKeyBuffer) { throw new Error( - `${ - 'account' in args ? `Account ${args.account}` : `Master nullifier public key hash ${args.npkMHash}` - } does not exist. Registered accounts: ${await this.getAccounts()}.`, + `Account or master nullifier public key hash ${accountOrNpkMHash} does not exist. Registered accounts: ${await this.getAccounts()}.`, ); } const masterNullifierSecretKey = GrumpkinScalar.fromBuffer(masterNullifierSecretKeyBuffer); diff --git a/yarn-project/pxe/src/database/kv_pxe_database.ts b/yarn-project/pxe/src/database/kv_pxe_database.ts index 408030b214d..07a116bfe1c 100644 --- a/yarn-project/pxe/src/database/kv_pxe_database.ts +++ b/yarn-project/pxe/src/database/kv_pxe_database.ts @@ -386,9 +386,8 @@ export class KVPxeDatabase implements PxeDatabase { return value ? CompleteAddress.fromBuffer(value) : undefined; } - getCompleteAddress(args: { account: AztecAddress } | { npkMHash: Fr }): Promise { - return Promise.resolve( - 'account' in args ? this.#getCompleteAddress(args.account) : this.#getCompleteAddressWithNpkMHash(args.npkMHash), + getCompleteAddress(accountOrNpkMHash: AztecAddress | Fr): Promise { + return Promise.resolve(this.#getCompleteAddress(accountOrNpkMHash) ?? this.#getCompleteAddressWithNpkMHash(accountOrNpkMHash), ); } diff --git a/yarn-project/pxe/src/database/pxe_database.ts b/yarn-project/pxe/src/database/pxe_database.ts index 8de09765e88..b39fa385a8c 100644 --- a/yarn-project/pxe/src/database/pxe_database.ts +++ b/yarn-project/pxe/src/database/pxe_database.ts @@ -134,10 +134,10 @@ export interface PxeDatabase extends ContractArtifactDatabase, ContractInstanceD /** * Retrieve the complete address associated to a given address or master nullifier public key hash. - * @param args - contains account - the address or npkMHash - the master nullifier public key hash + * @param accountOrNpkMHash - account - the address or npkMHash - the master nullifier public key hash * @returns A promise that resolves to a CompleteAddress instance if found, or undefined if not found. */ - getCompleteAddress(args: { account: AztecAddress } | { npkMHash: Fr }): Promise; + getCompleteAddress(accountOrNpkMHash: AztecAddress | Fr): Promise; /** * Retrieves the list of complete address added to this database diff --git a/yarn-project/pxe/src/database/pxe_database_test_suite.ts b/yarn-project/pxe/src/database/pxe_database_test_suite.ts index f4976faaa8e..df865b2b2ba 100644 --- a/yarn-project/pxe/src/database/pxe_database_test_suite.ts +++ b/yarn-project/pxe/src/database/pxe_database_test_suite.ts @@ -215,7 +215,7 @@ export function describePxeDatabase(getDatabase: () => PxeDatabase) { it('stores and retrieves addresses', async () => { const address = CompleteAddress.random(); await expect(database.addCompleteAddress(address)).resolves.toBe(true); - await expect(database.getCompleteAddress({ account: address.address })).resolves.toEqual(address); + await expect(database.getCompleteAddress(address.address)).resolves.toEqual(address); }); it('silently ignores an address it already knows about', async () => { @@ -251,7 +251,7 @@ export function describePxeDatabase(getDatabase: () => PxeDatabase) { }); it("returns undefined if it doesn't have an address", async () => { - expect(await database.getCompleteAddress({ account: CompleteAddress.random().address })).toBeUndefined(); + expect(await database.getCompleteAddress(CompleteAddress.random().address)).toBeUndefined(); }); }); diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index 3475d1dc983..575a8019fff 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -301,7 +301,7 @@ export class PXEService implements PXE { } public async addNote(note: ExtendedNote) { - const owner = await this.db.getCompleteAddress({ account: note.owner }); + const owner = await this.db.getCompleteAddress(note.owner); if (!owner) { throw new Error(`Unknown account: ${note.owner.toString()}`); } diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index ee4fc90be3f..66c0faac41e 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -38,21 +38,20 @@ export class SimulatorOracle implements DBOracle { ) {} async getNullifierKeys( - args: { account: AztecAddress } | { npkMHash: Fr }, + accountOrNpkMHash: AztecAddress | Fr, contractAddress: AztecAddress, ): Promise { - const masterNullifierPublicKey = await this.keyStore.getMasterNullifierPublicKey(args); - const appNullifierSecretKey = await this.keyStore.getAppNullifierSecretKey(args, contractAddress); + const masterNullifierPublicKey = await this.keyStore.getMasterNullifierPublicKey(accountOrNpkMHash); + const appNullifierSecretKey = await this.keyStore.getAppNullifierSecretKey(accountOrNpkMHash, contractAddress); return { masterNullifierPublicKey, appNullifierSecretKey }; } - async getCompleteAddress(args: { account: AztecAddress } | { npkMHash: Fr }): Promise { - const completeAddress = await this.db.getCompleteAddress(args); + async getCompleteAddress(accountOrNpkMHash: AztecAddress | Fr): Promise { + const completeAddress = await this.db.getCompleteAddress(accountOrNpkMHash); if (!completeAddress) { throw new Error( - `No public key registered for ${ - 'account' in args ? `address ${args.account}` : `master nullifier public key hash ${args.npkMHash}` - }. Register it by calling pxe.registerRecipient(...) or pxe.registerAccount(...).\nSee docs for context: https://docs.aztec.network/developers/debugging/aztecnr-errors#simulation-error-No-public-key-registered-for-address-0x0-Register-it-by-calling-pxeregisterRecipient-or-pxeregisterAccount`, + `No public key registered for address or master nullifier public key hash ${accountOrNpkMHash}. + Register it by calling pxe.registerRecipient(...) or pxe.registerAccount(...).\nSee docs for context: https://docs.aztec.network/developers/debugging/aztecnr-errors#simulation-error-No-public-key-registered-for-address-0x0-Register-it-by-calling-pxeregisterRecipient-or-pxeregisterAccount`, ); } return completeAddress; diff --git a/yarn-project/pxe/src/synchronizer/synchronizer.ts b/yarn-project/pxe/src/synchronizer/synchronizer.ts index 1ced609d3f6..527fe3d9a47 100644 --- a/yarn-project/pxe/src/synchronizer/synchronizer.ts +++ b/yarn-project/pxe/src/synchronizer/synchronizer.ts @@ -281,7 +281,7 @@ export class Synchronizer { * @throws If checking a sync status of account which is not registered. */ public async isAccountStateSynchronized(account: AztecAddress) { - const completeAddress = await this.db.getCompleteAddress({ account }); + const completeAddress = await this.db.getCompleteAddress(account); if (!completeAddress) { throw new Error(`Checking if account is synched is not possible for ${account} because it is not registered.`); } diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index 09b87d9a55c..fd568d1e003 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -43,9 +43,7 @@ export class Oracle { } async getNullifierKeys([accountAddress]: ACVMField[]): Promise { - const { masterNullifierPublicKey, appNullifierSecretKey } = await this.typedOracle.getNullifierKeys({ - account: fromACVMField(accountAddress), - }); + const { masterNullifierPublicKey, appNullifierSecretKey } = await this.typedOracle.getNullifierKeys(fromACVMField(accountAddress)); return [ toACVMField(masterNullifierPublicKey.x), toACVMField(masterNullifierPublicKey.y), @@ -55,9 +53,7 @@ export class Oracle { // Keeping this oracle separate from above because I don't want an implicit overload in noir code async getNullifierKeysWithNpkMHash([masterNullifierPublicKeyHash]: ACVMField[]): Promise { - const { masterNullifierPublicKey, appNullifierSecretKey } = await this.typedOracle.getNullifierKeys({ - npkMHash: fromACVMField(masterNullifierPublicKeyHash), - }); + const { masterNullifierPublicKey, appNullifierSecretKey } = await this.typedOracle.getNullifierKeys(fromACVMField(masterNullifierPublicKeyHash)); return [ toACVMField(masterNullifierPublicKey.x), @@ -179,9 +175,7 @@ export class Oracle { async getPublicKeysAndPartialAddress([address]: ACVMField[]): Promise { const parsedAddress = AztecAddress.fromField(fromACVMField(address)); - const { publicKeys, partialAddress } = await this.typedOracle.getCompleteAddress({ - account: parsedAddress, - }); + const { publicKeys, partialAddress } = await this.typedOracle.getCompleteAddress(parsedAddress); return [...publicKeys.toFields(), partialAddress].map(toACVMField); } @@ -189,9 +183,7 @@ export class Oracle { // Keeping this oracle separate from above because I don't want an implicit overload in noir code async getPublicKeysAndPartialAddressWithNpkMHash([masterNullifierPublicKeyHash]: ACVMField[]) { const parsedNpkMHash = fromACVMField(masterNullifierPublicKeyHash); - const { publicKeys, partialAddress } = await this.typedOracle.getCompleteAddress({ - npkMHash: parsedNpkMHash, - }); + const { publicKeys, partialAddress } = await this.typedOracle.getCompleteAddress(parsedNpkMHash); return [...publicKeys.toFields(), partialAddress].map(toACVMField); } diff --git a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts index 5b050be24ab..13f4ca59500 100644 --- a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts @@ -89,7 +89,7 @@ export abstract class TypedOracle { throw new OracleMethodNotAvailableError('unpackReturns'); } - getNullifierKeys(_args: { account: AztecAddress } | { npkMHash: Fr }): Promise { + getNullifierKeys(_accountOrNpkMHash: AztecAddress | Fr): Promise { throw new OracleMethodNotAvailableError('getNullifierKeys'); } @@ -124,7 +124,7 @@ export abstract class TypedOracle { throw new OracleMethodNotAvailableError('getHeader'); } - getCompleteAddress(_args: { account: AztecAddress } | { npkMHash: Fr }): Promise { + getCompleteAddress(_accountOrNpkMHash: AztecAddress | Fr): Promise { throw new OracleMethodNotAvailableError('getCompleteAddress'); } diff --git a/yarn-project/simulator/src/client/db_oracle.ts b/yarn-project/simulator/src/client/db_oracle.ts index 9b9e3f91743..7b702e85ca6 100644 --- a/yarn-project/simulator/src/client/db_oracle.ts +++ b/yarn-project/simulator/src/client/db_oracle.ts @@ -45,11 +45,11 @@ export interface DBOracle extends CommitmentsDB { /** * Retrieve the complete address associated to a given address or master nullifier public key hash. - * @param args - contains account - the address or npkMHash - the master nullifier public key hash + * @param accountOrNpkMHash - account - the address or npkMHash - the master nullifier public key hash * @returns A complete address associated with the input address or master nullifier public key hash * @throws An error if the account is not registered in the database. */ - getCompleteAddress(args: { account: AztecAddress } | { npkMHash: Fr }): Promise; + getCompleteAddress(accountOrNpkMHash: AztecAddress | Fr): Promise; /** * Retrieve the auth witness for a given message hash. @@ -67,12 +67,12 @@ export interface DBOracle extends CommitmentsDB { /** * Retrieve nullifier keys associated with a (specific account or master nullifier key hash) and app/contract address. - * @param args - contains account - the address or npkMHash - the master nullifier public key hash + * @param accountOrNpkMHash - account - the address or npkMHash - the master nullifier public key hash * @returns A Promise that resolves to nullifier keys of a (requested account or master nullifier key hash) and contract. * @throws An error if the nullifier keys associated to account or master nullifier public key hash is not registered in the key store. */ getNullifierKeys( - args: { account: AztecAddress } | { npkMHash: Fr }, + accountOrNpkMHash: AztecAddress | Fr, contractAddress: AztecAddress, ): Promise; diff --git a/yarn-project/simulator/src/client/private_execution.test.ts b/yarn-project/simulator/src/client/private_execution.test.ts index 464858d6b22..25b21cb887e 100644 --- a/yarn-project/simulator/src/client/private_execution.test.ts +++ b/yarn-project/simulator/src/client/private_execution.test.ts @@ -191,20 +191,20 @@ describe('Private Execution test suite', () => { trees = {}; oracle = mock(); oracle.getNullifierKeys.mockImplementation( - (args: { account: AztecAddress } | { npkMHash: Fr }, contractAddress: AztecAddress) => { - if ('account' in args && args.account.equals(ownerCompleteAddress.address)) { + (accountOrNpkMHash: AztecAddress | Fr, contractAddress: AztecAddress) => { + if (accountOrNpkMHash.equals(ownerCompleteAddress.address)) { return Promise.resolve({ masterNullifierPublicKey: ownerCompleteAddress.publicKeys.masterNullifierPublicKey, appNullifierSecretKey: computeAppNullifierSecretKey(ownerMasterNullifierSecretKey, contractAddress), }); } - if ('account' in args && args.account.equals(recipientCompleteAddress.address)) { + if (accountOrNpkMHash.equals(recipientCompleteAddress.address)) { return Promise.resolve({ masterNullifierPublicKey: recipientCompleteAddress.publicKeys.masterNullifierPublicKey, appNullifierSecretKey: computeAppNullifierSecretKey(recipientMasterNullifierSecretKey, contractAddress), }); } - throw new Error(`Unknown ${'account' in args ? 'address' : 'npkMHash'}`); + throw new Error(`Unknown address ${accountOrNpkMHash}`); }, ); @@ -213,14 +213,14 @@ describe('Private Execution test suite', () => { await insertLeaves([], 'publicData'); oracle.getHeader.mockResolvedValue(header); - oracle.getCompleteAddress.mockImplementation((args: { account: AztecAddress } | { npkMHash: Fr }) => { - if ('account' in args && args.account.equals(owner)) { + oracle.getCompleteAddress.mockImplementation((accountOrNpkMHash: AztecAddress | Fr) => { + if (accountOrNpkMHash.equals(owner)) { return Promise.resolve(ownerCompleteAddress); } - if ('account' in args && args.account.equals(recipient)) { + if (accountOrNpkMHash.equals(recipient)) { return Promise.resolve(recipientCompleteAddress); } - throw new Error(`Unknown ${'account' in args ? 'address' : 'npkMHash'}`); + throw new Error(`Unknown address ${accountOrNpkMHash}`); }); // 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 diff --git a/yarn-project/simulator/src/client/unconstrained_execution.test.ts b/yarn-project/simulator/src/client/unconstrained_execution.test.ts index 871949ed2e7..3d1b69cb0ca 100644 --- a/yarn-project/simulator/src/client/unconstrained_execution.test.ts +++ b/yarn-project/simulator/src/client/unconstrained_execution.test.ts @@ -33,11 +33,11 @@ describe('Unconstrained Execution test suite', () => { const ownerCompleteAddress = CompleteAddress.fromSecretKeyAndPartialAddress(ownerSecretKey, Fr.random()); owner = ownerCompleteAddress.address; - oracle.getCompleteAddress.mockImplementation((args: { account: AztecAddress } | { npkMHash: Fr }) => { - if ('account' in args && args.account.equals(owner)) { + oracle.getCompleteAddress.mockImplementation((accountOrNpkMHash: AztecAddress | Fr) => { + if (accountOrNpkMHash.equals(owner)) { return Promise.resolve(ownerCompleteAddress); } - throw new Error(`Unknown ${'account' in args ? 'address' : 'npkMHash'}`); + throw new Error(`Unknown address ${accountOrNpkMHash}`); }); }); diff --git a/yarn-project/simulator/src/client/view_data_oracle.ts b/yarn-project/simulator/src/client/view_data_oracle.ts index 298d75406b2..d0b959c0fbf 100644 --- a/yarn-project/simulator/src/client/view_data_oracle.ts +++ b/yarn-project/simulator/src/client/view_data_oracle.ts @@ -36,12 +36,12 @@ export class ViewDataOracle extends TypedOracle { /** * Retrieve nullifier keys associated with a (specific account or master nullifier key hash) and app/contract address. - * @param args - contains account - the address or npkMHash - the master nullifier public key hash + * @param accountOrNpkMHash - account - the address or npkMHash - the master nullifier public key hash * @returns A Promise that resolves to nullifier keys of a (requested account or master nullifier key hash) and contract. * @throws An error if the nullifier keys associated to account or master nullifier public key hash is not registered in the key store. */ - public override getNullifierKeys(args: { account: AztecAddress } | { npkMHash: Fr }): Promise { - return this.db.getNullifierKeys(args, this.contractAddress); + public override getNullifierKeys(accountOrNpkMHash: AztecAddress | Fr): Promise { + return this.db.getNullifierKeys(accountOrNpkMHash, this.contractAddress); } /** @@ -128,12 +128,12 @@ export class ViewDataOracle extends TypedOracle { /** * Retrieve the complete address associated to a given address or master nullifier public key hash. - * @param args - contains account - the address or npkMHash - the master nullifier public key hash + * @param accountOrNpkMHash - account - the address or npkMHash - the master nullifier public key hash * @returns A complete address associated with the input address or master nullifier public key hash * @throws An error if the account is not registered in the database. */ - public override getCompleteAddress(args: { account: AztecAddress } | { npkMHash: Fr }): Promise { - return this.db.getCompleteAddress(args); + public override getCompleteAddress(accountOrNpkMHash: AztecAddress | Fr): Promise { + return this.db.getCompleteAddress(accountOrNpkMHash); } /** From fee5a59f1a6bc50b4a7458764c3d9d79406dbc63 Mon Sep 17 00:00:00 2001 From: esau <152162806+sklppy88@users.noreply.github.com> Date: Tue, 14 May 2024 05:54:34 -0500 Subject: [PATCH 90/93] Apply suggestions from Jan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jan Beneš --- noir-projects/aztec-nr/aztec/src/context/private_context.nr | 2 +- noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr | 4 ++-- yarn-project/key-store/src/test_key_store.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index 1b286894f3a..ced5e581804 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -221,7 +221,7 @@ impl PrivateContext { keys.app_nullifier_secret_key } - // TODO: (#6176) Replace request_app_nullifier_secret_key above with this once we no longer get app nullifier secret key with address + // TODO(#5630) Replace request_app_nullifier_secret_key above with this once we no longer get app nullifier secret key with address pub fn request_nsk_app_with_npk_m_hash(&mut self, npk_m_hash: Field) -> Field { let keys = if self.nullifier_key.is_none() { let keys = get_nullifier_keys_with_npk_m_hash(npk_m_hash); diff --git a/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr b/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr index 469b4ff6cc3..c15e36bc6db 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr @@ -2,7 +2,7 @@ use dep::protocol_types::{address::AztecAddress, grumpkin_point::GrumpkinPoint, // Nullifier keys pertaining to a specific account struct NullifierKeys { - // TODO (#6176): Replace get_nullifier_keys above with this once we no longer get nullifier keys with address + // TODO(#5630): Replace get_nullifier_keys above with this once we no longer get nullifier keys with address account: AztecAddress, master_nullifier_public_key: GrumpkinPoint, app_nullifier_secret_key: Field, @@ -28,7 +28,7 @@ pub fn get_app_nullifier_secret_key(account: AztecAddress) -> Field { get_nullifier_keys_internal(account).app_nullifier_secret_key } -// TODO (#6176): Replace get_nullifier_keys above with this once we no longer get nullifier keys with address +// TODO(#5630): Replace get_nullifier_keys above with this once we no longer get nullifier keys with address #[oracle(getNullifierKeysWithNpkMHash)] fn get_nullifier_keys_with_npk_m_hash_oracle(_npk_m_hash: Field) -> [Field; 3] {} diff --git a/yarn-project/key-store/src/test_key_store.ts b/yarn-project/key-store/src/test_key_store.ts index 17b8486d94c..da66925b30e 100644 --- a/yarn-project/key-store/src/test_key_store.ts +++ b/yarn-project/key-store/src/test_key_store.ts @@ -57,7 +57,7 @@ export class TestKeyStore implements KeyStore { // We save the keys to db associated with the account address await this.#keys.set(`${accountAddress.toString()}-public_keys_hash`, publicKeysHash.toBuffer()); - // Naming of keys is as follows ${from}-${to}_${any modifiers (m = master, h = hash)} + // Naming of keys is as follows ${from}-${to}_m await this.#keys.set(`${accountAddress.toString()}-nsk_m`, masterNullifierSecretKey.toBuffer()); await this.#keys.set(`${accountAddress.toString()}-ivsk_m`, masterIncomingViewingSecretKey.toBuffer()); await this.#keys.set(`${accountAddress.toString()}-ovsk_m`, masterOutgoingViewingSecretKey.toBuffer()); From 071e7c41b3aad12c08cc3b7d1b1acac79b70a84a Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Tue, 14 May 2024 11:39:34 +0000 Subject: [PATCH 91/93] format --- .../circuit-types/src/keys/key_store.ts | 4 ++-- yarn-project/key-store/src/test_key_store.ts | 17 ++++++++--------- .../pxe/src/database/kv_pxe_database.ts | 3 ++- yarn-project/pxe/src/simulator_oracle/index.ts | 5 +---- .../simulator/src/acvm/oracle/oracle.ts | 8 ++++++-- yarn-project/simulator/src/client/db_oracle.ts | 5 +---- 6 files changed, 20 insertions(+), 22 deletions(-) diff --git a/yarn-project/circuit-types/src/keys/key_store.ts b/yarn-project/circuit-types/src/keys/key_store.ts index 9d42da54332..db0da3f21ec 100644 --- a/yarn-project/circuit-types/src/keys/key_store.ts +++ b/yarn-project/circuit-types/src/keys/key_store.ts @@ -34,7 +34,7 @@ export interface KeyStore { /** * Gets the master nullifier public key for a given account or master nullifier public key hash. * @throws If the account does not exist in the key store. - * @param account or master nullifier public key hash - The account address or master nullifier public key hash for which to retrieve the master nullifier public key. + * @param accountOrNpkMHash - account - the address or npkMHash - the master nullifier public key hash * @returns The master nullifier public key for the account. */ getMasterNullifierPublicKey(accountOrNpkMHash: AztecAddress | Fr): Promise; @@ -66,7 +66,7 @@ export interface KeyStore { /** * Derives and returns the application nullifier secret key for a given account or master nullifier public key hash. * @throws If the account does not exist in the key store. - * @param account or master nullifier public key hash - The account address or master nullifier public key hash for which to retrieve the application nullifier secret key. + * @param accountOrNpkMHash - account - the address or npkMHash - the master nullifier public key hash * @param app - The application address to retrieve the nullifier secret key for. * @returns A Promise that resolves to the application nullifier secret key. */ diff --git a/yarn-project/key-store/src/test_key_store.ts b/yarn-project/key-store/src/test_key_store.ts index da66925b30e..f5f417da192 100644 --- a/yarn-project/key-store/src/test_key_store.ts +++ b/yarn-project/key-store/src/test_key_store.ts @@ -86,12 +86,13 @@ export class TestKeyStore implements KeyStore { /** * Gets the master nullifier public key for a given account or master nullifier public key hash. * @throws If the account does not exist in the key store. - * @param account or master nullifier public key hash - The account address or master nullifier public key hash for which to retrieve the master nullifier public key. + * @param accountOrNpkMHash - account - the address or npkMHash - the master nullifier public key hash * @returns The master nullifier public key for the account. */ public async getMasterNullifierPublicKey(accountOrNpkMHash: AztecAddress | Fr): Promise { - const masterNullifierPublicKeyBuffer = this.#keys.get(`${accountOrNpkMHash.toString()}-npk_m`) ?? - this.#keys.get(`${this.#getAccountAddressForMasterNullifierPublicKeyHash(accountOrNpkMHash)?.toString()}-npk_m`); + const masterNullifierPublicKeyBuffer = + this.#keys.get(`${accountOrNpkMHash.toString()}-npk_m`) ?? + this.#keys.get(`${this.#getAccountAddressForMasterNullifierPublicKeyHash(accountOrNpkMHash)?.toString()}-npk_m`); if (!masterNullifierPublicKeyBuffer) { throw new Error( @@ -152,15 +153,13 @@ export class TestKeyStore implements KeyStore { /** * Derives and returns the application nullifier secret key for a given account or master nullifier public key hash. * @throws If the account does not exist in the key store. - * @param account or master nullifier public key hash - The account address or master nullifier public key hash for which to retrieve the application nullifier secret key. + * @param accountOrNpkMHash - account - the address or npkMHash - the master nullifier public key hash * @param app - The application address to retrieve the nullifier secret key for. * @returns A Promise that resolves to the application nullifier secret key. */ - public async getAppNullifierSecretKey( - accountOrNpkMHash: AztecAddress | Fr, - app: AztecAddress, - ): Promise { - const masterNullifierSecretKeyBuffer = this.#keys.get(`${accountOrNpkMHash.toString()}-nsk_m`) ?? + public async getAppNullifierSecretKey(accountOrNpkMHash: AztecAddress | Fr, app: AztecAddress): Promise { + const masterNullifierSecretKeyBuffer = + this.#keys.get(`${accountOrNpkMHash.toString()}-nsk_m`) ?? this.#keys.get(`${this.#getAccountAddressForMasterNullifierPublicKeyHash(accountOrNpkMHash)?.toString()}-nsk_m`); if (!masterNullifierSecretKeyBuffer) { diff --git a/yarn-project/pxe/src/database/kv_pxe_database.ts b/yarn-project/pxe/src/database/kv_pxe_database.ts index 07a116bfe1c..2de3eaff5b2 100644 --- a/yarn-project/pxe/src/database/kv_pxe_database.ts +++ b/yarn-project/pxe/src/database/kv_pxe_database.ts @@ -387,7 +387,8 @@ export class KVPxeDatabase implements PxeDatabase { } getCompleteAddress(accountOrNpkMHash: AztecAddress | Fr): Promise { - return Promise.resolve(this.#getCompleteAddress(accountOrNpkMHash) ?? this.#getCompleteAddressWithNpkMHash(accountOrNpkMHash), + return Promise.resolve( + this.#getCompleteAddress(accountOrNpkMHash) ?? this.#getCompleteAddressWithNpkMHash(accountOrNpkMHash), ); } diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index 66c0faac41e..e598a1c49e9 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -37,10 +37,7 @@ export class SimulatorOracle implements DBOracle { private log = createDebugLogger('aztec:pxe:simulator_oracle'), ) {} - async getNullifierKeys( - accountOrNpkMHash: AztecAddress | Fr, - contractAddress: AztecAddress, - ): Promise { + async getNullifierKeys(accountOrNpkMHash: AztecAddress | Fr, contractAddress: AztecAddress): Promise { const masterNullifierPublicKey = await this.keyStore.getMasterNullifierPublicKey(accountOrNpkMHash); const appNullifierSecretKey = await this.keyStore.getAppNullifierSecretKey(accountOrNpkMHash, contractAddress); return { masterNullifierPublicKey, appNullifierSecretKey }; diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index fd568d1e003..d57338e2592 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -43,7 +43,9 @@ export class Oracle { } async getNullifierKeys([accountAddress]: ACVMField[]): Promise { - const { masterNullifierPublicKey, appNullifierSecretKey } = await this.typedOracle.getNullifierKeys(fromACVMField(accountAddress)); + const { masterNullifierPublicKey, appNullifierSecretKey } = await this.typedOracle.getNullifierKeys( + fromACVMField(accountAddress), + ); return [ toACVMField(masterNullifierPublicKey.x), toACVMField(masterNullifierPublicKey.y), @@ -53,7 +55,9 @@ export class Oracle { // Keeping this oracle separate from above because I don't want an implicit overload in noir code async getNullifierKeysWithNpkMHash([masterNullifierPublicKeyHash]: ACVMField[]): Promise { - const { masterNullifierPublicKey, appNullifierSecretKey } = await this.typedOracle.getNullifierKeys(fromACVMField(masterNullifierPublicKeyHash)); + const { masterNullifierPublicKey, appNullifierSecretKey } = await this.typedOracle.getNullifierKeys( + fromACVMField(masterNullifierPublicKeyHash), + ); return [ toACVMField(masterNullifierPublicKey.x), diff --git a/yarn-project/simulator/src/client/db_oracle.ts b/yarn-project/simulator/src/client/db_oracle.ts index 7b702e85ca6..1588e3e7f45 100644 --- a/yarn-project/simulator/src/client/db_oracle.ts +++ b/yarn-project/simulator/src/client/db_oracle.ts @@ -71,10 +71,7 @@ export interface DBOracle extends CommitmentsDB { * @returns A Promise that resolves to nullifier keys of a (requested account or master nullifier key hash) and contract. * @throws An error if the nullifier keys associated to account or master nullifier public key hash is not registered in the key store. */ - getNullifierKeys( - accountOrNpkMHash: AztecAddress | Fr, - contractAddress: AztecAddress, - ): Promise; + getNullifierKeys(accountOrNpkMHash: AztecAddress | Fr, contractAddress: AztecAddress): Promise; /** * Retrieves a set of notes stored in the database for a given contract address and storage slot. From 34eb010312009d4ae6bc8609edc0aee7ef1cf03c Mon Sep 17 00:00:00 2001 From: Esau Date: Tue, 14 May 2024 14:56:56 +0200 Subject: [PATCH 92/93] bump timeout --- yarn-project/end-to-end/src/benchmarks/bench_proving.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn-project/end-to-end/src/benchmarks/bench_proving.test.ts b/yarn-project/end-to-end/src/benchmarks/bench_proving.test.ts index 954c88c2653..52f1d2f8826 100644 --- a/yarn-project/end-to-end/src/benchmarks/bench_proving.test.ts +++ b/yarn-project/end-to-end/src/benchmarks/bench_proving.test.ts @@ -120,5 +120,5 @@ describe('benchmarks/proving', () => { const receipts = await Promise.all(txs.map(tx => tx.wait({ timeout: txTimeoutSec }))); expect(receipts.every(r => r.status === TxStatus.MINED)).toBe(true); - }); + }, 1_200_000); }); From 880fb54dbdea86764090bb042e8635ff3933a804 Mon Sep 17 00:00:00 2001 From: benesjan Date: Wed, 15 May 2024 08:17:49 +0000 Subject: [PATCH 93/93] more concise wording --- yarn-project/circuit-types/src/keys/key_store.ts | 4 ++-- yarn-project/key-store/src/test_key_store.ts | 4 ++-- yarn-project/p2p/package.json | 2 +- yarn-project/pxe/src/database/pxe_database.ts | 2 +- yarn-project/simulator/src/client/db_oracle.ts | 10 +++++----- yarn-project/simulator/src/client/view_data_oracle.ts | 10 +++++----- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/yarn-project/circuit-types/src/keys/key_store.ts b/yarn-project/circuit-types/src/keys/key_store.ts index db0da3f21ec..256db6e36a9 100644 --- a/yarn-project/circuit-types/src/keys/key_store.ts +++ b/yarn-project/circuit-types/src/keys/key_store.ts @@ -34,7 +34,7 @@ export interface KeyStore { /** * Gets the master nullifier public key for a given account or master nullifier public key hash. * @throws If the account does not exist in the key store. - * @param accountOrNpkMHash - account - the address or npkMHash - the master nullifier public key hash + * @param accountOrNpkMHash - account address or master nullifier public key hash. * @returns The master nullifier public key for the account. */ getMasterNullifierPublicKey(accountOrNpkMHash: AztecAddress | Fr): Promise; @@ -66,7 +66,7 @@ export interface KeyStore { /** * Derives and returns the application nullifier secret key for a given account or master nullifier public key hash. * @throws If the account does not exist in the key store. - * @param accountOrNpkMHash - account - the address or npkMHash - the master nullifier public key hash + * @param accountOrNpkMHash - account address or master nullifier public key hash. * @param app - The application address to retrieve the nullifier secret key for. * @returns A Promise that resolves to the application nullifier secret key. */ diff --git a/yarn-project/key-store/src/test_key_store.ts b/yarn-project/key-store/src/test_key_store.ts index f5f417da192..2d0e0672104 100644 --- a/yarn-project/key-store/src/test_key_store.ts +++ b/yarn-project/key-store/src/test_key_store.ts @@ -86,7 +86,7 @@ export class TestKeyStore implements KeyStore { /** * Gets the master nullifier public key for a given account or master nullifier public key hash. * @throws If the account does not exist in the key store. - * @param accountOrNpkMHash - account - the address or npkMHash - the master nullifier public key hash + * @param accountOrNpkMHash - account address or master nullifier public key hash. * @returns The master nullifier public key for the account. */ public async getMasterNullifierPublicKey(accountOrNpkMHash: AztecAddress | Fr): Promise { @@ -153,7 +153,7 @@ export class TestKeyStore implements KeyStore { /** * Derives and returns the application nullifier secret key for a given account or master nullifier public key hash. * @throws If the account does not exist in the key store. - * @param accountOrNpkMHash - account - the address or npkMHash - the master nullifier public key hash + * @param accountOrNpkMHash - account address or master nullifier public key hash. * @param app - The application address to retrieve the nullifier secret key for. * @returns A Promise that resolves to the application nullifier secret key. */ diff --git a/yarn-project/p2p/package.json b/yarn-project/p2p/package.json index f7ad5cd7120..0cc79a46b28 100644 --- a/yarn-project/p2p/package.json +++ b/yarn-project/p2p/package.json @@ -97,4 +97,4 @@ "engines": { "node": ">=18" } -} \ No newline at end of file +} diff --git a/yarn-project/pxe/src/database/pxe_database.ts b/yarn-project/pxe/src/database/pxe_database.ts index b39fa385a8c..13c930b2b92 100644 --- a/yarn-project/pxe/src/database/pxe_database.ts +++ b/yarn-project/pxe/src/database/pxe_database.ts @@ -134,7 +134,7 @@ export interface PxeDatabase extends ContractArtifactDatabase, ContractInstanceD /** * Retrieve the complete address associated to a given address or master nullifier public key hash. - * @param accountOrNpkMHash - account - the address or npkMHash - the master nullifier public key hash + * @param accountOrNpkMHash - account address or master nullifier public key hash. * @returns A promise that resolves to a CompleteAddress instance if found, or undefined if not found. */ getCompleteAddress(accountOrNpkMHash: AztecAddress | Fr): Promise; diff --git a/yarn-project/simulator/src/client/db_oracle.ts b/yarn-project/simulator/src/client/db_oracle.ts index 1588e3e7f45..13bc8a9c7d4 100644 --- a/yarn-project/simulator/src/client/db_oracle.ts +++ b/yarn-project/simulator/src/client/db_oracle.ts @@ -45,7 +45,7 @@ export interface DBOracle extends CommitmentsDB { /** * Retrieve the complete address associated to a given address or master nullifier public key hash. - * @param accountOrNpkMHash - account - the address or npkMHash - the master nullifier public key hash + * @param accountOrNpkMHash - account address or master nullifier public key hash. * @returns A complete address associated with the input address or master nullifier public key hash * @throws An error if the account is not registered in the database. */ @@ -66,10 +66,10 @@ export interface DBOracle extends CommitmentsDB { popCapsule(): Promise; /** - * Retrieve nullifier keys associated with a (specific account or master nullifier key hash) and app/contract address. - * @param accountOrNpkMHash - account - the address or npkMHash - the master nullifier public key hash - * @returns A Promise that resolves to nullifier keys of a (requested account or master nullifier key hash) and contract. - * @throws An error if the nullifier keys associated to account or master nullifier public key hash is not registered in the key store. + * Retrieve nullifier keys associated with a specific account or master nullifier public key and app address. + * @param accountOrNpkMHash - account address or master nullifier public key hash. + * @returns A Promise that resolves to nullifier keys. + * @throws If the nullifier keys are not registered in the key store. */ getNullifierKeys(accountOrNpkMHash: AztecAddress | Fr, contractAddress: AztecAddress): Promise; diff --git a/yarn-project/simulator/src/client/view_data_oracle.ts b/yarn-project/simulator/src/client/view_data_oracle.ts index f056e764557..bca1a2b0697 100644 --- a/yarn-project/simulator/src/client/view_data_oracle.ts +++ b/yarn-project/simulator/src/client/view_data_oracle.ts @@ -35,10 +35,10 @@ export class ViewDataOracle extends TypedOracle { } /** - * Retrieve nullifier keys associated with a (specific account or master nullifier key hash) and app/contract address. - * @param accountOrNpkMHash - account - the address or npkMHash - the master nullifier public key hash - * @returns A Promise that resolves to nullifier keys of a (requested account or master nullifier key hash) and contract. - * @throws An error if the nullifier keys associated to account or master nullifier public key hash is not registered in the key store. + * Retrieve nullifier keys associated with a specific account or master nullifier public key and app address. + * @param accountOrNpkMHash - account address or master nullifier public key hash. + * @returns A Promise that resolves to nullifier keys. + * @throws If the nullifier keys are not registered in the key store. */ public override getNullifierKeys(accountOrNpkMHash: AztecAddress | Fr): Promise { return this.db.getNullifierKeys(accountOrNpkMHash, this.contractAddress); @@ -128,7 +128,7 @@ export class ViewDataOracle extends TypedOracle { /** * Retrieve the complete address associated to a given address or master nullifier public key hash. - * @param accountOrNpkMHash - account - the address or npkMHash - the master nullifier public key hash + * @param accountOrNpkMHash - account address or master nullifier public key hash. * @returns A complete address associated with the input address or master nullifier public key hash * @throws An error if the account is not registered in the database. */