Double-Spend Protection
Double-Spend Protection via Nullifiers
This document describes the nullifier-based double-spend protection mechanism in the Roru Protocol.
Overview
Problem
Prevent the same note from being spent multiple times while maintaining privacy.
Solution
Nullifiers provide a privacy-preserving way to mark notes as spent without revealing which note was spent.
Nullifier System
Nullifier Definition
Nullifier Structure:
pub struct Nullifier {
pub hash: Hash, // 32-byte hash
}Nullifier Generation
Generation Formula:
Generation Code:
Nullifier Properties
Uniqueness
Property: Each nullifier is unique
Guarantee:
Different notes produce different nullifiers
Same note always produces same nullifier
No collisions (cryptographically)
Unlinkability
Property: Cannot link nullifier to note
Guarantee:
Nullifier doesn't reveal commitment
Cannot determine which note was spent
Privacy-preserving
Determinism
Property: Same inputs always produce same nullifier
Guarantee:
Reproducible generation
Consistent verification
No randomness in nullifier
Nullifier Set
Set Structure
Nullifier Set:
Set Operations
Insertion:
Lookup:
Double-Spend Detection
Detection Process
Detection Steps:
Generate nullifier for note
Check if nullifier exists in set
If exists: reject transaction (double-spend)
If not: allow transaction
Detection Code:
Transaction Flow
Spending Process
Spending Steps:
Select note to spend
Generate nullifier
Check nullifier not in set
Create transaction with nullifier
After verification: add nullifier to set
Spending Code:
Nullifier Verification
Verification in Proof
Proof Circuit:
Proves nullifier generated correctly
Proves nullifier not in set
Hides note information
Validates generation
Circuit Constraints:
Sparse Merkle Tree
Tree Structure
Tree for Nullifiers:
Sparse Merkle tree
Only non-empty nodes stored
Efficient proofs
Fast lookups
Tree Implementation:
Tree Operations
Insertion:
Proof Generation:
Batch Operations
Batch Nullification
Batch Process:
Generate nullifiers for all inputs
Check all not in set
Batch insert after verification
Batch Code:
Performance
Efficiency
Operations:
Generation: O(1)
Lookup: O(1) with hash set
Insertion: O(1)
Proof: O(log n) with tree
Storage:
Nullifier: 32 bytes
Set: O(n) where n is number of spent notes
Tree: O(n log n) but sparse
Security
Security Properties
Cryptographic Security:
Based on hash function security
Collision resistance
Preimage resistance
Privacy Security:
Nullifiers don't reveal notes
Unlinkable to commitments
No information leakage
Threat Model
Protected Against:
Double-spending
Replay attacks
Nullifier forgery
Security Assumptions:
Secure hash function
Secure nullifier keys
Correct implementation
Edge Cases
Concurrent Transactions
Handling:
Lock nullifier set during verification
Sequential processing
Conflict detection
Network Partitions
Handling:
Eventual consistency
Conflict resolution
State reconciliation
Conclusion
Nullifier-based protection provides:
Security: Prevents double-spending
Privacy: Doesn't reveal spent notes
Efficiency: Fast operations
Scalability: Handles large sets
Reliability: Cryptographically secure
Understanding nullifiers is essential for transaction security.
Last updated
