diff --git a/docs/docs/misc/migration_notes.md b/docs/docs/misc/migration_notes.md index c792470b0b5c..1db96c0a21a8 100644 --- a/docs/docs/misc/migration_notes.md +++ b/docs/docs/misc/migration_notes.md @@ -6,9 +6,24 @@ 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] 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. +What used to be called encryption public key is now master incoming viewing public key. + +```diff +- use dep::aztec::oracles::get_public_key::get_public_key; ++ use dep::aztec::keys::getters::get_ivpk_m; + +- let encryption_pub_key = get_public_key(self.owner); ++ let ivpk_m = get_ivpk_m(context, self.owner); +``` + ## 0.38.0 -### [Aztec.nr] Emmiting encrypted logs +### [Aztec.nr] Emitting encrypted logs The `emit_encrypted_log` function is now a context method. diff --git a/noir-projects/aztec-nr/address-note/src/address_note.nr b/noir-projects/aztec-nr/address-note/src/address_note.nr index d784a0fb7e76..002c56de9348 100644 --- a/noir-projects/aztec-nr/address-note/src/address_note.nr +++ b/noir-projects/aztec-nr/address-note/src/address_note.nr @@ -1,7 +1,8 @@ use dep::aztec::{ + keys::getters::get_ivpk_m, protocol_types::{address::AztecAddress, traits::Empty, constants::GENERATOR_INDEX__NOTE_NULLIFIER}, note::{note_header::NoteHeader, note_interface::NoteInterface, utils::compute_note_hash_for_consumption}, - 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}, context::PrivateContext, hash::poseidon2_hash }; @@ -40,13 +41,13 @@ impl NoteInterface for AddressNote { // 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); + let ivpk_m = get_ivpk_m(context, self.owner); // docs:start:encrypted context.emit_encrypted_log( (*context).this_address(), slot, Self::get_note_type_id(), - encryption_pub_key, + ivpk_m, self.serialize_content(), ); // docs:end:encrypted 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 9d7010e3107a..8871cd762d6a 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -286,7 +286,7 @@ impl PrivateContext { contract_address: AztecAddress, storage_slot: Field, note_type_id: Field, - encryption_pub_key: GrumpkinPoint, + ivpk_m: GrumpkinPoint, preimage: [Field; N] ) where [Field; N]: LensForEncryptedLog { // TODO(1139): perform encryption in the circuit @@ -296,7 +296,7 @@ impl PrivateContext { contract_address, storage_slot, note_type_id, - encryption_pub_key, + ivpk_m, preimage, counter ); diff --git a/noir-projects/aztec-nr/aztec/src/encrypted_logs/body.nr b/noir-projects/aztec-nr/aztec/src/encrypted_logs/body.nr index 4393d9da16c5..9f490c768e05 100644 --- a/noir-projects/aztec-nr/aztec/src/encrypted_logs/body.nr +++ b/noir-projects/aztec-nr/aztec/src/encrypted_logs/body.nr @@ -67,7 +67,7 @@ mod test { use crate::{ note::{note_header::NoteHeader, note_interface::NoteInterface, utils::compute_note_hash_for_consumption}, - 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}, context::PrivateContext, hash::poseidon2_hash }; diff --git a/noir-projects/aztec-nr/aztec/src/oracle.nr b/noir-projects/aztec-nr/aztec/src/oracle.nr index 64c449d61f85..59031fcdb9f7 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle.nr @@ -10,7 +10,6 @@ mod get_l1_to_l2_membership_witness; 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; 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 deleted file mode 100644 index a509e8c1b54f..000000000000 --- a/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr +++ /dev/null @@ -1,20 +0,0 @@ -use dep::protocol_types::{address::{AztecAddress, PartialAddress, PublicKeysHash}, grumpkin_point::GrumpkinPoint}; - -#[oracle(getPublicKeyAndPartialAddress)] -fn get_public_key_and_partial_address_oracle(_address: AztecAddress) -> [Field; 3] {} - -unconstrained fn get_public_key_and_partial_address_internal(address: AztecAddress) -> [Field; 3] { - get_public_key_and_partial_address_oracle(address) -} - -pub fn get_public_key(address: AztecAddress) -> GrumpkinPoint { - let result = get_public_key_and_partial_address_internal(address); - 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/aztec-nr/aztec/src/oracle/keys.nr b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr index a985e385e811..173ad34aad2c 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr @@ -1,7 +1,5 @@ use dep::protocol_types::{address::{AztecAddress, PartialAddress}, grumpkin_point::GrumpkinPoint}; -use crate::hash::poseidon2_hash; - #[oracle(getPublicKeysAndPartialAddress)] fn get_public_keys_and_partial_address_oracle(_address: AztecAddress) -> [Field; 9] {} diff --git a/noir-projects/aztec-nr/aztec/src/oracle/logs.nr b/noir-projects/aztec-nr/aztec/src/oracle/logs.nr index d692329a82f5..a1d933915eed 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/logs.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/logs.nr @@ -17,7 +17,7 @@ unconstrained pub fn emit_encrypted_log( contract_address: AztecAddress, storage_slot: Field, note_type_id: Field, - encryption_pub_key: GrumpkinPoint, + ivpk_m: GrumpkinPoint, preimage: [Field; N], counter: u32 ) -> [Field; M] { @@ -25,7 +25,7 @@ unconstrained pub fn emit_encrypted_log( contract_address, storage_slot, note_type_id, - encryption_pub_key, + ivpk_m, preimage, counter ) diff --git a/noir-projects/aztec-nr/value-note/src/utils.nr b/noir-projects/aztec-nr/value-note/src/utils.nr index 5cb4b75b6c78..66f9b9983888 100644 --- a/noir-projects/aztec-nr/value-note/src/utils.nr +++ b/noir-projects/aztec-nr/value-note/src/utils.nr @@ -1,6 +1,6 @@ use dep::aztec::prelude::{AztecAddress, PrivateContext, PrivateSet, NoteGetterOptions}; use dep::aztec::note::note_getter_options::SortOrder; -use dep::aztec::oracle::get_public_key::get_public_key; +use dep::aztec::keys::getters::get_ivpk_m; use crate::{filter::filter_notes_min_sum, value_note::{ValueNote, VALUE_NOTE_LEN}}; // Sort the note values (0th field) in descending order. 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 019ea4bf543b..ac790864aa85 100644 --- a/noir-projects/aztec-nr/value-note/src/value_note.nr +++ b/noir-projects/aztec-nr/value-note/src/value_note.nr @@ -1,7 +1,8 @@ use dep::aztec::{ + keys::getters::get_ivpk_m, protocol_types::{address::AztecAddress, traits::{Deserialize, Serialize}, constants::GENERATOR_INDEX__NOTE_NULLIFIER}, note::{note_header::NoteHeader, note_interface::NoteInterface, utils::compute_note_hash_for_consumption}, - 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}, hash::poseidon2_hash, context::PrivateContext }; @@ -43,12 +44,12 @@ 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); + let ivpk_m = get_ivpk_m(context, self.owner); context.emit_encrypted_log( (*context).this_address(), slot, Self::get_note_type_id(), - encryption_pub_key, + ivpk_m, self.serialize_content(), ); } diff --git a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr index 2bf04c8628c9..3fa6b4d44368 100644 --- a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr @@ -12,7 +12,7 @@ contract AppSubscription { use dep::aztec::protocol_types::traits::is_empty; - use dep::aztec::{context::Context, oracle::get_public_key::get_public_key}; + use dep::aztec::{context::Context, keys::getters::get_ivpk_m}; use dep::authwit::{account::AccountActions, auth_witness::get_auth_witness, auth::assert_current_call_valid_authwit}; use crate::subscription_note::{SubscriptionNote, SUBSCRIPTION_NOTE_LEN}; 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 c2543a14707f..665393b166fe 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 @@ -1,8 +1,8 @@ use dep::aztec::prelude::{AztecAddress, PrivateContext, NoteHeader, NoteInterface}; use dep::aztec::{ - protocol_types::constants::GENERATOR_INDEX__NOTE_NULLIFIER, + keys::getters::get_ivpk_m, protocol_types::constants::GENERATOR_INDEX__NOTE_NULLIFIER, note::utils::compute_note_hash_for_consumption, hash::poseidon2_hash, - oracle::{nullifier_key::get_app_nullifier_secret_key, get_public_key::get_public_key} + oracle::{nullifier_key::get_app_nullifier_secret_key} }; global SUBSCRIPTION_NOTE_LEN: Field = 3; @@ -39,12 +39,12 @@ 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); + let ivpk_m = get_ivpk_m(context, self.owner); context.emit_encrypted_log( (*context).this_address(), slot, Self::get_note_type_id(), - encryption_pub_key, + ivpk_m, self.serialize_content(), ); } diff --git a/noir-projects/noir-contracts/contracts/docs_example_contract/src/types/card_note.nr b/noir-projects/noir-contracts/contracts/docs_example_contract/src/types/card_note.nr index 3f952146c2bf..aa2fea463d4e 100644 --- a/noir-projects/noir-contracts/contracts/docs_example_contract/src/types/card_note.nr +++ b/noir-projects/noir-contracts/contracts/docs_example_contract/src/types/card_note.nr @@ -1,8 +1,8 @@ use dep::aztec::prelude::{AztecAddress, NoteInterface, NoteHeader, PrivateContext}; use dep::aztec::{ - note::{utils::compute_note_hash_for_consumption}, - oracle::{nullifier_key::get_app_nullifier_secret_key, get_public_key::get_public_key}, - hash::poseidon2_hash, protocol_types::{traits::Empty, constants::GENERATOR_INDEX__NOTE_NULLIFIER} + keys::getters::get_ivpk_m, note::{utils::compute_note_hash_for_consumption}, + oracle::nullifier_key::get_app_nullifier_secret_key, hash::poseidon2_hash, + protocol_types::{traits::Empty, constants::GENERATOR_INDEX__NOTE_NULLIFIER} }; // Shows how to create a custom note @@ -47,12 +47,12 @@ impl NoteInterface for CardNote { // 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); + let ivpk_m = get_ivpk_m(context, self.owner); context.emit_encrypted_log( (*context).this_address(), slot, Self::get_note_type_id(), - encryption_pub_key, + ivpk_m, self.serialize_content(), ); } diff --git a/noir-projects/noir-contracts/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr b/noir-projects/noir-contracts/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr index 20fd400e9679..eaadbbc60ace 100644 --- a/noir-projects/noir-contracts/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr +++ b/noir-projects/noir-contracts/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr @@ -1,9 +1,9 @@ use dep::aztec::prelude::{AztecAddress, FunctionSelector, NoteHeader, NoteInterface, NoteGetterOptions, PrivateContext}; use dep::aztec::{ - note::utils::compute_note_hash_for_consumption, - oracle::{nullifier_key::get_app_nullifier_secret_key, get_public_key::get_public_key}, - hash::poseidon2_hash, protocol_types::constants::GENERATOR_INDEX__NOTE_NULLIFIER + keys::getters::get_ivpk_m, note::utils::compute_note_hash_for_consumption, + oracle::nullifier_key::get_app_nullifier_secret_key, hash::poseidon2_hash, + protocol_types::constants::GENERATOR_INDEX__NOTE_NULLIFIER }; global ECDSA_PUBLIC_KEY_NOTE_LEN: Field = 5; @@ -85,12 +85,12 @@ impl NoteInterface for EcdsaPublicKeyNote { // 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); + let ivpk_m = get_ivpk_m(context, self.owner); context.emit_encrypted_log( (*context).this_address(), slot, Self::get_note_type_id(), - encryption_pub_key, + ivpk_m, self.serialize_content(), ); } diff --git a/noir-projects/noir-contracts/contracts/ecdsa_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/ecdsa_account_contract/src/main.nr index 25f96128b9df..d992251604db 100644 --- a/noir-projects/noir-contracts/contracts/ecdsa_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/ecdsa_account_contract/src/main.nr @@ -8,7 +8,7 @@ contract EcdsaAccount { use dep::aztec::protocol_types::abis::call_context::CallContext; use dep::std; - use dep::aztec::{context::{PublicContext, Context}, oracle::get_public_key::get_public_key}; + use dep::aztec::context::Context; use dep::authwit::{ entrypoint::{app::AppPayload, fee::FeePayload}, account::AccountActions, auth_witness::get_auth_witness diff --git a/noir-projects/noir-contracts/contracts/escrow_contract/src/main.nr b/noir-projects/noir-contracts/contracts/escrow_contract/src/main.nr index c1ec425486b4..bc17776d83d1 100644 --- a/noir-projects/noir-contracts/contracts/escrow_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/escrow_contract/src/main.nr @@ -2,7 +2,7 @@ contract Escrow { use dep::aztec::prelude::{AztecAddress, EthAddress, FunctionSelector, NoteHeader, PrivateContext, PrivateImmutable}; - use dep::aztec::{context::{PublicContext, Context}, oracle::get_public_key::get_public_key}; + use dep::aztec::context::{PublicContext, Context}; use dep::address_note::address_note::AddressNote; diff --git a/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/main.nr index d42ee2119d68..39cc3384b3b0 100644 --- a/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/main.nr @@ -7,7 +7,7 @@ contract SchnorrAccount { use dep::aztec::prelude::{AztecAddress, FunctionSelector, NoteHeader, PrivateContext, PrivateImmutable}; use dep::aztec::state_vars::{Map, PublicMutable}; - use dep::aztec::{context::Context, oracle::get_public_key::get_public_key}; + use dep::aztec::context::Context; use dep::authwit::{ entrypoint::{app::AppPayload, fee::FeePayload}, account::AccountActions, auth_witness::get_auth_witness diff --git a/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/public_key_note.nr b/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/public_key_note.nr index 95fbe422f78e..74812ec7465b 100644 --- a/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/public_key_note.nr +++ b/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/public_key_note.nr @@ -1,7 +1,7 @@ use dep::aztec::prelude::{AztecAddress, NoteHeader, NoteInterface, PrivateContext}; use dep::aztec::{ - note::utils::compute_note_hash_for_consumption, hash::poseidon2_hash, - oracle::{nullifier_key::get_app_nullifier_secret_key, get_public_key::get_public_key}, + keys::getters::get_ivpk_m, note::utils::compute_note_hash_for_consumption, hash::poseidon2_hash, + oracle::{nullifier_key::get_app_nullifier_secret_key}, protocol_types::constants::GENERATOR_INDEX__NOTE_NULLIFIER }; @@ -39,12 +39,12 @@ impl NoteInterface for PublicKeyNote { // 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); + let ivpk_m = get_ivpk_m(context, self.owner); context.emit_encrypted_log( (*context).this_address(), slot, Self::get_note_type_id(), - encryption_pub_key, + ivpk_m, self.serialize_content(), ); } 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 97210ff7b09d..39ec2ec5559b 100644 --- a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr @@ -23,18 +23,15 @@ contract Test { use dep::aztec::state_vars::{shared_mutable::SharedMutablePrivateGetter, map::derive_storage_slot_in_map}; use dep::aztec::{ - keys::getters::get_npk_m, + keys::getters::{get_npk_m, get_ivpk_m}, context::{Context, inputs::private_context_inputs::PrivateContextInputs}, - hash::{pedersen_hash, poseidon2_hash, compute_secret_hash, ArgsHasher}, + hash::{pedersen_hash, compute_secret_hash, ArgsHasher}, note::{ lifecycle::{create_note, destroy_note}, note_getter::{get_notes, view_notes}, note_getter_options::NoteStatus }, deploy::deploy_contract as aztec_deploy_contract, - oracle::{ - encryption::aes128_encrypt, get_public_key::get_public_key as get_public_key_oracle, - unsafe_rand::unsafe_rand - } + oracle::{encryption::aes128_encrypt, unsafe_rand::unsafe_rand} }; use dep::token_portal_content_hash_lib::{get_mint_private_content_hash, get_mint_public_content_hash}; use dep::value_note::value_note::ValueNote; @@ -53,8 +50,8 @@ contract Test { } #[aztec(private)] - fn get_public_key(address: AztecAddress) -> [Field; 2] { - let pub_key = get_public_key_oracle(address); + fn get_master_incoming_viewing_public_key(address: AztecAddress) -> [Field; 2] { + let pub_key = get_ivpk_m(&mut context, address); [pub_key.x, pub_key.y] } 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 798a9cfe174d..8492b92a1fca 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 @@ -1,8 +1,8 @@ use dep::aztec::{ - prelude::{AztecAddress, NoteHeader, NoteInterface, PrivateContext}, + keys::getters::get_ivpk_m, 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, get_public_key::get_public_key} + oracle::{unsafe_rand::unsafe_rand, nullifier_key::get_app_nullifier_secret_key} }; trait OwnedNote { @@ -52,12 +52,12 @@ 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); + let ivpk_m = get_ivpk_m(context, self.owner); context.emit_encrypted_log( (*context).this_address(), slot, Self::get_note_type_id(), - encryption_pub_key, + ivpk_m, self.serialize_content(), ); } 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 798a9cfe174d..8492b92a1fca 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,8 +1,8 @@ use dep::aztec::{ - prelude::{AztecAddress, NoteHeader, NoteInterface, PrivateContext}, + keys::getters::get_ivpk_m, 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, get_public_key::get_public_key} + oracle::{unsafe_rand::unsafe_rand, nullifier_key::get_app_nullifier_secret_key} }; trait OwnedNote { @@ -52,12 +52,12 @@ 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); + let ivpk_m = get_ivpk_m(context, self.owner); context.emit_encrypted_log( (*context).this_address(), slot, Self::get_note_type_id(), - encryption_pub_key, + ivpk_m, self.serialize_content(), ); } diff --git a/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts index 8697c01cbdda..03c228469109 100644 --- a/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts @@ -39,7 +39,6 @@ import { TxContext } from './tx_context.js'; /** * Public inputs to a private circuit. - * @see abis/private_circuit_public_inputs.hpp. */ export class PrivateCircuitPublicInputs { constructor( diff --git a/yarn-project/end-to-end/src/fixtures/utils.ts b/yarn-project/end-to-end/src/fixtures/utils.ts index 93439822fec8..f0fb99532c3e 100644 --- a/yarn-project/end-to-end/src/fixtures/utils.ts +++ b/yarn-project/end-to-end/src/fixtures/utils.ts @@ -190,6 +190,12 @@ export async function setupPXEService( const pxeServiceConfig = { ...getPXEServiceConfig(), ...opts }; const pxe = await createPXEService(aztecNode, pxeServiceConfig, useLogSuffix, proofCreator); + if (await pxe.getBlockNumber() ===0 && numberOfAccounts > 0) { + // Deploying accounts in block 1 fails because we try to get a public data tree witness when deploying an account + // and that fails since historical header block is set to 0. + throw new Error("Cannot deploy accounts in block 1. Deploy key registry first."); + } + const wallets = await createAccounts(pxe, numberOfAccounts); const teardown = async () => { @@ -400,7 +406,10 @@ export async function setup( const prover = aztecNode.getProver(); logger.verbose('Creating a pxe...'); - const { pxe, wallets } = await setupPXEService(numberOfAccounts, aztecNode!, pxeOpts, logger); + // Initially we do not deploy any account because we would get a failure -> deploying accounts in block 1 fails + // because we try to get a public data tree witness when deploying an account and that fails since historical header + // block is set to 0. + const { pxe } = await setupPXEService(0, aztecNode!, pxeOpts, logger); logger.verbose('Deploying key registry...'); await deployCanonicalKeyRegistry( @@ -414,6 +423,9 @@ export async function setup( ); } + // We progressed beyond block 1 so now we can deploy the accounts. + const wallets = await createAccounts(pxe, numberOfAccounts); + const cheatCodes = CheatCodes.create(config.rpcUrl, pxe!); const teardown = async () => { diff --git a/yarn-project/simulator/src/client/private_execution.test.ts b/yarn-project/simulator/src/client/private_execution.test.ts index 3b93537e10c2..5fce8a9829e5 100644 --- a/yarn-project/simulator/src/client/private_execution.test.ts +++ b/yarn-project/simulator/src/client/private_execution.test.ts @@ -4,6 +4,8 @@ import { type L1ToL2Message, Note, PackedValues, + PublicDataWitness, + SiblingPath, TxExecutionRequest, } from '@aztec/circuit-types'; import { @@ -13,13 +15,13 @@ import { FunctionData, GasSettings, GeneratorIndex, - type GrumpkinPrivateKey, Header, L1_TO_L2_MSG_TREE_HEIGHT, NOTE_HASH_TREE_HEIGHT, + PUBLIC_DATA_TREE_HEIGHT, PartialStateReference, PublicCallRequest, - type PublicKey, + PublicDataTreeLeafPreimage, StateReference, TxContext, computeAppNullifierSecretKey, @@ -39,7 +41,7 @@ import { Fr } from '@aztec/foundation/fields'; import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { type FieldsOf } from '@aztec/foundation/types'; import { openTmpStore } from '@aztec/kv-store/utils'; -import { type AppendOnlyTree, Pedersen, StandardTree, newTree } from '@aztec/merkle-tree'; +import { type AppendOnlyTree, INITIAL_LEAF, Pedersen, StandardTree, newTree } from '@aztec/merkle-tree'; import { ChildContractArtifact, ImportTestContractArtifact, @@ -79,14 +81,14 @@ describe('Private Execution test suite', () => { let ownerCompleteAddress: CompleteAddress; let recipientCompleteAddress: CompleteAddress; - let ownerMasterNullifierPublicKey: PublicKey; - let recipientMasterNullifierPublicKey: PublicKey; - let ownerMasterNullifierSecretKey: GrumpkinPrivateKey; - let recipientMasterNullifierSecretKey: GrumpkinPrivateKey; + // TODO(#5834): Nuke the following once complete address is refactored + let allOwnerKeys: any; + let allRecipientKeys: any; const treeHeights: { [name: string]: number } = { noteHash: NOTE_HASH_TREE_HEIGHT, l1ToL2Messages: L1_TO_L2_MSG_TREE_HEIGHT, + publicData: PUBLIC_DATA_TREE_HEIGHT, }; let trees: { [name: keyof typeof treeHeights]: AppendOnlyTree } = {}; @@ -139,7 +141,7 @@ describe('Private Execution test suite', () => { // Create a new snapshot. const newSnap = new AppendOnlyTreeSnapshot(Fr.fromBuffer(tree.getRoot(true)), Number(tree.getNumLeaves(true))); - if (name === 'noteHash' || name === 'l1ToL2Messages') { + if (name === 'noteHash' || name === 'l1ToL2Messages' || 'publicData') { header = new Header( header.lastArchive, header.contentCommitment, @@ -148,7 +150,7 @@ describe('Private Execution test suite', () => { new PartialStateReference( name === 'noteHash' ? newSnap : header.state.partial.noteHashTree, header.state.partial.nullifierTree, - header.state.partial.publicDataTree, + name === 'publicData' ? newSnap : header.state.partial.publicDataTree, ), ), header.globalVariables, @@ -175,42 +177,83 @@ describe('Private Execution test suite', () => { const ownerPartialAddress = Fr.random(); ownerCompleteAddress = CompleteAddress.fromSecretKeyAndPartialAddress(ownerSk, ownerPartialAddress); - - const allOwnerKeys = deriveKeys(ownerSk); - ownerMasterNullifierPublicKey = allOwnerKeys.masterNullifierPublicKey; - ownerMasterNullifierSecretKey = allOwnerKeys.masterNullifierSecretKey; + allOwnerKeys = deriveKeys(ownerSk); const recipientPartialAddress = Fr.random(); recipientCompleteAddress = CompleteAddress.fromSecretKeyAndPartialAddress(recipientSk, recipientPartialAddress); - - const allRecipientKeys = deriveKeys(recipientSk); - recipientMasterNullifierPublicKey = allRecipientKeys.masterNullifierPublicKey; - recipientMasterNullifierSecretKey = allRecipientKeys.masterNullifierSecretKey; + allRecipientKeys = deriveKeys(recipientSk); owner = ownerCompleteAddress.address; recipient = recipientCompleteAddress.address; }); - beforeEach(() => { + beforeEach(async () => { trees = {}; oracle = mock(); oracle.getNullifierKeys.mockImplementation((accountAddress: AztecAddress, contractAddress: AztecAddress) => { if (accountAddress.equals(ownerCompleteAddress.address)) { return Promise.resolve({ - masterNullifierPublicKey: ownerMasterNullifierPublicKey, - appNullifierSecretKey: computeAppNullifierSecretKey(ownerMasterNullifierSecretKey, contractAddress), + masterNullifierPublicKey: allOwnerKeys.masterNullifierPublicKey, + appNullifierSecretKey: computeAppNullifierSecretKey(allOwnerKeys.masterNullifierSecretKey, contractAddress), }); } if (accountAddress.equals(recipientCompleteAddress.address)) { return Promise.resolve({ - masterNullifierPublicKey: recipientMasterNullifierPublicKey, - appNullifierSecretKey: computeAppNullifierSecretKey(recipientMasterNullifierSecretKey, contractAddress), + masterNullifierPublicKey: allRecipientKeys.masterNullifierPublicKey, + appNullifierSecretKey: computeAppNullifierSecretKey( + allRecipientKeys.masterNullifierSecretKey, + contractAddress, + ), }); } throw new Error(`Unknown address ${accountAddress}`); }); + + // 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)) { + return Promise.resolve(ownerCompleteAddress); + } + if (address.equals(recipient)) { + return Promise.resolve(recipientCompleteAddress); + } + throw new Error(`Unknown address ${address}`); + }); + // TODO(#5834): The following oracle should be unnecessary + oracle.getPublicKeysForAddress.mockImplementation((address: AztecAddress) => { + if (address.equals(owner)) { + return Promise.resolve([ + allOwnerKeys.masterNullifierPublicKey, + allOwnerKeys.masterIncomingViewingPublicKey, + allOwnerKeys.masterOutgoingViewingPublicKey, + allOwnerKeys.masterTaggingPublicKey, + ]); + } + if (address.equals(recipient)) { + return Promise.resolve([ + allRecipientKeys.masterNullifierPublicKey, + allRecipientKeys.masterIncomingViewingPublicKey, + allRecipientKeys.masterOutgoingViewingPublicKey, + allRecipientKeys.masterTaggingPublicKey, + ]); + } + throw new Error(`Unknown address ${address}`); + }); + // 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 flows in which getCompleteAddress oracle + // gets called and we constrain the result by hashing address preimage and checking it matches. + oracle.getPublicDataTreeWitness.mockResolvedValue( + new PublicDataWitness( + 0n, + PublicDataTreeLeafPreimage.empty(), + SiblingPath.ZERO(PUBLIC_DATA_TREE_HEIGHT, INITIAL_LEAF, new Pedersen()), + ), + ); + acirSimulator = new AcirSimulator(oracle, node); }); @@ -286,16 +329,6 @@ describe('Private Execution test suite', () => { }; beforeEach(() => { - oracle.getCompleteAddress.mockImplementation((address: AztecAddress) => { - if (address.equals(owner)) { - return Promise.resolve(ownerCompleteAddress); - } - if (address.equals(recipient)) { - return Promise.resolve(recipientCompleteAddress); - } - throw new Error(`Unknown address ${address}`); - }); - oracle.getFunctionArtifactByName.mockImplementation((_, functionName: string) => Promise.resolve(getFunctionArtifact(StatefulTestContractArtifact, functionName)), ); @@ -929,7 +962,7 @@ describe('Private Execution test suite', () => { const nullifier = result.callStackItem.publicInputs.newNullifiers[0]; const expectedNullifier = poseidon2Hash([ innerNoteHash, - computeAppNullifierSecretKey(ownerMasterNullifierSecretKey, contractAddress), + computeAppNullifierSecretKey(allOwnerKeys.masterNullifierSecretKey, contractAddress), GeneratorIndex.NOTE_NULLIFIER, ]); expect(nullifier.value).toEqual(expectedNullifier); @@ -1008,7 +1041,7 @@ describe('Private Execution test suite', () => { const nullifier = execGetThenNullify.callStackItem.publicInputs.newNullifiers[0]; const expectedNullifier = poseidon2Hash([ innerNoteHash, - computeAppNullifierSecretKey(ownerMasterNullifierSecretKey, contractAddress), + computeAppNullifierSecretKey(allOwnerKeys.masterNullifierSecretKey, contractAddress), GeneratorIndex.NOTE_NULLIFIER, ]); expect(nullifier.value).toEqual(expectedNullifier); @@ -1034,17 +1067,14 @@ describe('Private Execution test suite', () => { }); }); - describe('get public key', () => { + describe('get master incoming viewing public key', () => { it('gets the public key for an address', async () => { // Tweak the contract artifact so we can extract return values - const artifact = getFunctionArtifact(TestContractArtifact, 'get_public_key'); + const artifact = getFunctionArtifact(TestContractArtifact, 'get_master_incoming_viewing_public_key'); - // Generate a partial address, pubkey, and resulting address - const completeAddress = CompleteAddress.random(); - const args = [completeAddress.address]; - const pubKey = completeAddress.publicKey; + const args = [recipientCompleteAddress.address]; + const pubKey = recipientCompleteAddress.publicKey; - oracle.getCompleteAddress.mockResolvedValue(completeAddress); const result = await runSimulator({ artifact, args }); expect(result.returnValues).toEqual([pubKey.x, pubKey.y]); });