resource: https://github.com/0xPolygonMiden/miden-vm/discussions/356
This protocol thus provides a robust way to handle nullifiers without indefinite growth of the database, ensures privacy via epoch indexing, and offers performance optimizations through hash chains and sequential lookups. The discussion also highlights potential future research areas, such as the use of mutator sets or alternative approaches.
vault
: A map from asset IDs to balances.program
: A Miden program MAST.block_number
: The block number of the note creation.serial_num
: A user-provided identifier.serial_num
, i.e., nullifier = hash([serial_num])
.hash([vault.root], [program.root], [block_number], [serial_num])
.s_n
) is the one actively updated as nullifiers are consumed during an epoch.N
blocks, the current nullifier tree (s_n
) is frozen (no further updates) and a new empty tree (s_(n+1)
) is created for the next epoch.e
). Each key in this tree is the root of a frozen epoch's nullifier tree, and the corresponding value is the block number at which that epoch was frozen (i*N
).To consume a note, the following checks need to be performed:
s_n
).block_number
is greater than N
, non-membership proofs must be provided for each previous epoch’s nullifier trie. This involves proving that the nullifier does not exist in any trie from epoch ⌊r/N⌋
to s_(n-1)
(where r
is the note's block number).This is done using:
s_n
) to show non-membership.s_i
), if applicable.