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

Change tag computation to avoid revealing recipient and senders #9787

Open
Tracked by #9119
nventuro opened this issue Nov 6, 2024 · 0 comments
Open
Tracked by #9119

Change tag computation to avoid revealing recipient and senders #9787

nventuro opened this issue Nov 6, 2024 · 0 comments
Labels
C-aztec.nr Component: Aztec smart contract framework C-pxe Component: PXE (Private eXecution Envrionment) team-fairies Nico's team

Comments

@nventuro
Copy link
Contributor

nventuro commented Nov 6, 2024

#9786 describes how we can use all of the accounts in scope as recipients when choosing who to discover notes for. However, we shouldn't simply inject these values into a circuit because a malicious contract could then learn about all of the scoped accounts, therefore linking them together. This is similar to how we cannot return the contents of the address book, as described in #9365.

The current tag definition is

let tag: Field = poseidon2([app_siloed_secret, recipient_address, index]);

This is problematic because we want to compute the tag in circuit, which requires knowledge of the recipient. We could have an oracle that receives app_siloed_secret and index and returns the tag (since the app_siloed_secret implies a recipient, given we know the scoped accounts and we can infer it's one of them), but this is also leaky: armed with this information an attacker could brute force the small known-address space and still produce the list of unlocked accounts.

Instead, the proposed solution is to slightly change the definition of the tag. We need the recipient there for directionality (see #9373), but it doesn't need to necessarily be part of the tag preimage. Given a shared secret S, #9378 defines the app_siloed_secret as:

let s_app: Field = hash(S, app_address) = poseidon2([S.x, S.y, app_address]);

The proposed solution to having to reveal the recipient is to change the above definitions as follows, including the recipient inside s_app:

let app_siloed_secret: Field = hash(S, app_address, recipient) = poseidon2([S.x, S.y, app_address, recipient]);
let tag: Field = poseidon2([app_siloed_secret, index]);

Note that this results in different app siloed secrets when acting as a sender and recipient. This is fine - it's equivalent to having different sender/recipient tags - but it does mean the storage inside PXE requires changes.

When producing app siloed secrets in order to compute tags, the oracle call would not pass any sender or recipient, and the senders would implicitly be all accounts in the address book (which would not be revelead), and the recipients all unlocked accounts (also not revelead).

The one issue I can see maybe arising with this is that when discovering a note it's not necessarily clear to which account's note database it should be added to, since we will not know which recipient got it.

@nventuro nventuro added C-aztec.nr Component: Aztec smart contract framework C-pxe Component: PXE (Private eXecution Envrionment) team-fairies Nico's team labels Nov 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-aztec.nr Component: Aztec smart contract framework C-pxe Component: PXE (Private eXecution Envrionment) team-fairies Nico's team
Projects
None yet
Development

No branches or pull requests

1 participant