This directory contains comprehensive documentation about how Zcash transaction decryption works, including code examples, architecture guides, and quick references.
Best for: Quick understanding and overview
- Executive summary of the entire system
- High-level architecture
- Key concepts explained simply
- Common issues and solutions
- ~5-10 minute read
Read this first if you want a quick understanding without getting into code details.
Best for: Understanding the complete architecture
- Detailed component descriptions
- Decryption flow diagrams
- Key types and domains (Sapling vs Orchard)
- Integration in WebZjs
- Performance considerations
- ~15-20 minute read
Read this after the summary to understand all the pieces.
Best for: Looking at actual code
- Full decryption function with comments
- Key types and structures
- Batch decryption implementations
- Scanning key operations
- WebZjs integration code
- Trial decryption process
- ~20-30 minute read
Read this when you want to see actual Rust code.
Best for: Navigating the codebase
- Exact file locations
- Function signatures
- Line number ranges
- Quick lookup table
- Testing and debugging info
- ~5-10 minute read
Use this as a quick reference when exploring the code.
...understand Zcash decryption in 5 minutes
→ Read: DECRYPTION_SUMMARY.md (Key Concepts section)
...understand the full architecture
→ Read: ZCASH_DECRYPTION_GUIDE.md (all sections)
...see how decryption code works
→ Read: DECRYPTION_CODE_EXAMPLES.md (sections 1-3)
...find a specific function or file
→ Use: DECRYPTION_FILE_REFERENCE.md (File Locations section)
...understand WebZjs integration
→ Read: ZCASH_DECRYPTION_GUIDE.md (Integration section)
→ Then: DECRYPTION_CODE_EXAMPLES.md (sections 5)
...debug decryption issues
→ Read: DECRYPTION_SUMMARY.md (Common Issues section)
→ Then: DECRYPTION_FILE_REFERENCE.md (Testing section)
...implement custom decryption
→ Read: DECRYPTION_SUMMARY.md (Entry Points section)
→ Then: DECRYPTION_CODE_EXAMPLES.md (sections 1-4)
...understand the database layer
→ Read: DECRYPTION_FILE_REFERENCE.md (Database Operations section)
Transaction → Try decrypt with each wallet's keys → Matched outputs → Stored in wallet
- External IVK → Incoming transaction
- Internal IVK → Change/internal transaction
- OVK → Outgoing transaction (sent by wallet)
zcash_note_encryption- Cryptographic primitives (trial decryption)zcash_client_backend/src/decrypt.rs- High-level decryption logiczcash_client_backend/src/scanning.rs- Key management- WebZjs - Browser wallet wrapper
- UFVK (Unified Full Viewing Key) - Public key for a wallet account
- IVK (Incoming Viewing Key) - Trial decryption key (can't spend)
- OVK (Outgoing Viewing Key) - Sender recovery key
- DecryptedOutput - Result of successful decryption
/home/realist/projects/zcashhashtx/
├── zcash_tx_decryptor/ # Rust CLI tool (this project’s binary)
├── api/ # Node/Express HTTP API wrapper
├── librustzcash/ # Core Zcash Rust libraries (fork)
└── *.md # Documentation set (this file, guides, examples)
Core Decryption:
librustzcash/zcash_client_backend/src/decrypt.rs(lines 100-223)
Key Management:
librustzcash/zcash_client_backend/src/scanning.rs(lines 40-300)
Batch Processing:
librustzcash/zcash_client_backend/src/scan.rs(lines 1-200)
WebZjs entry point (external repo):
crates/webzjs-wallet/src/bindgen/wallet.rsin the WebZjs repository (lines 269-290)
DECRYPTION_SUMMARY.md- Quick overviewZCASH_DECRYPTION_GUIDE.md- ArchitectureDECRYPTION_CODE_EXAMPLES.md- See actual code
DECRYPTION_FILE_REFERENCE.md- Find what you needDECRYPTION_CODE_EXAMPLES.md- Study implementations- Explore actual code in
librustzcash/
DECRYPTION_SUMMARY.md- Common issuesDECRYPTION_FILE_REFERENCE.md- Testing section- Check
RUST_LOG=debugoutput
- Protocol Spec: https://zips.z.cash/protocol/protocol.pdf
- ZIP 212: Privacy and Security on Sapling
- ZIP 316: Unified Addressing and Unified Full Viewing Keys
- ZIP 32: Hierarchical Deterministic Wallets
- Official Zcash Rust: https://github.com/zcash/librustzcash
- ChainSafe Fork: https://github.com/ChainSafe/librustzcash
- WebZjs Wallet: https://github.com/ChainSafe/WebZjs
| Term | Meaning |
|---|---|
| UFVK | Unified Full Viewing Key - public key that can see received funds |
| IVK | Incoming Viewing Key - used for trial decryption |
| OVK | Outgoing Viewing Key - used for sender recovery |
| USK | Unified Spending Key - private key that can spend funds |
| Trial Decryption | Attempting decryption to see if output belongs to wallet |
| Compact Block | Compressed block format (44 bytes per note vs 604 for full) |
| Shielded | Private transaction (Sapling or Orchard) |
| Transparent | Public transaction (t-address) |
| TransferType | Incoming / WalletInternal / Outgoing |
┌─────────────────────────────────────────────────────────────────┐
│ Zcash Transaction │
│ (containing encrypted outputs) │
└────────────────────────┬────────────────────────────────────────┘
│
▼
┌────────────────────────────────┐
│ decrypt_transaction() │
│ (zcash_client_backend::decrypt) │
└────────────────┬────────────────┘
│
┌────────────────┴────────────────┐
│ │
▼ ▼
┌────────────┐ ┌────────────────┐
│ Sapling │ │ Orchard │
│ Bundle │ │ Bundle │
└────────────┘ └────────────────┘
│ │
├─► External IVK ─────────────┼─► Incoming ✓
│ (trial decrypt) │
│ │
├─► Internal IVK ─────────────┼─► WalletInternal ✓
│ (change addr) │
│ │
└─► OVK ──────────────────────┼─► Outgoing ✓
(sent by wallet) │
Results: DecryptedOutput[] stored in wallet database
↓
wallet.get_balance() returns funds
- IVK is safe to share - can only see received funds, can't spend
- USK must be secret - never share spending key
- OVK is semi-private - shows outgoing txs but not recipients
- Compact blocks (~44 bytes) - faster scanning, no memo
- Full transactions (~604 bytes) - slower, includes memo
- Batch processing - 10-100x speedup via parallelization
- Sapling - Legacy shielded protocol (since 2018)
- Orchard - Newer, more efficient (since 2022)
- Transparent - Public addresses (legacy, ZEC originally)
→ Check the Terminology section above
→ Use DECRYPTION_FILE_REFERENCE.md → File Locations
→ Check DECRYPTION_SUMMARY.md → Common Issues and Solutions
→ Read the specific document listed in "Quick Navigation"
cd /home/realist/projects/zcashhashtx/
# Explore librustzcash (core decryption logic)
cd librustzcash
find . -name "decrypt.rs" -o -name "scanning.rs"
# View core decryption function
cat zcash_client_backend/src/decrypt.rs | head -100
# Explore the CLI wrapper
cd ../zcash_tx_decryptor
ls srcgrep -r "DecryptedOutput" librustzcash/zcash_client_backend/src/
grep -r "try_note_decryption" librustzcash/zcash_client_backend/src/
grep -r "TransferType" librustzcash/zcash_client_backend/src/This is a complete guide to understanding Zcash transaction decryption. Start with DECRYPTION_SUMMARY.md for a quick overview, then read the other documents based on your needs.
The core idea: Zcash uses trial decryption with viewing keys to detect which transactions belong to which wallet. This happens automatically during wallet synchronization.
Key takeaway: Understanding zcash_client_backend/src/decrypt.rs is the key to understanding the entire system.