JoinSplit Circuit
Details of JoinSplit circuit, including PIs, encodings, and constraints (in english)
High-Level Statement
Prove that all of the following are true:
both input notes exist in the commitment tree
the user owns both input notes
all four notes are for the same asset
the total value of the input notes equals the total value of the output notes plus the amount being unwrapped (the "public spend")
the owner of those assets could produce a valid signature over the hash of an associated operation.
Public Inputs
The JoinSplit circuit has a total of 13 public inputs:
operationDigest: The hash of the operation the JoinSplit is associated with. The hash is computed outside the circuit usingkeccak256and is reduced modulo to an element of .encodedAssetId: The theencodedAssetIdfield of the encoded asset being spentencodedAssetAddrWithSignBits: TheencodedAssetAddrfield of the encoded asset being spent, but with the sign bits corresponding torefundAddrH1CompressedYandrefundAddrH2CompressedYpacked-in.refundAddrH1CompressedY: The Y-coordinate of the compressed encoding of the first component of the refund address in the associated operationrefundAddrH2CompressedY: The Y-coordinate of the compressed encoding of the second component of the refund address in the associated operationnewNoteACommitment: The note commitment for the first output notenewNoteBCommitment: The note commitment for the second output notecommitmentTreeRoot: The current commitment tree rootpublicSpend: The amount to unwrap publiclynullifierA: The nullifier for the first input notenullifierB: The nullifier for the second input notesenderCommitment: A blinded commitment to the sender of the operation. This allows the recipient to know the canonical address of whoever is paying them.joinSplitInfoCommitment: A blinded commitment to the details of the JoinSplit (sender, recipient, notes being spent, etc.) enabling individuals to selectively disclose transaction details if they want to.
Private Data
vk: the viewing keyvkNonce: the nonce used in viewing key derivationspendPK: the spending public key(c, z): a Schnorr signature ofopDigestoldNoteA: anEncodedNoterepresenting the first input noteoldNoteB: anEncodedNoterepresenting the second input notenewNoteA: anEncodedNoterepresenting the first output notenewNoteB: anEncodedNoterepresenting the second output noteMembershipProofA: a Merkle membership proof foroldNoteA's note commitment in the commitment treeMembershipProofB: a Merkle membership proof foroldNoteB's note commitment in the commitment treereceiverCanonAddr: the canonical address of the receiversenderCanonAddr: the canonical address of the receiver
Constraints
vkandvkNoncecorrectly correspond tospendPksenderCanonAddris indeed the canonical address corresponding tovkthe signature
(c, z)is a valid signature ofopDigestoldNoteA.ownerandoldNoteB.ownerare well-formed stealth addressesoldNoteA.ownerandoldNoteB.ownerare both owned byvkthe refund address provided via
refundAddrH1CompressedY,refundAddrH2CompressedY, and their associated sign bits fromencodedAssetAddrWithSignBitsis a valid stealth address owned byvkMembershipProofA.leafis the note commitment foroldNoteAMembershipProofB.leafis the note commitment foroldNoteB, oroldNoteB.value = 0(we don't care aboutoldNoteBif its value is0)MembershipProofAis a valid Merkle membership proof againstcommitmentTreeRootMembershipProofBis a valid Merkle membership proof againstcommitmentTreeRoot, oroldNoteB.value = 0(we don't care aboutoldNoteBif its value is0)newNoteA.owneris the sender's canonical stealth addressnewNoteB.owneris the receiver's canonical stealth addressoldNoteA.value + oldNoteB.value = newNoteA.value + newNoteB.value + publicSpendnewNoteACommitmentis the correct note commitment fornewNoteAnewNoteBCommitmentis the note commitment fornewNoteBsenderCommitmentis computed correctlyjoinSplitInfoCommitmentis computed correctly
Last updated