Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add increment tagging secret oracles #9573

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions noir-projects/aztec-nr/aztec/src/oracle/notes.nr
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,16 @@ unconstrained fn get_app_tagging_secret_oracle(
_recipient: AztecAddress,
) -> [Field; INDEXED_TAGGING_SECRET_LENGTH] {}

pub unconstrained fn increment_app_tagging_secret(sender: AztecAddress, recipient: AztecAddress) {
increment_app_tagging_secret_oracle(sender, recipient);
}

#[oracle(incrementAppTaggingSecret)]
unconstrained fn increment_app_tagging_secret_oracle(
_sender: AztecAddress,
_recipient: AztecAddress,
) {}

/// 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.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::traits::Deserialize;
use crate::traits::{Deserialize, Serialize};
use super::address::aztec_address::AztecAddress;
use std::meta::derive;

pub global INDEXED_TAGGING_SECRET_LENGTH: u32 = 3;

#[derive(Deserialize)]
#[derive(Serialize, Deserialize)]
pub struct IndexedTaggingSecret {
secret: Field,
recipient: AztecAddress,
Expand Down
10 changes: 9 additions & 1 deletion yarn-project/circuits.js/src/structs/tagging_secret.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type AztecAddress } from '@aztec/foundation/aztec-address';
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { Fr } from '@aztec/foundation/fields';

