Skip to content

Commit

Permalink
refactor: tagging cleanup (#10675)
Browse files Browse the repository at this point in the history
  • Loading branch information
benesjan authored Dec 13, 2024
1 parent 95eb658 commit 52b541a
Show file tree
Hide file tree
Showing 19 changed files with 231 additions and 157 deletions.
9 changes: 6 additions & 3 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -275,11 +275,12 @@
"unexcluded",
"unfinalised",
"unprefixed",
"unshift",
"unshifted",
"unsynched",
"unzipit",
"updateable",
"upperfirst",
"unshift",
"unshifted",
"usecase",
"usecases",
"utxo",
Expand Down Expand Up @@ -323,5 +324,7 @@
"lib",
"*.cmake"
],
"flagWords": ["anonymous"]
"flagWords": [
"anonymous"
]
}
2 changes: 1 addition & 1 deletion noir-projects/aztec-nr/aztec/src/encrypted_logs/payload.nr
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ mod test {
0x25afb798ea6d0b8c1618e50fdeafa463059415013d3b7c75d46abf5e242be70c,
);

let _ = OracleMock::mock("getAppTaggingSecretAsSender").returns([69420, 1337]);
let _ = OracleMock::mock("getIndexedTaggingSecretAsSender").returns([69420, 1337]);

let _ = OracleMock::mock("incrementAppTaggingSecretIndexAsSender").returns(());

Expand Down
14 changes: 7 additions & 7 deletions noir-projects/aztec-nr/aztec/src/oracle/notes.nr
Original file line number Diff line number Diff line change
Expand Up @@ -205,25 +205,25 @@ pub unconstrained fn check_nullifier_exists(inner_nullifier: Field) -> bool {
#[oracle(checkNullifierExists)]
unconstrained fn check_nullifier_exists_oracle(_inner_nullifier: Field) -> Field {}

/// Same as `get_app_tagging_secret_as_sender`, except it returns the derived tag, ready to be included in a log.
/// Same as `get_indexed_tagging_secret_as_sender`, except it returns the derived tag, ready to be included in a log.
pub unconstrained fn get_app_tag_as_sender(sender: AztecAddress, recipient: AztecAddress) -> Field {
get_app_tagging_secret_as_sender(sender, recipient).compute_tag(recipient)
get_indexed_tagging_secret_as_sender(sender, recipient).compute_tag(recipient)
}

/// Returns the tagging secret for a given sender and recipient pair, siloed for the current contract address.
/// Includes the last known index used to send a note tagged with this secret.
/// For this to work, PXE must know the ivpsk_m of the sender.
/// For this to work, PXE must know the ivsk_m of the sender.
/// For the recipient's side, only the address is needed.
pub unconstrained fn get_app_tagging_secret_as_sender(
pub unconstrained fn get_indexed_tagging_secret_as_sender(
sender: AztecAddress,
recipient: AztecAddress,
) -> IndexedTaggingSecret {
let result = get_app_tagging_secret_as_sender_oracle(sender, recipient);
let result = get_indexed_tagging_secret_as_sender_oracle(sender, recipient);
IndexedTaggingSecret::deserialize(result)
}

#[oracle(getAppTaggingSecretAsSender)]
unconstrained fn get_app_tagging_secret_as_sender_oracle(
#[oracle(getIndexedTaggingSecretAsSender)]
unconstrained fn get_indexed_tagging_secret_as_sender_oracle(
_sender: AztecAddress,
_recipient: AztecAddress,
) -> [Field; INDEXED_TAGGING_SECRET_LENGTH] {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ pub global INDEXED_TAGGING_SECRET_LENGTH: u32 = 2;

#[derive(Serialize, Deserialize)]
pub struct IndexedTaggingSecret {
secret: Field,
app_tagging_secret: Field,
index: u32,
}

impl IndexedTaggingSecret {
pub fn compute_tag(self, recipient: AztecAddress) -> Field {
poseidon2_hash([self.secret, recipient.to_field(), self.index as Field])
poseidon2_hash(
[self.app_tagging_secret, recipient.to_field(), self.index as Field],
)
}
}
3 changes: 2 additions & 1 deletion yarn-project/circuits.js/src/keys/derivation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ export function deriveKeys(secretKey: Fr) {
};
}

export function computeTaggingSecret(knownAddress: CompleteAddress, ivsk: Fq, externalAddress: AztecAddress) {
// Returns shared tagging secret computed with Diffie-Hellman key exchange.
export function computeTaggingSecretPoint(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 externalAddressPoint = externalAddress.toAddressPoint();
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/circuits.js/src/structs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export * from './gas_fees.js';
export * from './gas_settings.js';
export * from './global_variables.js';
export * from './block_header.js';
export * from './tagging_secret.js';
export * from './indexed_tagging_secret.js';
export * from './kernel/combined_accumulated_data.js';
export * from './kernel/combined_constant_data.js';
export * from './kernel/private_kernel_empty_inputs.js';
Expand Down
40 changes: 40 additions & 0 deletions yarn-project/circuits.js/src/structs/indexed_tagging_secret.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { type AztecAddress } from '@aztec/foundation/aztec-address';
import { poseidon2Hash } from '@aztec/foundation/crypto';
import { Fr } from '@aztec/foundation/fields';

export class IndexedTaggingSecret {
constructor(public appTaggingSecret: Fr, public index: number) {}

toFields(): Fr[] {
return [this.appTaggingSecret, new Fr(this.index)];
}

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

/**
* Computes the tag based on the app tagging secret, recipient and index.
* @dev By including the recipient we achieve "directionality" of the tag (when sending a note in the other
* direction, the tag will be different).
* @param recipient The recipient of the note
* @returns The tag.
*/
computeTag(recipient: AztecAddress) {
return poseidon2Hash([this.appTaggingSecret, recipient, this.index]);
}

/**
* Computes the tag as it is submitted on-chain.
* @dev We do this second layer of siloing (one was already done as the tagging secret is app-siloed) because kernels
* do that to protect against contract impersonation attacks. This extra layer of siloing in kernels ensures that
* a malicious contract cannot emit a note with a tag corresponding to another contract.
* @param recipient The recipient of the note
* @param app The app address
* @returns The tag as it is submitted on-chain in a log.
*/
computeSiloedTag(recipient: AztecAddress, app: AztecAddress) {
const tag = this.computeTag(recipient);
return poseidon2Hash([app, tag]);
}
}
24 changes: 0 additions & 24 deletions yarn-project/circuits.js/src/structs/tagging_secret.ts

This file was deleted.

4 changes: 3 additions & 1 deletion yarn-project/pxe/src/database/kv_pxe_database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,9 @@ export class KVPxeDatabase implements PxeDatabase {

async #setTaggingSecretsIndexes(indexedSecrets: IndexedTaggingSecret[], storageMap: AztecAsyncMap<string, number>) {
await Promise.all(
indexedSecrets.map(indexedSecret => storageMap.set(indexedSecret.secret.toString(), indexedSecret.index)),
indexedSecrets.map(indexedSecret =>
storageMap.set(indexedSecret.appTaggingSecret.toString(), indexedSecret.index),
),
);
}

Expand Down
Loading

0 comments on commit 52b541a

Please sign in to comment.