Consider whether a contract init nullifier should contain the salt
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.
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
That sounds like a good idea to me, and it doesn't affect the protocol, so 👍
it doesn't affect the protocol
Doesn't the AVM read this nullifier to determine whether the contract has actually been published?
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.
@sirasistant
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.