export class TaggingSecret {
Expand All @@ -17,4 +17,12 @@ export class IndexedTaggingSecret extends TaggingSecret {
override toFields(): Fr[] {
return [this.secret, this.recipient, new Fr(this.index)];
}

static fromFields(serialized: Fr[]) {
return new this(serialized[0], AztecAddress.fromField(serialized[1]), serialized[2].toNumber());
}

static fromTaggingSecret(directionalSecret: TaggingSecret, index: number) {
return new this(directionalSecret.secret, directionalSecret.recipient, index);
}
}
2 changes: 1 addition & 1 deletion yarn-project/pxe/src/database/kv_pxe_database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ export class KVPxeDatabase implements PxeDatabase {
const indexes = await this.getTaggingSecretsIndexes(appTaggingSecretsWithRecipient);
await this.db.transaction(() => {
indexes.forEach((taggingSecretIndex, listIndex) => {
const nextIndex = taggingSecretIndex ? taggingSecretIndex + 1 : 1;
const nextIndex = taggingSecretIndex + 1;
const { secret, recipient } = appTaggingSecretsWithRecipient[listIndex];
const key = `${secret.toString()}-${recipient.toString()}`;
void this.#taggingSecretIndexes.set(key, nextIndex);
Expand Down
24 changes: 22 additions & 2 deletions yarn-project/pxe/src/simulator_oracle/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,15 +255,35 @@ export class SimulatorOracle implements DBOracle {
sender: AztecAddress,
recipient: AztecAddress,
): Promise<IndexedTaggingSecret> {
const directionalSecret = await this.#calculateDirectionalSecret(contractAddress, sender, recipient);
const [index] = await this.db.getTaggingSecretsIndexes([directionalSecret]);
return IndexedTaggingSecret.fromTaggingSecret(directionalSecret, index);
}

/**
* Increments the tagging secret for a given sender and recipient pair. For this to work, the ivpsk_m of the sender must be known.
* @param contractAddress - The contract address to silo the secret for
* @param sender - The address sending the note
* @param recipient - The address receiving the note
*/
public async incrementAppTaggingSecret(
contractAddress: AztecAddress,
sender: AztecAddress,
recipient: AztecAddress,
): Promise<void> {
const directionalSecret = await this.#calculateDirectionalSecret(contractAddress, sender, recipient);
await this.db.incrementTaggingSecretsIndexes([directionalSecret]);
}

async #calculateDirectionalSecret(contractAddress: AztecAddress, sender: AztecAddress, recipient: AztecAddress) {
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
const siloedSecret = poseidon2Hash([sharedSecret.x, sharedSecret.y, contractAddress]);
// Get the index of the secret, ensuring the directionality (sender -> recipient)
const directionalSecret = new TaggingSecret(siloedSecret, recipient);
const [index] = await this.db.getTaggingSecretsIndexes([directionalSecret]);
return new IndexedTaggingSecret(siloedSecret, recipient, index);
return directionalSecret;
}

/**
Expand Down
7 changes: 7 additions & 0 deletions yarn-project/simulator/src/acvm/oracle/oracle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,13 @@ export class Oracle {
return taggingSecret.toFields().map(toACVMField);
}

async incrementAppTaggingSecret([sender]: ACVMField[], [recipient]: ACVMField[]) {
await this.typedOracle.incrementAppTaggingSecret(
AztecAddress.fromString(sender),
AztecAddress.fromString(recipient),
);
}

async getAppTaggingSecretsForSenders([recipient]: ACVMField[]): Promise<ACVMField[]> {
const taggingSecrets = await this.typedOracle.getAppTaggingSecretsForSenders(AztecAddress.fromString(recipient));
return taggingSecrets.flatMap(taggingSecret => taggingSecret.toFields().map(toACVMField));
Expand Down
4 changes: 4 additions & 0 deletions yarn-project/simulator/src/acvm/oracle/typed_oracle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,10 @@ export abstract class TypedOracle {
throw new OracleMethodNotAvailableError('getAppTaggingSecret');
}

incrementAppTaggingSecret(_sender: AztecAddress, _recipient: AztecAddress): Promise<void> {
throw new OracleMethodNotAvailableError('incrementAppTaggingSecret');
}

getAppTaggingSecretsForSenders(_recipient: AztecAddress): Promise<IndexedTaggingSecret[]> {
throw new OracleMethodNotAvailableError('getAppTaggingSecretsForSenders');
}
Expand Down
4 changes: 4 additions & 0 deletions yarn-project/simulator/src/client/client_execution_context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -609,4 +609,8 @@ export class ClientExecutionContext extends ViewDataOracle {
public getDebugFunctionName() {
return this.db.getDebugFunctionName(this.contractAddress, this.callContext.functionSelector);
}

public override async incrementAppTaggingSecret(sender: AztecAddress, recipient: AztecAddress) {
await this.db.incrementAppTaggingSecret(this.contractAddress, sender, recipient);
}
}
12 changes: 12 additions & 0 deletions yarn-project/simulator/src/client/db_oracle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,18 @@ export interface DBOracle extends CommitmentsDB {
recipient: AztecAddress,
): Promise<IndexedTaggingSecret>;

/**
* Increments the tagging secret for a given sender and recipient pair. For this to work, the ivpsk_m of the sender must be known.
* @param contractAddress - The contract address to silo the secret for
* @param sender - The address sending the note
* @param recipient - The address receiving the note
*/
incrementAppTaggingSecret(
contractAddress: AztecAddress,
sender: AztecAddress,
recipient: AztecAddress,
): Promise<void>;

/**
* 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
Expand Down
18 changes: 15 additions & 3 deletions yarn-project/txe/src/oracle/txe_oracle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -756,14 +756,26 @@ export class TXE implements TypedOracle {
return;
}

async incrementAppTaggingSecret(sender: AztecAddress, recipient: AztecAddress): Promise<void> {
const directionalSecret = await this.#calculateDirectionalSecret(this.contractAddress, sender, recipient);
await this.txeDatabase.incrementTaggingSecretsIndexes([directionalSecret]);
}

async getAppTaggingSecret(sender: AztecAddress, recipient: AztecAddress): Promise<IndexedTaggingSecret> {
const directionalSecret = await this.#calculateDirectionalSecret(this.contractAddress, sender, recipient);
const [index] = await this.txeDatabase.getTaggingSecretsIndexes([directionalSecret]);
return IndexedTaggingSecret.fromTaggingSecret(directionalSecret, index);
}

async #calculateDirectionalSecret(contractAddress: AztecAddress, sender: AztecAddress, recipient: AztecAddress) {
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
const secret = poseidon2Hash([sharedSecret.x, sharedSecret.y, this.contractAddress]);
const [index] = await this.txeDatabase.getTaggingSecretsIndexes([new TaggingSecret(secret, recipient)]);
return new IndexedTaggingSecret(secret, recipient, index);
const siloedSecret = poseidon2Hash([sharedSecret.x, sharedSecret.y, contractAddress]);
// Get the index of the secret, ensuring the directionality (sender -> recipient)
const directionalSecret = new TaggingSecret(siloedSecret, recipient);
return directionalSecret;
}

async getAppTaggingSecretsForSenders(recipient: AztecAddress): Promise<IndexedTaggingSecret[]> {
Expand Down
Loading