rustywallet-silent
Silent Payments (BIP352) implementation for rustywallet.
Overview
Silent Payments allow receivers to publish a single static address while each payment generates a unique on-chain address that only the receiver can detect and spend. This provides significant privacy benefits compared to address reuse.
Features
- Silent Payment Address: Generate and parse sp1/tsp1 addresses
- Payment Derivation: ECDH-based output key derivation
- Scanning: Detect incoming payments to your silent payment address
- Sending: Create outputs for silent payment recipients
- Labels: Support for multiple labeled addresses from single key
- Change Handling: Proper change output derivation
Usage
use *;
use PrivateKey;
// Generate Silent Payment keys
let scan_key = random;
let spend_key = random;
// Create Silent Payment address
let sp_address = new.unwrap;
println!;
// Sender: Create payment output
let sender_keys = vec!;
let outpoints = vec!;
let outputs = create_outputs.unwrap;
// Receiver: Scan for payments
let scanner = new;
let found = scanner.scan_outputs.unwrap;
Protocol Overview
Address Format
Silent Payment addresses use bech32m encoding:
- Mainnet:
sp1... - Testnet:
tsp1...
The address contains two public keys:
- Scan key (B_scan): Used to detect incoming payments
- Spend key (B_spend): Used to derive spending keys
Sending
- Collect all input private keys
- Compute input hash from outpoints
- For each recipient, compute shared secret via ECDH
- Derive output public key: P_output = B_spend + hash(shared_secret || n) * G
Receiving
- For each transaction output, compute potential shared secret
- Check if output matches derived key
- If match found, compute spending private key
Security Considerations
- Scan key can be shared with a light client for detection
- Spend key must remain secret
- Each payment creates a unique address (no address reuse)
- Labels allow multiple addresses without additional keys
License
MIT