Encrypted Transfer Execution

Protocol Overview

The Encrypted Transfer mechanism allows users to send assets to other stealth addresses without the funds ever leaving the privacy pool. Unlike deposits (Public \to Private) or withdrawals (Private \to Public), this operation is Private \to Private.

To an external observer, the transaction appears only as a cryptographic proof validation and an update to the Merkle Tree. The sender, recipient, and asset amount remain mathematically opaque.


Sender Workflow: Construction & Encryption

The transfer process is executed entirely client-side to ensure zero-knowledge integrity.

1. UTXO Selection

The wallet algorithmically selects the optimal set of input notes to satisfy the transfer amount.

  • Optimization: The system prioritizes older notes or exact matches to minimize fragmentation.

  • Proof of Ownership: For each selected input, the client generates a Nullifier using the private spending key. This proves ownership and prevents double-spending without revealing the specific note.

2. Output Commitment Generation

The client constructs two new Commitments (Hashes). Crucially, the Recipient's Commitment is derived using a random secret that the sender generates.

Commitmentrecipient=PoseidonHash(Secretnew,Amount,Randomness,Token)Commitment_{recipient} = \text{PoseidonHash}(Secret_{new}, Amount, Randomness, Token)

At this stage, the Commitment is just a hash. The contract can store it, but the Recipient cannot "claim" it yet because they don't know the or .

3. Asymmetric Note Encryption

To transfer ownership, the Sender must securely transmit the note details (, , etc.) to the Recipient. This is done on-chain via Integrated Encryption.

  • Key Exchange: The sender retrieves the recipient's Public Viewing Key.

  • Encryption: The note data is encrypted (using ECIES or similar asymmetric scheme).

  • Payload: The encrypted "Ciphertext" is attached to the transaction as public call data.

Only the holder of the corresponding Private Viewing Key (the recipient) can decrypt this payload.


On-Chain Execution

The Smart Contract acts as a verifier and data availability layer. It performs three critical actions:

1. Verification

It verifies the Zero-Knowledge Proof, confirming:

  • The Nullifiers are valid (inputs exist and are owned by sender).

  • The Sum of Inputs equals the Sum of Outputs.

  • The new Commitments are well-formed.

2. State Mutation

  • Nullification: The Input Nullifiers are marked as true in the global state, permanently destroying the spent notes.

  • Accrual: The new Commitments (Recipient's note and Sender's change) are inserted into the Merkle Tree.

3. Event Emission

The contract emits a Transfer event containing the Encrypted Ciphertext. This logs the data permanently on the blockchain, allowing the recipient to retrieve it asynchronously.


Recipient Workflow: Trial Decryption

In a private system, there is no public "To: Address" field. Therefore, the recipient does not inherently know when they have received funds. We utilize a Trial Decryption (Scanning) mechanism.

The Scanning Loop

The recipient's wallet periodically scans the blockchain for new Transfer events.

  1. Fetch: Download the Encrypted Ciphertext from recent events.

  2. Attempt Decrypt: The wallet attempts to decrypt the ciphertext using the user's Private Viewing Key.

  3. Outcome:

    • Failure: The decryption produces garbage data. This means the transaction belongs to someone else. The wallet ignores it.

    • Success: The decryption yields a valid JSON object containing an Amount and Secret. This confirms the transaction is intended for the user.

Local State Update

Upon successful decryption, the wallet reconstructs the Commitment locally and verifies that it exists in the on-chain Merkle Tree. The note is then added to the user's local database with a status of Unspent.

Last updated