Privacy Architecture
Obelysk uses two complementary privacy tracks that protect different aspects of your on-chain activity. Track 1 encrypts amounts using ElGamal. Track 2 uses a UTXO model with Poseidon2-M31 hashing for maximum correlation resistance. Both tracks connect through the VM31Bridge.
Track 1 โ ElGamal Privacy DeFi
Track 1 handles encrypted token operations. Amounts are hidden using ElGamal encryption on the STARK curve, and zero-knowledge Schnorr proofs verify correctness without revealing values.
Contract Architecture
ConfidentialTransfer โโโ Encrypted balances (ElGamal ciphertexts)
โ
โผ
PrivacyRouter โโโโโโโโโโ Multi-asset routing, nullifier tracking, auditor keys
โ
โโโโถ PrivacyPools (5x) โโ LeanIMT Merkle trees (ETH, STRK, USDC, wBTC, SAGE)
โ
โโโโถ ShieldedSwap โโโโโโโโ Privacy wrapper for Ekubo AMM
โ
โโโโถ DarkPool โโโโโโโโโโโโ Commit-reveal batch auctions, zero MEV
โ
โโโโถ StealthRegistry โโโโ Ephemeral one-time payment addresses
Every balance is stored as an ElGamal ciphertext: Enc(amount, randomness) = (g^amount ยท pk^r, g^r). Because ElGamal is additively homomorphic, the contract can update encrypted balances without ever decrypting them.
Contract Details
ConfidentialTransfer holds encrypted balances per address. You fund it with plaintext tokens, and all subsequent operations use ElGamal ciphertexts. Six Schnorr proofs verify each transfer: ownership, blinding, encryption, range, and two same-encryption proofs.
PrivacyRouter manages private balances across pools, handles nullifier tracking, and supports auditor keys for optional compliance. It coordinates deposits/withdrawals across all five privacy pools.
PrivacyPools (ETH, STRK, USDC, wBTC, SAGE) maintain LeanIMT Merkle trees (depth 20, supporting 1M+ deposits) of Pedersen commitments. Withdrawals prove membership via Merkle inclusion proofs and prevent double-spending with nullifiers.
ShieldedSwap routes private AMM swaps through Ekubo's ILocker interface. The swap router is the only address the AMM sees โ your identity stays completely hidden.
DarkPool runs commit-reveal batch auctions across 3 blocks. Orders are sealed during commit, revealed on the next block, and settled at a uniform clearing price. This eliminates front-running and MEV extraction.
StealthRegistry enables one-time payment addresses using ECDH key derivation. The sender derives a fresh address from the recipient's published meta-address. Only the recipient can detect and claim payments via view tags.
Track 2 โ VM31 UTXO Privacy
Track 2 takes a fundamentally different approach. Instead of encrypting balances, it uses a UTXO (unspent transaction output) model built on the Mersenne-31 prime field with Poseidon2 hashing.
Contract Architecture
VM31Pool โโโโโโโโโโ Poseidon2-M31 Merkle tree (depth 20, 1M notes)
โ
โผ
VM31Relayer โโโโโโโ Off-chain batching, ECIES encrypted submissions
โ
โผ
VM31Bridge โโโโโโโโ Bridges UTXO withdrawals โ Track 1 encrypted balances
The Mersenne-31 field (p = 2ยณยน - 1) enables single-cycle modular reduction on modern CPUs. Operations that take ~800 multiplications with felt252 limb decomposition take just 1 multiplication in native M31. This yields 250-800x faster proofs.
VM31Pool stores UTXO commitments in a Poseidon2-M31 Merkle tree. Deposits are split into fixed denominations (like physical cash), making all UTXOs of the same denomination indistinguishable. Each note is:
Note = Poseidon2(owner_pubkey || asset_id || amount_lo || amount_hi || blinding)
VM31Relayer processes UTXO operations off-chain. All data sent to the relayer is ECIES-encrypted (X25519 + ChaCha20), so even the relayer cannot see transaction details. It batches 1,000 transactions into a single GKR proof (~2s on GPU).
VM31Bridge connects the two tracks. You can bridge VM31 withdrawals into Track 1 encrypted balances through a deterministic bridge_key for idempotent processing.
Transaction Types
| Transaction | Inputs | Outputs | Poseidon Perms | Proof |
|---|---|---|---|---|
| Deposit | Public amount | 1 UTXO commitment | 2 | Commitment hash + range proof |
| Withdraw | 1 UTXO + Merkle path | Public release | 25 (padded to 32) | Nullifier + Merkle inclusion |
| Spend | 2 UTXOs + Merkle paths | 2 new UTXOs | 54 (padded to 64) | Balance conservation + nullifiers |
How the Tracks Connect
Security Properties
Next Steps
- Privacy Features (SDK) โ use the privacy primitives from code
- VM31 UTXO Vault (SDK) โ work with the UTXO track
- Deployed Contracts โ all mainnet addresses for both tracks
- Cryptography Primitives โ deep dive into Poseidon2-M31