| # Architecture & Flow Diagrams | |
| This document provides visual representations of the Solana Secure Signer architecture. | |
| --- | |
| ## ποΈ System Architecture | |
| ``` | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β USER APPLICATION LAYER β | |
| β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β | |
| β β Your Python CLI (Coldstar SOL) β β | |
| β β β’ Transaction building β β | |
| β β β’ Network communication β β | |
| β β β’ User interface β β | |
| β βββββββββββββββββ¬βββββββββββββββββββββββββββββ¬ββββββββββββββββββ β | |
| β β β β | |
| β β β β | |
| ββββββββββββββββββββΌβββββββββββββββββββββββββββββΌββββββββββββββββββββββββ | |
| β β | |
| βΌ βΌ | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β INTEGRATION LAYER β | |
| β ββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ β | |
| β β FFI Integration β β CLI Subprocess Integration β β | |
| β β (Fast, Direct) β β (Portable, Isolated) β β | |
| β β β β β β | |
| β β β’ ctypes bindings β β β’ subprocess.run() β β | |
| β β β’ Shared library β β β’ stdin/stdout JSON β β | |
| β β β’ Direct function calls β β β’ Process isolation β β | |
| β ββββββββββββββ¬ββββββββββββββ ββββββββββββββ¬ββββββββββββββββββββ β | |
| β β β β | |
| βββββββββββββββββΌβββββββββββββββββββββββββββββββΌββββββββββββββββββββββββ | |
| β β | |
| ββββββββββββ¬ββββββββββββββββββββ | |
| βΌ | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β RUST SIGNING CORE β | |
| β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β | |
| β β Public API β β | |
| β β β’ sign_transaction(container, passphrase, tx) β β | |
| β β β’ create_encrypted_container(key, passphrase) β β | |
| β ββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββ β | |
| β βΌ β | |
| β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β | |
| β β Signing Logic (signer.rs) β β | |
| β β 1. Derive decryption key (Argon2id) β β | |
| β β 2. Decrypt ciphertext (AES-256-GCM) β β | |
| β β 3. Copy to secure buffer β β | |
| β β 4. Sign with Ed25519 β β | |
| β β 5. Return signature β β | |
| β ββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββ β | |
| β βΌ β | |
| β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β | |
| β β Secure Memory (secure_memory.rs) β β | |
| β β β’ SecureBuffer: mlock/VirtualLock β β | |
| β β β’ Automatic zeroization on drop β β | |
| β β β’ Panic-safe cleanup β β | |
| β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β | |
| β β | |
| β Dependencies: ed25519-dalek, aes-gcm, argon2, zeroize, region β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| ``` | |
| --- | |
| ## π Signing Flow (Detailed) | |
| ``` | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β PHASE 1: INPUT PREPARATION β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ | |
| β β | |
| β Python Application β | |
| β ββ Load encrypted container (JSON file) β | |
| β ββ Get passphrase (user input, secure) β | |
| β ββ Prepare unsigned transaction bytes β | |
| β β | |
| β Status: β No sensitive data yet β | |
| ββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββ | |
| βΌ | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β PHASE 2: ENTER RUST SECURE ZONE β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ | |
| β β | |
| β FFI Boundary / CLI Invocation β | |
| β ββ Serialize inputs to JSON/bytes β | |
| β ββ Call: sign_transaction_ffi() or subprocess β | |
| β ββ Enter Rust memory space β | |
| β β | |
| β Status: β Encrypted data crosses boundary β | |
| ββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββ | |
| βΌ | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β PHASE 3: KEY DERIVATION β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ | |
| β β | |
| β Argon2id Key Derivation β | |
| β ββ Input: passphrase + salt from container β | |
| β ββ Compute: memory-hard hash β | |
| β ββ Output: 32-byte AES key β | |
| β ββ Zeroize: passphrase copy β | |
| β β | |
| β Status: β Passphrase zeroized, no plaintext key yet β | |
| ββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββ | |
| βΌ | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β PHASE 4: MEMORY ALLOCATION & LOCKING β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ | |
| β β | |
| β SecureKeyBuffer::new_secret_key() β | |
| β ββ Allocate: 32 bytes on heap β | |
| β ββ Lock: mlock()/VirtualLock() syscall β | |
| β ββ Verify: lock succeeded or return error β | |
| β ββ Initialize: fill with zeros β | |
| β β | |
| β Memory State: β | |
| β ββββββββββββββββββββββββββββββββββββββ β | |
| β β Locked RAM (32 bytes) β β | |
| β β [0, 0, 0, ..., 0] (all zeros) β β | |
| β β Status: LOCKED, not swappable β β | |
| β ββββββββββββββββββββββββββββββββββββββ β | |
| β β | |
| β Status: β Secure buffer ready, no sensitive data yet β | |
| ββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββ | |
| βΌ | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β PHASE 5: DECRYPTION β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ | |
| β β | |
| β AES-256-GCM Decryption β | |
| β ββ Input: ciphertext + nonce + derived key β | |
| β ββ Decrypt: to temporary Vec<u8> β | |
| β ββ Verify: authentication tag β | |
| β ββ Output: plaintext key (32 bytes) β | |
| β β | |
| β Temporary State: β | |
| β ββββββββββββββββββββββββββββββββββββββ β | |
| β β Stack/Heap (decrypted_bytes) β β | |
| β β [kβ, kβ, kβ, ..., kββ] β β | |
| β β Status: PLAINTEXT KEY! β οΈ β β | |
| β ββββββββββββββββββββββββββββββββββββββ β | |
| β β | |
| β Status: β οΈ CRITICAL - Plaintext key in temporary buffer β | |
| ββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββ | |
| βΌ | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β PHASE 6: SECURE TRANSFER β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ | |
| β β | |
| β Copy to Locked Buffer β | |
| β ββ Copy: decrypted_bytes β secure_key buffer β | |
| β ββ Zeroize: decrypted_bytes (constant-time) β | |
| β ββ Verify: no copies remain β | |
| β β | |
| β Before: After: β | |
| β ββββββββββββββββββββββββ ββββββββββββββββββββββββ β | |
| β β Temporary Buffer β β Temporary Buffer β β | |
| β β [kβ, kβ, ..., kββ] β βββββββ> β [0, 0, ..., 0] β β | |
| β β (plaintext key) β β (zeroized) β β | |
| β ββββββββββββββββββββββββ ββββββββββββββββββββββββ β | |
| β β | |
| β ββββββββββββββββββββββββ ββββββββββββββββββββββββ β | |
| β β Locked Buffer β β Locked Buffer β β | |
| β β [0, 0, ..., 0] β βββββββ> β [kβ, kβ, ..., kββ] β β | |
| β β (empty) β β (plaintext key) β β | |
| β ββββββββββββββββββββββββ ββββββββββββββββββββββββ β | |
| β β | |
| β Status: β Key in locked memory, temporary copy zeroized β | |
| ββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββ | |
| βΌ | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β PHASE 7: SIGNING β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ | |
| β β | |
| β Ed25519 Signing β | |
| β ββ Create: SigningKey from locked buffer (borrow, no copy) β | |
| β ββ Sign: signature = signing_key.sign(transaction) β | |
| β ββ Output: 64-byte signature β | |
| β ββ Note: SigningKey borrows, doesn't own the key β | |
| β β | |
| β Memory State: β | |
| β ββββββββββββββββββββββββββββββββββββββ β | |
| β β Locked Buffer β β | |
| β β [kβ, kβ, kβ, ..., kββ] ββββββββ SigningKey borrows β | |
| β β Status: LOCKED, being used β β | |
| β ββββββββββββββββββββββββββββββββββββββ β | |
| β β | |
| β Status: β οΈ Key still in memory, being used for signing β | |
| ββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββ | |
| βΌ | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β PHASE 8: RESULT PREPARATION β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ | |
| β β | |
| β Build Signed Transaction β | |
| β ββ Allocate: new Vec<u8> for result β | |
| β ββ Append: signature (64 bytes, public data) β | |
| β ββ Append: original transaction β | |
| β ββ Return: SignedTransaction struct β | |
| β β | |
| β Status: β Public signature ready, key still in locked buffer β | |
| ββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββ | |
| βΌ | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β PHASE 9: AUTOMATIC CLEANUP (Drop) β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ | |
| β β | |
| β SecureKeyBuffer::drop() automatically called β | |
| β ββ Trigger: secure_key goes out of scope β | |
| β ββ Zeroize: data.zeroize() (constant-time) β | |
| β ββ Unlock: munlock()/VirtualUnlock() β | |
| β ββ Extra: manual write_bytes for paranoia β | |
| β β | |
| β Before Drop: After Drop: β | |
| β ββββββββββββββββββββββββ ββββββββββββββββββββββββ β | |
| β β Locked Buffer β β Unlocked Memory β β | |
| β β [kβ, kβ, ..., kββ] β βββββββ> β [0, 0, ..., 0] β β | |
| β β (plaintext key) β β (zeroized) β β | |
| β β Status: LOCKED β β Status: FREE β β | |
| β ββββββββββββββββββββββββ ββββββββββββββββββββββββ β | |
| β β | |
| β Note: This happens even if signing panicked! β | |
| β β | |
| β Status: β Key completely erased from memory β | |
| ββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββ | |
| βΌ | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β PHASE 10: RETURN TO PYTHON β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ | |
| β β | |
| β FFI Boundary / CLI Output β | |
| β ββ Serialize: SignedTransaction to JSON β | |
| β ββ Return: to Python via FFI or stdout β | |
| β ββ Python receives: signature + signed transaction β | |
| β β | |
| β Data Returned to Python: β | |
| β β’ signature: [sβ, sβ, ..., sββ] (64 bytes, public) β | |
| β β’ signed_tx: signature + transaction (public) β | |
| β β | |
| β Status: β Only public data crosses boundary β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| SECURITY SUMMARY: | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β’ Plaintext key existed in locked memory for phases 6-8 only | |
| β’ Key was zeroized immediately after use (phase 9) | |
| β’ No copies of plaintext key exist outside locked buffer | |
| β’ Cleanup is guaranteed even on panic | |
| β’ Only public data (signature) returned to Python | |
| β’ Private key NEVER exposed to Python memory space | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| ``` | |
| --- | |
| ## π¦ Data Flow (Input β Output) | |
| ``` | |
| INPUT (Python) SECURE ZONE (Rust) OUTPUT (Python) | |
| βββββββββββββββ βββββββββββββββββββ βββββββββββββββ | |
| ββββββββββββββββ ββββββββββββββββ | |
| β Encrypted β β Signature β | |
| β Container ββββββββββ β (64 bytes) β | |
| β (JSON) β β β β | |
| ββββββββββββββββ β ββββββββββββββββ | |
| β β² | |
| ββββββββββββββββ β βββββββββββββββββββββββ β | |
| β Passphrase ββββββββββΌββββββββ>β Rust Signing Core ββββββββββββββββββ€ | |
| β (string) β β β β β | |
| ββββββββββββββββ β β 1. Decrypt β ββββββββββββββββ | |
| β β 2. Lock memory β β Signed β | |
| ββββββββββββββββ β β 3. Sign β β Transaction β | |
| β Unsigned TX ββββββββββ β 4. Zeroize β β (bytes) β | |
| β (bytes) β β 5. Return β ββββββββββββββββ | |
| ββββββββββββββββ βββββββββββββββββββββββ β² | |
| β | |
| Private key exists β | |
| here only! Never β | |
| leaves this box. β | |
| β | |
| ββββββββββββββββββββ β | |
| β Locked Memory β β | |
| β ββββββββββββββ β β | |
| β β Private β β β | |
| β β Key β β β | |
| β β (32 bytes) β β β | |
| β ββββββββββββββ β β | |
| β Auto-zeroized! β β | |
| ββββββββββββββββββββ β | |
| β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| FFI / CLI Boundary β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ§ββ | |
| Legend: | |
| ββββ> Data flow | |
| βββ> Security boundary | |
| βββββ Data container | |
| ``` | |
| --- | |
| ## π Memory Safety Guarantees | |
| ``` | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β MEMORY SAFETY GUARANTEES β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| Guarantee 1: MEMORY LOCKING | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β RAM β | |
| β βββββββββββββββββββββββββββββββββββββ β | |
| β β Locked Pages (via mlock) β βββ Private key here β | |
| β β Cannot be swapped to disk β β | |
| β βββββββββββββββββββββββββββββββββββββ β | |
| β β β | |
| β β BLOCKED (no swap) β | |
| β βΌ β | |
| β βββββββββββββββββββββββββββββββββββββ β | |
| β β Disk / Swap File β βββ Key never reaches here β | |
| β β β Private key CANNOT be here β β | |
| β βββββββββββββββββββββββββββββββββββββ β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| Guarantee 2: ZEROIZATION | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β Before Drop: After Drop: β | |
| β βββββββββββββββββββ βββββββββββββββββββ β | |
| β β [kβ, kβ, ..., kββ]β β [0, 0, ..., 0] β β | |
| β β Private key β ββββββββ> β All zeros β β | |
| β β SENSITIVE! β οΈ β β Safe β β β | |
| β βββββββββββββββββββ βββββββββββββββββββ β | |
| β β | |
| β Method: zeroize crate (constant-time, not optimized out) β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| Guarantee 3: PANIC SAFETY | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β Normal Flow: Panic Flow: β | |
| β ββββββββββββ ββββββββββββ β | |
| β β Signing β β Signing β β | |
| β β Success β β PANIC! β β | |
| β ββββββ¬ββββββ ββββββ¬ββββββ β | |
| β β β β | |
| β βΌ βΌ β | |
| β ββββββββββββ ββββββββββββ β | |
| β β Drop β β Drop β βββ Drop ALWAYS runs β | |
| β β Runs β β Runs β β | |
| β ββββββ¬ββββββ ββββββ¬ββββββ β | |
| β β β β | |
| β βΌ βΌ β | |
| β ββββββββββββ ββββββββββββ β | |
| β β Zeroized β β Zeroized β βββ Key erased in both cases β | |
| β ββββββββββββ ββββββββββββ β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| Guarantee 4: NO COPIES | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β ONLY ONE instance of plaintext key exists: β | |
| β β | |
| β ββββββββββββββββββββββββββββββββββββββββββββββββββ β | |
| β β SecureKeyBuffer β β | |
| β β ββββββββββββββββββββββββββββββββββββ β β | |
| β β β Private Key (32 bytes) β ββββββββ Single instance β | |
| β β β [kβ, kβ, kβ, ..., kββ] β β β | |
| β β ββββββββββββββββββββββββββββββββββββ β β | |
| β β β² β β | |
| β β β borrow (no copy) β β | |
| β β β β β | |
| β β βββββββββββ΄βββββββββββ β β | |
| β β β SigningKey β β β | |
| β β β (borrows data) β β β | |
| β β βββββββββββββββββββββββ β β | |
| β ββββββββββββββββββββββββββββββββββββββββββββββββββ β | |
| β β | |
| β All other buffers (decryption, etc.) are zeroized immediately β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| Guarantee 5: EPHEMERAL LIFECYCLE | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β Function Scope: β | |
| β β | |
| β fn sign_transaction(...) { β | |
| β let secure_key = SecureKeyBuffer::new(); βββ Created β | |
| β // ... decrypt into secure_key ... β | |
| β // ... use for signing ... β | |
| β return signature; β | |
| β } βββ secure_key dropped here, automatic cleanup β | |
| β β | |
| β Key exists ONLY during function execution β | |
| β No global variables, no caching, no persistence β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| ``` | |
| --- | |
| ## π― Integration Comparison | |
| ``` | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β INTEGRATION MODE COMPARISON β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β FFI Mode (libsolana_secure_signer.so/dll/dylib) β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ | |
| β β | |
| β Python βββ(ctypes)βββ Rust Library β | |
| β β | |
| β Pros: β | |
| β β Fastest (no process overhead) β | |
| β β Direct function calls β | |
| β β Minimal latency (~0.1ms overhead) β | |
| β β | |
| β Cons: β | |
| β β οΈ Requires compiled library for platform β | |
| β β οΈ Shared memory space (less isolated) β | |
| β β | |
| β Use When: β | |
| β β’ Production deployments β | |
| β β’ High transaction throughput β | |
| β β’ Minimal latency required β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β CLI Mode (solana-signer binary) β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ | |
| β β | |
| β Python ββ(subprocess)βββ Rust Binary ββ(exit)βββ All memory freed β | |
| β β | |
| β Pros: β | |
| β β Maximum isolation (separate process) β | |
| β β Platform-agnostic (just needs binary) β | |
| β β Automatic cleanup (process exit) β | |
| β β No FFI complexity β | |
| β β | |
| β Cons: β | |
| β β οΈ Slower (process startup ~10-50ms) β | |
| β β οΈ IPC overhead (JSON serialization) β | |
| β β | |
| β Use When: β | |
| β β’ Development/testing β | |
| β β’ Maximum security isolation β | |
| β β’ Cross-platform portability β | |
| β β’ Occasional signing (not high frequency) β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| Performance Comparison: | |
| ββββββββββββββββββ¬βββββββββββ¬ββββββββββββ¬βββββββββββββββ | |
| β Operation β FFI β CLI β Difference β | |
| ββββββββββββββββββΌβββββββββββΌββββββββββββΌβββββββββββββββ€ | |
| β Overhead β ~0.1ms β ~10-50ms β 100-500x β | |
| β Throughput β High β Low β - β | |
| β Memory Safety β Good β Excellentβ CLI better β | |
| β Portability β Medium β High β CLI better β | |
| ββββββββββββββββββ΄βββββββββββ΄ββββββββββββ΄βββββββββββββββ | |
| ``` | |
| This completes the visual documentation! π | |