Skip to content

Commit

Permalink
feat: add increment secret oracles (#9573)
Browse files Browse the repository at this point in the history
This PR adds the oracles to increment a tagging secret's index.
  • Loading branch information
sklppy88 authored Oct 31, 2024
1 parent feace70 commit 97a4c0c
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 9 deletions.
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

0 comments on commit 97a4c0c

Please sign in to comment.