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 usingkeccak256
and is reduced modulo to an element of .encodedAssetId
: The theencodedAssetId
field of the encoded asset being spentencodedAssetAddrWithSignBits
: TheencodedAssetAddr
field of the encoded asset being spent, but with the sign bits corresponding torefundAddrH1CompressedY
andrefundAddrH2CompressedY
packed-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 ofopDigest
oldNoteA
: anEncodedNote
representing the first input noteoldNoteB
: anEncodedNote
representing the second input notenewNoteA
: anEncodedNote
representing the first output notenewNoteB
: anEncodedNote
representing 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
vk
andvkNonce
correctly correspond tospendPk
senderCanonAddr
is indeed the canonical address corresponding tovk
the signature
(c, z)
is a valid signature ofopDigest
oldNoteA.owner
andoldNoteB.owner
are well-formed stealth addressesoldNoteA.owner
andoldNoteB.owner
are both owned byvk
the refund address provided via
refundAddrH1CompressedY
,refundAddrH2CompressedY
, and their associated sign bits fromencodedAssetAddrWithSignBits
is a valid stealth address owned byvk
MembershipProofA.leaf
is the note commitment foroldNoteA
MembershipProofB.leaf
is the note commitment foroldNoteB
, oroldNoteB.value = 0
(we don't care aboutoldNoteB
if its value is0
)MembershipProofA
is a valid Merkle membership proof againstcommitmentTreeRoot
MembershipProofB
is a valid Merkle membership proof againstcommitmentTreeRoot
, oroldNoteB.value = 0
(we don't care aboutoldNoteB
if its value is0
)newNoteA.owner
is the sender's canonical stealth addressnewNoteB.owner
is the receiver's canonical stealth addressoldNoteA.value + oldNoteB.value = newNoteA.value + newNoteB.value + publicSpend
newNoteACommitment
is the correct note commitment fornewNoteA
newNoteBCommitment
is the note commitment fornewNoteB
senderCommitment
is computed correctlyjoinSplitInfoCommitment
is computed correctly
Last updated