From 4ea44f022f5ae510df2d67fab9576e2b6db52750 Mon Sep 17 00:00:00 2001 From: thunkar Date: Mon, 28 Oct 2024 11:03:22 +0000 Subject: [PATCH 1/5] added indexes and a way to store/retrieve tagged secrets --- .../aztec-nr/aztec/src/oracle/notes.nr | 32 ++++++++++++++-- .../types/src/indexed_tagging_secret.nr | 10 +++++ .../crates/types/src/lib.nr | 1 + .../src/interfaces/aztec-node.ts | 17 ++++++++- .../circuits.js/src/keys/derivation.ts | 13 +++---- yarn-project/circuits.js/src/structs/index.ts | 1 + .../src/structs/indexed_tagging_secret.ts | 9 +++++ .../pxe/src/database/kv_pxe_database.ts | 20 ++++++++++ yarn-project/pxe/src/database/pxe_database.ts | 4 ++ .../pxe/src/simulator_oracle/index.ts | 37 +++++++++++++++++-- .../simulator/src/acvm/oracle/oracle.ts | 4 +- .../simulator/src/acvm/oracle/typed_oracle.ts | 3 +- .../simulator/src/client/db_oracle.ts | 19 +++++++++- .../simulator/src/client/view_data_oracle.ts | 13 ++++++- yarn-project/txe/src/oracle/txe_oracle.ts | 7 +++- .../txe/src/txe_service/txe_service.ts | 2 +- 16 files changed, 167 insertions(+), 25 deletions(-) create mode 100644 noir-projects/noir-protocol-circuits/crates/types/src/indexed_tagging_secret.nr create mode 100644 yarn-project/circuits.js/src/structs/indexed_tagging_secret.ts diff --git a/noir-projects/aztec-nr/aztec/src/oracle/notes.nr b/noir-projects/aztec-nr/aztec/src/oracle/notes.nr index 642dcb4a0e03..b07c031c20c5 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/notes.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/notes.nr @@ -1,6 +1,10 @@ use crate::note::{note_header::NoteHeader, note_interface::NoteInterface}; -use dep::protocol_types::{address::AztecAddress, utils::arr_copy_slice}; +use dep::protocol_types::{ + address::AztecAddress, + indexed_tagging_secret::{INDEXED_TAGGING_SECRET_LENGTH, IndexedTaggingSecret}, + utils::arr_copy_slice, +}; /// Notifies the simulator that a note has been created, so that it can be returned in future read requests in the same /// transaction. This note should only be added to the non-volatile database if found in an actual block. @@ -200,17 +204,37 @@ pub unconstrained fn check_nullifier_exists(inner_nullifier: Field) -> bool { unconstrained fn check_nullifier_exists_oracle(_inner_nullifier: Field) -> Field {} /// Returns the tagging secret for a given sender and recipient pair, siloed for the current contract address. +/// Includes the last known index used for tagging with this secret. /// For this to work, PXE must know the ivpsk_m of the sender. /// For the recipient's side, only the address is needed. pub unconstrained fn get_app_tagging_secret( sender: AztecAddress, recipient: AztecAddress, -) -> Field { - get_app_tagging_secret_oracle(sender, recipient) +) -> IndexedTaggingSecret { + let result = get_app_tagging_secret_oracle(sender, recipient); + IndexedTaggingSecret::deserialize(result) } #[oracle(getAppTaggingSecret)] unconstrained fn get_app_tagging_secret_oracle( _sender: AztecAddress, _recipient: AztecAddress, -) -> Field {} +) -> [Field; INDEXED_TAGGING_SECRET_LENGHT] {} + +/// Returns the tagging secrets for a given recipient and all the senders in PXE's address book, +// siloed for the current contract address. +/// Includes the last known index used for tagging with this secret. +/// For this to work, PXE must know the ivpsk_m of the recipient. +pub unconstrained fn get_app_tagging_secrets_for_senders( + sender: AztecAddress, + recipient: AztecAddress, +) -> [IndexedTaggingSecret] { + let results = get_app_tagging_secrets_for_senders_oracle(sender, recipient); + results.map(|result| IndexedTaggingSecret::deserialize(result)) +} + +#[oracle(getAppTaggingSecretsForSenders)] +unconstrained fn get_app_tagging_secrets_for_senders_oracle( + _sender: AztecAddress, + _recipient: AztecAddress, +) -> [[Field; INDEXED_TAGGING_SECRET_LENGTH]] {} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/indexed_tagging_secret.nr b/noir-projects/noir-protocol-circuits/crates/types/src/indexed_tagging_secret.nr new file mode 100644 index 000000000000..1685fdf38e8a --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/types/src/indexed_tagging_secret.nr @@ -0,0 +1,10 @@ +use crate::traits::Deserialize; +use std::meta::derive; + +pub global INDEXED_TAGGING_SECRET_LENGTH: u32 = 2; + +#[derive(Deserialize)] +pub struct IndexedTaggingSecret { + secret: Field, + index: u32, +} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/lib.nr b/noir-projects/noir-protocol-circuits/crates/types/src/lib.nr index 4fa82de35ff7..f9b2f0ebbd62 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/lib.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/lib.nr @@ -31,6 +31,7 @@ mod data; mod storage; mod validate; mod meta; +mod indexed_tagging_secret; pub use abis::kernel_circuit_public_inputs::{ KernelCircuitPublicInputs, PrivateKernelCircuitPublicInputs, PublicKernelCircuitPublicInputs, diff --git a/yarn-project/circuit-types/src/interfaces/aztec-node.ts b/yarn-project/circuit-types/src/interfaces/aztec-node.ts index b8f7c80634c7..e7c79fda0ce3 100644 --- a/yarn-project/circuit-types/src/interfaces/aztec-node.ts +++ b/yarn-project/circuit-types/src/interfaces/aztec-node.ts @@ -15,7 +15,14 @@ import type { AztecAddress } from '@aztec/foundation/aztec-address'; import type { Fr } from '@aztec/foundation/fields'; import type { L2Block } from '../l2_block.js'; -import type { FromLogType, GetUnencryptedLogsResponse, L2BlockL2Logs, LogFilter, LogType } from '../logs/index.js'; +import type { + EncryptedL2NoteLog, + FromLogType, + GetUnencryptedLogsResponse, + L2BlockL2Logs, + LogFilter, + LogType, +} from '../logs/index.js'; import type { MerkleTreeId } from '../merkle_tree_id.js'; import type { EpochProofQuote } from '../prover_coordination/epoch_proof_quote.js'; import type { PublicDataWitness } from '../public_data_witness.js'; @@ -247,6 +254,14 @@ export interface AztecNode extends ProverCoordination { */ getUnencryptedLogs(filter: LogFilter): Promise; + /** + * Gets all logs that match any of the received tags (i.e. logs with their first field equal to a tag). + * @param tags - The tags to filter the logs by. + * @returns For each received tag, an array of matching logs is returned. An empty array implies no logs match + * that tag. + */ + getLogsByTags(tags: Fr[]): Promise; + /** * Method to submit a transaction to the p2p pool. * @param tx - The transaction to be submitted. diff --git a/yarn-project/circuits.js/src/keys/derivation.ts b/yarn-project/circuits.js/src/keys/derivation.ts index ae298c208b4b..1fa9276e3f31 100644 --- a/yarn-project/circuits.js/src/keys/derivation.ts +++ b/yarn-project/circuits.js/src/keys/derivation.ts @@ -127,15 +127,12 @@ export function deriveKeys(secretKey: Fr) { }; } -export function computeTaggingSecret(senderCompleteAddress: CompleteAddress, senderIvsk: Fq, recipient: AztecAddress) { - const senderPreaddress = computePreaddress( - senderCompleteAddress.publicKeys.hash(), - senderCompleteAddress.partialAddress, - ); +export function computeTaggingSecret(knownAddress: CompleteAddress, ivsk: Fq, externalAddress: AztecAddress) { + const knownPreaddress = computePreaddress(knownAddress.publicKeys.hash(), knownAddress.partialAddress); // TODO: #8970 - Computation of address point from x coordinate might fail - const recipientAddressPoint = computePoint(recipient); + const externalAddressPoint = computePoint(externalAddress); const curve = new Grumpkin(); - // Given A (sender) -> B (recipient) and h == preaddress + // Given A (known complete address) -> B (external address) and h == preaddress // Compute shared secret as S = (h_A + ivsk_A) * Addr_Point_B - return curve.mul(recipientAddressPoint, senderIvsk.add(new Fq(senderPreaddress.toBigInt()))); + return curve.mul(externalAddressPoint, ivsk.add(new Fq(knownPreaddress.toBigInt()))); } diff --git a/yarn-project/circuits.js/src/structs/index.ts b/yarn-project/circuits.js/src/structs/index.ts index 611652fe46e9..8635d8e7c09a 100644 --- a/yarn-project/circuits.js/src/structs/index.ts +++ b/yarn-project/circuits.js/src/structs/index.ts @@ -13,6 +13,7 @@ export * from './gas_fees.js'; export * from './gas_settings.js'; export * from './global_variables.js'; export * from './header.js'; +export * from './indexed_tagging_secret.js'; export * from './kernel/combined_accumulated_data.js'; export * from './kernel/combined_constant_data.js'; export * from './kernel/enqueued_call_data.js'; diff --git a/yarn-project/circuits.js/src/structs/indexed_tagging_secret.ts b/yarn-project/circuits.js/src/structs/indexed_tagging_secret.ts new file mode 100644 index 000000000000..ab218b5b7ee7 --- /dev/null +++ b/yarn-project/circuits.js/src/structs/indexed_tagging_secret.ts @@ -0,0 +1,9 @@ +import { Fr } from '@aztec/foundation/fields'; + +export class IndexedTaggingSecret { + constructor(public secret: Fr, public index: number) {} + + toFields(): Fr[] { + return [this.secret, new Fr(this.index)]; + } +} diff --git a/yarn-project/pxe/src/database/kv_pxe_database.ts b/yarn-project/pxe/src/database/kv_pxe_database.ts index 412aacf4fa51..28eb11e38cba 100644 --- a/yarn-project/pxe/src/database/kv_pxe_database.ts +++ b/yarn-project/pxe/src/database/kv_pxe_database.ts @@ -66,6 +66,8 @@ export class KVPxeDatabase implements PxeDatabase { #notesByTxHashAndScope: Map>; #notesByIvpkMAndScope: Map>; + #taggingSecretIndices: AztecMap; + constructor(private db: AztecKVStore) { this.#db = db; @@ -111,6 +113,8 @@ export class KVPxeDatabase implements PxeDatabase { this.#notesByTxHashAndScope.set(scope, db.openMultiMap(`${scope}:notes_by_tx_hash`)); this.#notesByIvpkMAndScope.set(scope, db.openMultiMap(`${scope}:notes_by_ivpk_m`)); } + + this.#taggingSecretIndices = db.openMap('tagging_secret_indices'); } public async getContract( @@ -572,4 +576,20 @@ export class KVPxeDatabase implements PxeDatabase { return incomingNotesSize + outgoingNotesSize + treeRootsSize + authWitsSize + addressesSize; } + + async incrementTaggingSecretsIndexes(appTaggingSecrets: Fr[]): Promise { + const indexes = await this.getTaggingSecretsIndexes(appTaggingSecrets); + await this.db.transaction(() => { + indexes.forEach(index => { + const nextIndex = index ? index + 1 : 1; + void this.#taggingSecretIndices.set(appTaggingSecrets.toString(), nextIndex); + }); + }); + } + + async getTaggingSecretsIndexes(appTaggingSecrets: Fr[]): Promise { + return this.db.transaction(() => + appTaggingSecrets.map(secret => this.#taggingSecretIndices.get(secret.toString()) ?? 0), + ); + } } diff --git a/yarn-project/pxe/src/database/pxe_database.ts b/yarn-project/pxe/src/database/pxe_database.ts index 0562f79bd6da..843b565da167 100644 --- a/yarn-project/pxe/src/database/pxe_database.ts +++ b/yarn-project/pxe/src/database/pxe_database.ts @@ -185,4 +185,8 @@ export interface PxeDatabase extends ContractArtifactDatabase, ContractInstanceD * @returns The estimated size in bytes of this db. */ estimateSize(): Promise; + + getTaggingSecretsIndexes(appTaggingSecrets: Fr[]): Promise; + + incrementTaggingSecretsIndexes(appTaggingSecrets: Fr[]): Promise; } diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index 1b18b32c3188..6dda36f90fed 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -1,5 +1,7 @@ import { type AztecNode, + EncryptedL2Log, + EncryptedL2NoteLog, type L2Block, MerkleTreeId, type NoteStatus, @@ -14,6 +16,7 @@ import { type Fr, type FunctionSelector, type Header, + IndexedTaggingSecret, type KeyValidationRequest, type L1_TO_L2_MSG_TREE_HEIGHT, computeTaggingSecret, @@ -231,20 +234,48 @@ export class SimulatorOracle implements DBOracle { /** * Returns the tagging secret for a given sender and recipient pair. For this to work, the ivpsk_m of the sender must be known. + * Includes the last known index used for tagging with this secret. * @param contractAddress - The contract address to silo the secret for * @param sender - The address sending the note * @param recipient - The address receiving the note - * @returns A tagging secret that can be used to tag notes. + * @returns A siloed tagging secret that can be used to tag notes. */ public async getAppTaggingSecret( contractAddress: AztecAddress, sender: AztecAddress, recipient: AztecAddress, - ): Promise { + ): Promise { const senderCompleteAddress = await this.getCompleteAddress(sender); const senderIvsk = await this.keyStore.getMasterIncomingViewingSecretKey(sender); const sharedSecret = computeTaggingSecret(senderCompleteAddress, senderIvsk, recipient); // Silo the secret to the app so it can't be used to track other app's notes - return poseidon2Hash([sharedSecret.x, sharedSecret.y, contractAddress]); + const secret = poseidon2Hash([sharedSecret.x, sharedSecret.y, contractAddress]); + const [index] = await this.db.getTaggingSecretsIndexes([secret]); + return new IndexedTaggingSecret(secret, index); + } + + /** + * Returns the siloed tagging secrets for a given recipient and all the senders in the address book + * @param contractAddress - The contract address to silo the secret for + * @param recipient - The address receiving the notes + * @returns A list of siloed tagging secrets + */ + public async getAppTaggingSecretsForSenders( + contractAddress: AztecAddress, + recipient: CompleteAddress, + ): Promise { + const completeAddresses = await this.db.getCompleteAddresses(); + // Filter out the addresses corresponding to accounts + const accounts = await this.keyStore.getAccounts(); + const senders = completeAddresses.filter( + completeAddress => !accounts.find(account => account.equals(completeAddress.address)), + ); + const recipientIvsk = await this.keyStore.getMasterIncomingViewingSecretKey(recipient.address); + const secrets = senders.map(({ address: sender }) => { + const sharedSecret = computeTaggingSecret(recipient, recipientIvsk, sender); + return poseidon2Hash([sharedSecret.x, sharedSecret.y, contractAddress]); + }); + const indexes = await this.db.getTaggingSecretsIndexes(secrets); + return secrets.map((secret, i) => new IndexedTaggingSecret(secret, indexes[i])); } } diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index e3c315f07083..7d648c454918 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -409,11 +409,11 @@ export class Oracle { this.typedOracle.notifySetMinRevertibleSideEffectCounter(frToNumber(fromACVMField(minRevertibleSideEffectCounter))); } - async getAppTaggingSecret([sender]: ACVMField[], [recipient]: ACVMField[]): Promise { + async getAppTaggingSecret([sender]: ACVMField[], [recipient]: ACVMField[]): Promise { const taggingSecret = await this.typedOracle.getAppTaggingSecret( AztecAddress.fromString(sender), AztecAddress.fromString(recipient), ); - return toACVMField(taggingSecret); + return taggingSecret.toFields().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 1e66f0f150c7..fe5c2dd050a6 100644 --- a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts @@ -11,6 +11,7 @@ import { import { type ContractInstance, type Header, + IndexedTaggingSecret, type KeyValidationRequest, type L1_TO_L2_MSG_TREE_HEIGHT, } from '@aztec/circuits.js'; @@ -253,7 +254,7 @@ export abstract class TypedOracle { throw new OracleMethodNotAvailableError('debugLog'); } - getAppTaggingSecret(_sender: AztecAddress, _recipient: AztecAddress): Promise { + getAppTaggingSecret(_sender: AztecAddress, _recipient: AztecAddress): Promise { throw new OracleMethodNotAvailableError('getAppTaggingSecret'); } } diff --git a/yarn-project/simulator/src/client/db_oracle.ts b/yarn-project/simulator/src/client/db_oracle.ts index c80d4fed5df9..97e1e40352a2 100644 --- a/yarn-project/simulator/src/client/db_oracle.ts +++ b/yarn-project/simulator/src/client/db_oracle.ts @@ -9,6 +9,7 @@ import { type CompleteAddress, type ContractInstance, type Header, + IndexedTaggingSecret, type KeyValidationRequest, } from '@aztec/circuits.js'; import { type FunctionArtifact, type FunctionSelector } from '@aztec/foundation/abi'; @@ -196,10 +197,26 @@ export interface DBOracle extends CommitmentsDB { /** * Returns the tagging secret for a given sender and recipient pair. For this to work, the ivpsk_m of the sender must be known. + * Includes the last known index used for tagging with this secret. * @param contractAddress - The contract address to silo the secret for * @param sender - The address sending the note * @param recipient - The address receiving the note * @returns A tagging secret that can be used to tag notes. */ - getAppTaggingSecret(contractAddress: AztecAddress, sender: AztecAddress, recipient: AztecAddress): Promise; + getAppTaggingSecret( + contractAddress: AztecAddress, + sender: AztecAddress, + recipient: AztecAddress, + ): Promise; + + /** + * Returns the siloed tagging secrets for a given recipient and all the senders in the address book + * @param contractAddress - The contract address to silo the secret for + * @param recipient - The address receiving the notes + * @returns A list of siloed tagging secrets + */ + getAppTaggingSecretsForSenders( + contractAddress: AztecAddress, + recipient: CompleteAddress, + ): Promise; } diff --git a/yarn-project/simulator/src/client/view_data_oracle.ts b/yarn-project/simulator/src/client/view_data_oracle.ts index 644c4b8b6bdc..3be96a30ea1c 100644 --- a/yarn-project/simulator/src/client/view_data_oracle.ts +++ b/yarn-project/simulator/src/client/view_data_oracle.ts @@ -7,7 +7,12 @@ import { type NullifierMembershipWitness, type PublicDataWitness, } from '@aztec/circuit-types'; -import { type ContractInstance, type Header, type KeyValidationRequest } from '@aztec/circuits.js'; +import { + type ContractInstance, + type Header, + IndexedTaggingSecret, + type KeyValidationRequest, +} from '@aztec/circuits.js'; import { siloNullifier } from '@aztec/circuits.js/hash'; import { type AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; @@ -291,12 +296,16 @@ export class ViewDataOracle extends TypedOracle { /** * Returns the tagging secret for a given sender and recipient pair, siloed to the current contract address. + * Includes the last known index used for tagging with this secret. * For this to work, the ivpsk_m of the sender must be known. * @param sender - The address sending the note * @param recipient - The address receiving the note * @returns A tagging secret that can be used to tag notes. */ - public override async getAppTaggingSecret(sender: AztecAddress, recipient: AztecAddress): Promise { + public override async getAppTaggingSecret( + sender: AztecAddress, + recipient: AztecAddress, + ): Promise { return await this.db.getAppTaggingSecret(this.contractAddress, sender, recipient); } } diff --git a/yarn-project/txe/src/oracle/txe_oracle.ts b/yarn-project/txe/src/oracle/txe_oracle.ts index 3823d6d940d4..d26325dd0451 100644 --- a/yarn-project/txe/src/oracle/txe_oracle.ts +++ b/yarn-project/txe/src/oracle/txe_oracle.ts @@ -18,6 +18,7 @@ import { type ContractInstanceWithAddress, Gas, Header, + IndexedTaggingSecret, type KeyValidationRequest, NULLIFIER_SUBTREE_HEIGHT, type NULLIFIER_TREE_HEIGHT, @@ -749,12 +750,14 @@ export class TXE implements TypedOracle { return; } - async getAppTaggingSecret(sender: AztecAddress, recipient: AztecAddress): Promise { + async getAppTaggingSecret(sender: AztecAddress, recipient: AztecAddress): Promise { const senderCompleteAddress = await this.getCompleteAddress(sender); const senderIvsk = await this.keyStore.getMasterIncomingViewingSecretKey(sender); const sharedSecret = computeTaggingSecret(senderCompleteAddress, senderIvsk, recipient); // Silo the secret to the app so it can't be used to track other app's notes - return poseidon2Hash([sharedSecret.x, sharedSecret.y, this.contractAddress]); + const secret = poseidon2Hash([sharedSecret.x, sharedSecret.y, this.contractAddress]); + const [index] = await this.txeDatabase.getTaggingSecretsIndexes([secret]); + return new IndexedTaggingSecret(secret, index); } // AVM oracles diff --git a/yarn-project/txe/src/txe_service/txe_service.ts b/yarn-project/txe/src/txe_service/txe_service.ts index f0f41fa232ca..4eaa22d4bd7a 100644 --- a/yarn-project/txe/src/txe_service/txe_service.ts +++ b/yarn-project/txe/src/txe_service/txe_service.ts @@ -604,7 +604,7 @@ export class TXEService { AztecAddress.fromField(fromSingle(sender)), AztecAddress.fromField(fromSingle(recipient)), ); - return toForeignCallResult([toSingle(secret)]); + return toForeignCallResult([toArray(secret.toFields())]); } // AVM opcodes From 7fd2702600bcec84a036db75b1aef089ff04cb21 Mon Sep 17 00:00:00 2001 From: thunkar Date: Mon, 28 Oct 2024 11:09:45 +0000 Subject: [PATCH 2/5] fmt --- noir-projects/aztec-nr/aztec/src/oracle/notes.nr | 2 +- yarn-project/pxe/src/database/kv_pxe_database.ts | 10 +++++----- yarn-project/pxe/src/simulator_oracle/index.ts | 2 -- yarn-project/simulator/src/acvm/oracle/typed_oracle.ts | 2 +- yarn-project/simulator/src/client/db_oracle.ts | 2 +- yarn-project/simulator/src/client/view_data_oracle.ts | 2 +- 6 files changed, 9 insertions(+), 11 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/oracle/notes.nr b/noir-projects/aztec-nr/aztec/src/oracle/notes.nr index b07c031c20c5..b5cc6289ea47 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/notes.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/notes.nr @@ -219,7 +219,7 @@ pub unconstrained fn get_app_tagging_secret( unconstrained fn get_app_tagging_secret_oracle( _sender: AztecAddress, _recipient: AztecAddress, -) -> [Field; INDEXED_TAGGING_SECRET_LENGHT] {} +) -> [Field; INDEXED_TAGGING_SECRET_LENGTH] {} /// Returns the tagging secrets for a given recipient and all the senders in PXE's address book, // siloed for the current contract address. diff --git a/yarn-project/pxe/src/database/kv_pxe_database.ts b/yarn-project/pxe/src/database/kv_pxe_database.ts index 28eb11e38cba..af23c0d1c056 100644 --- a/yarn-project/pxe/src/database/kv_pxe_database.ts +++ b/yarn-project/pxe/src/database/kv_pxe_database.ts @@ -66,7 +66,7 @@ export class KVPxeDatabase implements PxeDatabase { #notesByTxHashAndScope: Map>; #notesByIvpkMAndScope: Map>; - #taggingSecretIndices: AztecMap; + #taggingSecretIndexes: AztecMap; constructor(private db: AztecKVStore) { this.#db = db; @@ -114,7 +114,7 @@ export class KVPxeDatabase implements PxeDatabase { this.#notesByIvpkMAndScope.set(scope, db.openMultiMap(`${scope}:notes_by_ivpk_m`)); } - this.#taggingSecretIndices = db.openMap('tagging_secret_indices'); + this.#taggingSecretIndexes = db.openMap('tagging_secret_indices'); } public async getContract( @@ -582,14 +582,14 @@ export class KVPxeDatabase implements PxeDatabase { await this.db.transaction(() => { indexes.forEach(index => { const nextIndex = index ? index + 1 : 1; - void this.#taggingSecretIndices.set(appTaggingSecrets.toString(), nextIndex); + void this.#taggingSecretIndexes.set(appTaggingSecrets.toString(), nextIndex); }); }); } - async getTaggingSecretsIndexes(appTaggingSecrets: Fr[]): Promise { + getTaggingSecretsIndexes(appTaggingSecrets: Fr[]): Promise { return this.db.transaction(() => - appTaggingSecrets.map(secret => this.#taggingSecretIndices.get(secret.toString()) ?? 0), + appTaggingSecrets.map(secret => this.#taggingSecretIndexes.get(secret.toString()) ?? 0), ); } } diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index 6dda36f90fed..f935ceb90fb5 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -1,7 +1,5 @@ import { type AztecNode, - EncryptedL2Log, - EncryptedL2NoteLog, type L2Block, MerkleTreeId, type NoteStatus, diff --git a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts index fe5c2dd050a6..b957ddc9ce46 100644 --- a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts @@ -11,7 +11,7 @@ import { import { type ContractInstance, type Header, - IndexedTaggingSecret, + type IndexedTaggingSecret, type KeyValidationRequest, type L1_TO_L2_MSG_TREE_HEIGHT, } from '@aztec/circuits.js'; diff --git a/yarn-project/simulator/src/client/db_oracle.ts b/yarn-project/simulator/src/client/db_oracle.ts index 97e1e40352a2..1e352719edd0 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 ContractInstance, type Header, - IndexedTaggingSecret, + type IndexedTaggingSecret, type KeyValidationRequest, } from '@aztec/circuits.js'; import { type FunctionArtifact, type FunctionSelector } from '@aztec/foundation/abi'; diff --git a/yarn-project/simulator/src/client/view_data_oracle.ts b/yarn-project/simulator/src/client/view_data_oracle.ts index 3be96a30ea1c..3fbfaae9fa01 100644 --- a/yarn-project/simulator/src/client/view_data_oracle.ts +++ b/yarn-project/simulator/src/client/view_data_oracle.ts @@ -10,7 +10,7 @@ import { import { type ContractInstance, type Header, - IndexedTaggingSecret, + type IndexedTaggingSecret, type KeyValidationRequest, } from '@aztec/circuits.js'; import { siloNullifier } from '@aztec/circuits.js/hash'; From e56cd9553d5b290df869990bf461394ffa3ffd9d Mon Sep 17 00:00:00 2001 From: thunkar Date: Mon, 28 Oct 2024 12:14:47 +0000 Subject: [PATCH 3/5] fix oracle args --- noir-projects/aztec-nr/aztec/src/oracle/notes.nr | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/oracle/notes.nr b/noir-projects/aztec-nr/aztec/src/oracle/notes.nr index b5cc6289ea47..8f177d891e7e 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/notes.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/notes.nr @@ -226,15 +226,13 @@ unconstrained fn get_app_tagging_secret_oracle( /// Includes the last known index used for tagging with this secret. /// For this to work, PXE must know the ivpsk_m of the recipient. pub unconstrained fn get_app_tagging_secrets_for_senders( - sender: AztecAddress, recipient: AztecAddress, ) -> [IndexedTaggingSecret] { - let results = get_app_tagging_secrets_for_senders_oracle(sender, recipient); + let results = get_app_tagging_secrets_for_senders_oracle(recipient); results.map(|result| IndexedTaggingSecret::deserialize(result)) } #[oracle(getAppTaggingSecretsForSenders)] unconstrained fn get_app_tagging_secrets_for_senders_oracle( - _sender: AztecAddress, _recipient: AztecAddress, ) -> [[Field; INDEXED_TAGGING_SECRET_LENGTH]] {} From 700a16112590296a4d78842ae36fca95b70f5064 Mon Sep 17 00:00:00 2001 From: Gregorio Juliana Date: Mon, 28 Oct 2024 15:07:34 +0100 Subject: [PATCH 4/5] Update noir-projects/aztec-nr/aztec/src/oracle/notes.nr Co-authored-by: esau <152162806+sklppy88@users.noreply.github.com> --- noir-projects/aztec-nr/aztec/src/oracle/notes.nr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noir-projects/aztec-nr/aztec/src/oracle/notes.nr b/noir-projects/aztec-nr/aztec/src/oracle/notes.nr index 8f177d891e7e..1f40cd3b5df0 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/notes.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/notes.nr @@ -224,7 +224,7 @@ unconstrained fn get_app_tagging_secret_oracle( /// Returns the tagging secrets for a given recipient and all the senders in PXE's address book, // siloed for the current contract address. /// Includes the last known index used for tagging with this secret. -/// For this to work, PXE must know the ivpsk_m of the recipient. +/// For this to work, PXE must know the ivsk_m of the recipient. pub unconstrained fn get_app_tagging_secrets_for_senders( recipient: AztecAddress, ) -> [IndexedTaggingSecret] { From d5bf8588f37fbbf1ad0edd7434e7324773aa1050 Mon Sep 17 00:00:00 2001 From: thunkar Date: Mon, 28 Oct 2024 14:36:27 +0000 Subject: [PATCH 5/5] fixes --- .../aztec-nr/aztec/src/oracle/notes.nr | 15 +++++++++++---- yarn-project/pxe/src/simulator_oracle/index.ts | 7 ++++--- .../simulator/src/acvm/oracle/oracle.ts | 5 +++++ .../simulator/src/acvm/oracle/typed_oracle.ts | 4 ++++ yarn-project/simulator/src/client/db_oracle.ts | 2 +- .../simulator/src/client/view_data_oracle.ts | 10 ++++++++++ yarn-project/txe/src/oracle/txe_oracle.ts | 17 +++++++++++++++++ yarn-project/txe/src/txe_service/txe_service.ts | 7 +++++++ 8 files changed, 59 insertions(+), 8 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/oracle/notes.nr b/noir-projects/aztec-nr/aztec/src/oracle/notes.nr index 8f177d891e7e..6d51673fbae7 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/notes.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/notes.nr @@ -229,10 +229,17 @@ pub unconstrained fn get_app_tagging_secrets_for_senders( recipient: AztecAddress, ) -> [IndexedTaggingSecret] { let results = get_app_tagging_secrets_for_senders_oracle(recipient); - results.map(|result| IndexedTaggingSecret::deserialize(result)) + let mut indexed_tagging_secrets = &[]; + for i in 0..results.len() { + if i % 2 != 0 { + continue; + } + indexed_tagging_secrets = indexed_tagging_secrets.push_back( + IndexedTaggingSecret::deserialize([results[i], results[i + 1]]), + ); + } + indexed_tagging_secrets } #[oracle(getAppTaggingSecretsForSenders)] -unconstrained fn get_app_tagging_secrets_for_senders_oracle( - _recipient: AztecAddress, -) -> [[Field; INDEXED_TAGGING_SECRET_LENGTH]] {} +unconstrained fn get_app_tagging_secrets_for_senders_oracle(_recipient: AztecAddress) -> [Field] {} diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index f935ceb90fb5..50570db1ae5b 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -260,17 +260,18 @@ export class SimulatorOracle implements DBOracle { */ public async getAppTaggingSecretsForSenders( contractAddress: AztecAddress, - recipient: CompleteAddress, + recipient: AztecAddress, ): Promise { + const recipientCompleteAddress = await this.getCompleteAddress(recipient); const completeAddresses = await this.db.getCompleteAddresses(); // Filter out the addresses corresponding to accounts const accounts = await this.keyStore.getAccounts(); const senders = completeAddresses.filter( completeAddress => !accounts.find(account => account.equals(completeAddress.address)), ); - const recipientIvsk = await this.keyStore.getMasterIncomingViewingSecretKey(recipient.address); + const recipientIvsk = await this.keyStore.getMasterIncomingViewingSecretKey(recipient); const secrets = senders.map(({ address: sender }) => { - const sharedSecret = computeTaggingSecret(recipient, recipientIvsk, sender); + const sharedSecret = computeTaggingSecret(recipientCompleteAddress, recipientIvsk, sender); return poseidon2Hash([sharedSecret.x, sharedSecret.y, contractAddress]); }); const indexes = await this.db.getTaggingSecretsIndexes(secrets); diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index 7d648c454918..c8fdb5a18b2f 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -416,4 +416,9 @@ export class Oracle { ); return taggingSecret.toFields().map(toACVMField); } + + async getAppTaggingSecretsForSenders([recipient]: ACVMField[]): Promise { + const taggingSecrets = await this.typedOracle.getAppTaggingSecretsForSenders(AztecAddress.fromString(recipient)); + return taggingSecrets.flatMap(taggingSecret => taggingSecret.toFields().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 b957ddc9ce46..284b08f5e0f5 100644 --- a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts @@ -257,4 +257,8 @@ export abstract class TypedOracle { getAppTaggingSecret(_sender: AztecAddress, _recipient: AztecAddress): Promise { throw new OracleMethodNotAvailableError('getAppTaggingSecret'); } + + getAppTaggingSecretsForSenders(_recipient: AztecAddress): Promise { + throw new OracleMethodNotAvailableError('getAppTaggingSecretsForSenders'); + } } diff --git a/yarn-project/simulator/src/client/db_oracle.ts b/yarn-project/simulator/src/client/db_oracle.ts index 1e352719edd0..c19a0b1636ac 100644 --- a/yarn-project/simulator/src/client/db_oracle.ts +++ b/yarn-project/simulator/src/client/db_oracle.ts @@ -217,6 +217,6 @@ export interface DBOracle extends CommitmentsDB { */ getAppTaggingSecretsForSenders( contractAddress: AztecAddress, - recipient: CompleteAddress, + recipient: 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 3fbfaae9fa01..b8ca0266fa4b 100644 --- a/yarn-project/simulator/src/client/view_data_oracle.ts +++ b/yarn-project/simulator/src/client/view_data_oracle.ts @@ -308,4 +308,14 @@ export class ViewDataOracle extends TypedOracle { ): Promise { return await this.db.getAppTaggingSecret(this.contractAddress, sender, recipient); } + + /** + * Returns the siloed tagging secrets for a given recipient and all the senders in the address book + * @param contractAddress - The contract address to silo the secret for + * @param recipient - The address receiving the notes + * @returns A list of siloed tagging secrets + */ + public override async getAppTaggingSecretsForSenders(recipient: AztecAddress): Promise { + return await this.db.getAppTaggingSecretsForSenders(this.contractAddress, recipient); + } } diff --git a/yarn-project/txe/src/oracle/txe_oracle.ts b/yarn-project/txe/src/oracle/txe_oracle.ts index d26325dd0451..b16be91beb12 100644 --- a/yarn-project/txe/src/oracle/txe_oracle.ts +++ b/yarn-project/txe/src/oracle/txe_oracle.ts @@ -760,6 +760,23 @@ export class TXE implements TypedOracle { return new IndexedTaggingSecret(secret, index); } + async getAppTaggingSecretsForSenders(recipient: AztecAddress): Promise { + const recipientCompleteAddress = await this.getCompleteAddress(recipient); + const completeAddresses = await this.txeDatabase.getCompleteAddresses(); + // Filter out the addresses corresponding to accounts + const accounts = await this.keyStore.getAccounts(); + const senders = completeAddresses.filter( + completeAddress => !accounts.find(account => account.equals(completeAddress.address)), + ); + const recipientIvsk = await this.keyStore.getMasterIncomingViewingSecretKey(recipient); + const secrets = senders.map(({ address: sender }) => { + const sharedSecret = computeTaggingSecret(recipientCompleteAddress, recipientIvsk, sender); + return poseidon2Hash([sharedSecret.x, sharedSecret.y, this.contractAddress]); + }); + const indexes = await this.txeDatabase.getTaggingSecretsIndexes(secrets); + return secrets.map((secret, i) => new IndexedTaggingSecret(secret, indexes[i])); + } + // AVM oracles async avmOpcodeCall( diff --git a/yarn-project/txe/src/txe_service/txe_service.ts b/yarn-project/txe/src/txe_service/txe_service.ts index 4eaa22d4bd7a..7731f55b23f8 100644 --- a/yarn-project/txe/src/txe_service/txe_service.ts +++ b/yarn-project/txe/src/txe_service/txe_service.ts @@ -607,6 +607,13 @@ export class TXEService { return toForeignCallResult([toArray(secret.toFields())]); } + async getAppTaggingSecretsForSenders(recipient: ForeignCallSingle) { + const secrets = await this.typedOracle.getAppTaggingSecretsForSenders( + AztecAddress.fromField(fromSingle(recipient)), + ); + return toForeignCallResult([toArray(secrets.flatMap(secret => secret.toFields()))]); + } + // AVM opcodes avmOpcodeEmitUnencryptedLog(_message: ForeignCallArray) {