Private Swap
A Groth16 proof authorizes an input note spend and verifies its public CPMM settlement without publishing the private note witness.
Private Swap spends a Shielded Note into the public CPMM and creates a new output note, plus a change note when the selected input exceeds the swap input. It does not make the pool, transaction, or swap amount private.
Public statement
The production circuit has 22 public field inputs. At the semantic level these bind the domain, pool, input/output assets, accepted root and sequence, tree generation, nullifier, pre-swap reserves, fee tier, input/output amounts, change amount, change/output commitments, direction, statement version and pool swap nonce. The exact flattened field order is in the Private Swap circuit reference.
Core recomputes the public statement from the supplied pool accounts and instruction arguments before verifying the proof. A caller cannot substitute another pool, reserve state, fee, direction, amount, commitment or nonce while keeping the proof valid.
Private witness
The witness contains the input spend secret, input randomness and 16-level Merkle path, plus the authorization material and randomness for the change and output notes. The proof connects that private witness to the public nullifier, accepted root, CPMM equation and public commitments.
What is verified
- The input note commitment matches the hidden note preimage and owner commitment.
- The commitment is a leaf under the stated Merkle root and generation.
- The supplied spend secret derives the public nullifier.
- The fee tier and fee-adjusted CPMM output are correct for the public reserves.
- The hidden input note value equals
amount_in + change_amount. - The output commitment represents the public output amount; nonzero change matches its public commitment.
- Core initializes the canonical spent-nullifier PDA, settles the tokens and appends the output commitments.
What remains visible
The statement and PrivateSwapped event expose the pool, direction, amount_in, amount_out, input root/sequence/generation, nullifier, change/output commitments and append indexes. Reserves and custody account changes are visible on Solana. The event associates one nullifier with its newly emitted commitments, but does not expose the hidden input note commitment or its owner.
Fee Payer ≠ Trader when a relayer submits the prepared transaction. The relayer is visible and pays transaction costs; note ownership still comes from the private witness. Continue with Unshield or the full circuit layout.