aztec-packages icon indicating copy to clipboard operation
aztec-packages copied to clipboard

Consider whether a contract init nullifier should contain the salt

Open iAmMichaelConnor opened this issue 3 months ago • 6 comments

Observation from Nico (paraphrased):

Currently, knowledge of an address is enough to know whether that address has be initialized.

Of course, any contract with public functions is publicly known to have been initialized, but private-function-only contracts could in theory be initialized without leaking that fact.

The only real leak would be that if an address interacts with you and it's not inited, then it's not one part of a certain family of acct contracts that do have init fns. Maybe not a huge deal.

I suppose if it's an account contract, and a particular FPC and token is used to pay fees, this info then places the user in an anonymity set relating to that fee pattern. So every subsequent tx with that fee fingerprint could be that user. That's not ideal. [Aside: we're revisiting FPC leakage].

A solution (as proposed by Nico) would be to do something like:

nullifier = hash(contract_address, salt)

or

nullifier = hash(contract_address, init_hash)

or

nullifier = hash(contract_address, keys_hash)

... with the assumption that a user can keep the 2nd argument to themselves*.

*That is, unless the user wants to enable someone to do a transferFrom which makes an authwit call into their account contract, and hence requires access to their address preimage.

iAmMichaelConnor avatar Sep 17 '25 18:09 iAmMichaelConnor

cc @LeilaWang @sirasistant @nventuro @spalladino

The notion that initializing an account contract could place the user in a small anonymity set (by association with a particular fpc) is enough to make this change worthy of consideration

iAmMichaelConnor avatar Sep 30 '25 16:09 iAmMichaelConnor

That sounds like a good idea to me, and it doesn't affect the protocol, so 👍

spalladino avatar Sep 30 '25 17:09 spalladino

it doesn't affect the protocol

Doesn't the AVM read this nullifier to determine whether the contract has actually been published?

iAmMichaelConnor avatar Oct 02 '25 10:10 iAmMichaelConnor

Doesn't the AVM read this nullifier to determine whether the contract has actually been published?

IIRC the AVM needs to check the public deployment nullifier, but not the initialization nullifier. The former is emitted by the ContractInstancePublisher, while the latter is emitted by the contract itself.

It's possible this has changed though.

spalladino avatar Oct 02 '25 14:10 spalladino

@sirasistant

iAmMichaelConnor avatar Oct 23 '25 09:10 iAmMichaelConnor

Yes, that's the case. The AVM uses the deployment nullifier to decide to allow the call to be made or not https://github.com/AztecProtocol/aztec-packages/blob/next/barretenberg/cpp/pil/vm2/bytecode/contract_instance_retrieval.pil#L136 Then, the bytecode for the contract has the initialization checks that aztec-nr considers necessary to create. This task is a pure aztec-nr macros thing, no protocol contracts or protocol changes required.

sirasistant avatar Oct 31 '25 12:10 sirasistant