Hush Privacy Protocol

Privacy-preserving shielded transactions using Miden STARK zero-knowledge proofs

Shield, transfer, and unshield tokens with cryptographic guarantees that deposits cannot be linked to withdrawals.

No Trusted Setup
Quantum Resistant
OFAC Compliant

Operations

Three core operations enable privacy-preserving transactions with cryptographic guarantees

Shield (Deposit)

Shielding moves tokens from Solana into the privacy pool.

Client

Generate spending_key, derive note_secret and randomness, compute commitment

Solana

Call shield instruction - tokens transfer from wallet to program vault

Sidecar

Detect shield event, run CipherOwl OFAC check on shielder address

zrchain

If clean, add commitment to Merkle tree, create voucher (ACTIVE immediately)

Client

Store secrets locally for later proof generation

The shielder's Solana address is screened but not stored on zrchain - filtering happens at the sidecar.

Unshield (Withdraw)

Unshielding moves tokens from the privacy pool back to a Solana address. The ZK proof ensures the withdrawal is valid without revealing which deposit is being spent.

Client

Load spending_key, query current Merkle root

Client

Generate STARK proof proving knowledge of a valid commitment and correct nullifier derivation

zrchain

Verify proof, check nullifier hasn't been spent, mark as spent

zrchain

Create UnshieldRequest, build Solana transfer transaction

MPC

Sign transaction, sidecar broadcasts to Solana

Confirmation

Sidecar detects completion, updates request status

The unshield amount is visible on Solana after completion. Privacy comes from unlinkability - observers cannot determine which shield was spent.

Shielded Transfer

Transfers within the privacy pool. Amounts are encrypted - only the recipient can decrypt.

Sender

Generate ephemeral keypair, compute recipient and change commitments

Sender

Encrypt amounts using ECDH shared secret with recipient's public viewing key

Sender

Generate STARK proof, submit MsgShieldedTransfer

zrchain

Verify proof, add new commitments to Merkle tree, emit event

Recipient

Scan chain events, attempt ECDH decryption to find transfers addressed to them

Privacy: Transfer sender/recipient link is hidden. Amounts are fully encrypted.

Cryptographic Design

Built on Miden STARKs for quantum-resistant, trustless privacy

Why Miden STARKs

  • No trusted setup (unlike Groth16/PLONK)
  • Hash-based, does not rely on algebraic assumptions broken by Shor's algorithm
  • Configured for ≥128-bit classical security, providing post-quantum resistance
  • Native RPO hash is efficient in-circuit

Primitives

PrimitiveImplementationPurpose
HashRPO (Rescue Prime Optimized)ZK-friendly, native to Miden
Merkle TreeSparse binary, depth 20~1M commitment capacity
Proof SystemMiden STARKsZK proof generation/verification
Key ExchangeX25519 ECDHStealth addresses for transfers
Amount EncryptionChaCha20-Poly1305Shielded transfer amounts, voucher recovery
Key DerivationSHA-256Voucher amount encryption keys

Comparison

How Hush compares to other privacy protocols

FeatureHushZcashTornado Cash
Proof System
Miden STARKs
Groth16/Halo2Groth16
Trusted Setup
No
YesYes
Quantum Resistant
Yes
PartialNo
Flexible Amounts
Yes (UTXO)
YesNo
Shielded Transfers
Yes
YesNo
Viewing Keys
Yes (tiered)
YesNo
Wallet Recovery
Yes (Seed phrase)
Seed phraseManual
Compliance
Built-in
OptionalNone

Privacy Model

Understand what's hidden and what's public in Hush transactions

Hidden

  • Link between shield and unshield
  • Depositor identity
  • Transfer sender/recipient link
  • Shielded transfer amounts

Public

  • Unshield amount (visible on Solana)
  • Merkle root in proof (approximate timing)
  • Nullifier (prevents double-spend)
  • Recipient address (unshield only)

Maximizing Privacy

Best practices for maintaining anonymity in your transactions

Use Standard Denominations

Custom amounts make correlation easier. The UI provides standard amounts: 0.1, 1, 10, 100, 1000.

Custom amounts reduce anonymity

Wait Before Unshielding

Immediate unshield after shield creates timing correlation. Wait some time between operations.

Use Different Networks

Don't use the same IP for shield and unshield. Consider Tor/VPN for unshield operations.

Standard Denominations

Using standard amounts helps maintain anonymity by making transactions indistinguishable.

0.1
Small
1
Standard
10
Medium
100
Large
1000
Whale
Custom
Reduces anonymity

OFAC Compliance

Built-in compliance screening for all shield operations

Shield events are screened at the sidecar using CipherOwl. The shielder address is not propagated to zrchain, ensuring privacy while maintaining compliance.

Screening Process

1
User shields on Solana
Shielder address in event
2
Sidecar runs CipherOwl
Batch check on address
3
Sanctioned
Event dropped, tokens remain in vault, no voucher
4
Clean
Event reported to zrchain via vote extensions

Privacy Preserved: The shielder address is not stored on zrchain. Filtering happens at the sidecar level, maintaining the privacy guarantees of the protocol.

Key Hierarchy

Tiered viewing keys enable flexible privacy and auditing capabilities

spending_key

Root secret - never share

Spend
See Spent
Decrypt Received
Decrypt Sent

full_viewing_key

For auditors

Spend
See Spent
Decrypt Received
Decrypt Sent

incoming_viewing_key

Receive only

Spend
See Spent
Decrypt Received
Decrypt Sent

Key Derivation

note_secret
Derived from spending key
RPO(spending_key || NOTE_SECRET_DOMAIN || voucher_index)
nullifier_key
Used for spending verification
RPO(spending_key || NULLIFIER_KEY_DOMAIN)
Commitment
Added to Merkle tree
Step 1
step1 = RPO_merge(note_secret, randomness)
Step 2
commitment = RPO_merge(step1, [0, 0, 0, amount])
Nullifier
Revealed at unshield
nullifier = RPO_merge(nullifier_key, commitment)

Viewing Key Access: The nullifier formula allows full_viewing_key holders to compute nullifiers and verify spent status without spending capabilities.

Fees and Supply

Fee Structure

OperationFee TypePolicy
ShieldPercentageZero (encourage pool growth)
Shielded TransferFlatFixed per transfer, burned
UnshieldPercentage% of amount, deducted before transfer

Supply Accounting

TotalShielded
Currently in privacy pool
PendingUnshields
Awaiting withdrawal
TotalUnshielded
Successfully withdrawn
TotalFeesBurned
Fees removed from supply
+
+
+
=
Total Ever Shielded
Sum of all token states

Every token is accounted for. Whether shielded in the pool, pending withdrawal, successfully unshielded, or burned as fees—the total remains constant and verifiable.

Supported Assets

Privacy-preserving transactions for multiple Solana assets

jitoSOL

solana/programs/hush-sol

Deployed

zenBTC

solana/programs/zenbtc

Coming Soon

zenZEC

solana/programs/zenzec

Coming Soon

ROCK

solana/programs/rock

Coming Soon

USDC

solana/programs/usdc

Coming Soon