Note Commitment and Nullifier Formulas v1¶
Status: frozen for TKT-P3-36.
Purpose: define one canonical encoding and hash policy for note commitments and nullifiers used by prover/wallet/covenant integrations.
1. Canonical implementations¶
The canonical implementation surface is:
@bch-stealth/zk-notespackages/zk-notes/src/commitment_nullifier_v1.tspackages/zk-notes/src/note_tree_v1.ts(NoteLeafV1encoding/hash primitives)
Downstream packages (wallet validation, planner, backend adapters) must consume these helpers and must not fork formula logic.
2. Note commitment v1¶
2.1 Leaf structure and ordering¶
NoteLeafV1 is encoded in this exact order:
version = "NLeaf1"(6 ASCII bytes)poolId32shardId32ownerCommitment32valueCommitment32nonce32
2.2 Note commitment formula¶
noteCommitment32 = HASH256("NTL1" || encodeNoteLeafV1(noteLeaf))
No field reordering, shortening, or alternative domain tags are valid.
3. Nullifier formula v1¶
3.1 Domain tag¶
NULLIFIER_DERIVE_V1_DOMAIN_ASCII = "P3-16:nullifier:v1"
3.2 Preimage ordering¶
Nullifier preimage order is frozen as:
- domain tag ASCII bytes
noteId32noteHash32senderPub33receiverSpendPub33shardId32
3.3 Nullifier formula¶
nullifier32 = HASH256(domain || noteId32 || noteHash32 || senderPub33 || receiverSpendPub33 || shardId32)
No domain substitutions and no field-order changes are allowed.
4. Serialization and reject rules¶
4.1 Byte constraints¶
noteId32,noteHash32,shardId32MUST be exactly 32 bytessenderPub33,receiverSpendPub33MUST be exactly 33 bytes- all
NoteLeafV132-byte fields MUST be exactly 32 bytes
Malformed lengths MUST reject deterministically.
4.2 Hex constraints¶
Hex helper inputs MUST:
- be lowercase/uppercase hex-compatible (
[0-9a-fA-F]) - have even length
- have exact byte width for each field
Malformed hex MUST reject deterministically.
4.3 Formula mismatch checks¶
Validation code may assert expected commitments/nullifiers against recomputed values. Any mismatch (including domain-tag mutation or ordering mutation) MUST reject deterministically.
5. Vectors¶
Canonical vectors:
packages/zk-notes/test-vectors/commitment_nullifier_v1.json
The vector set includes:
- canonical valid note-commitment/nullifier cases
- malformed-length rejects
- malformed-hex rejects
- domain-tag mismatch reject case
- ordering mismatch reject case
6. Policy boundaries¶
- Derivation paths are wallet policy and not part of formula validity.
- Receiver identity model remains
(A, B)at ownership layer; formulas consume concrete byte inputs only.