Madison meets Satoshi
Step-by-step verification of proof of reserves & solvency
Provisions is a privacy-preserving proof of solvency protocol for cryptocurrency exchanges. It allows an exchange to prove they control enough assets to cover all customer liabilities without revealing individual account balances, the total holdings, or which blockchain addresses they control.
Protocol 1 - Proof of Assets: The exchange proves control of Bitcoin addresses using an anonymity set, without revealing which addresses are theirs.
Protocol 2 - Proof of Liabilities: The exchange commits to each customer's balance, proves each is positive, and sums them homomorphically.
Protocol 3 - Proof of Solvency: The exchange proves that total assets ≥ total liabilities using the commitments from Protocols 1 and 2.
This calculator focuses on demonstrating:
In 2014, Greg Maxwell proposed the first cryptographic proof of liabilities protocol, summarized by Zak Wilcox. This method uses a Merkle hash tree to allow customers to verify their balances are included in the exchange's total liabilities. While elegant and using familiar Bitcoin cryptography, it has significant privacy limitations that Provisions later addressed.
The exchange builds a binary Merkle tree where each leaf represents a customer account:
Enter customer balances (comma-separated) to see the Merkle tree structure.
To verify their balance is included, a customer receives:
Select a customer to see their verification path (Merkle proof).
The Maxwell method reveals significant information:
These privacy concerns led exchanges like Kraken to prefer trusted auditors over cryptographic proofs, which motivated the development of Provisions.
A Pedersen commitment allows you to commit to a value m in a way that is:
Hiding: The commitment reveals nothing about m
Binding: You cannot change m after committing
Homomorphic: Operations on commitments correspond to operations on values
Enter a value to commit to and a random blinding factor. We use simplified parameters for demonstration.
The security of Pedersen commitments requires that nobody knows the discrete logarithm relationship between g and h (i.e., no one knows x such that h = gx). In Provisions, g is the standard Bitcoin generator, and h is derived by hashing the string "Provisions" - ensuring no one can know the relationship.
To prove a balance is positive (not negative), Provisions decomposes each balance into its binary representation. By proving each bit is either 0 or 1, the protocol ensures the committed value is within a valid range [0, 2m-1].
Bitcoin uses satoshis (1 BTC = 108 satoshis), with a maximum supply of 21M BTC. This requires m = 51 bits to represent any valid balance.
Each bit xk of the balance gets its own Pedersen commitment with fresh randomness rk. The exchange then provides a zero-knowledge proof that each committed value is binary (0 or 1).
Enter a small balance (0-255 for demonstration) and see the individual bit commitments created.
The magic of Pedersen commitments: we can compute a commitment to the full balance by raising each bit commitment to the appropriate power of 2 and multiplying them together.
Building on the bit commitments, let's compute the full balance commitment homomorphically.
After the exchange publishes the proof of liabilities, each customer receives (privately):
Each client performs the following verification:
Simulate client verification. Enter your known balance and the randomness the exchange provided.
The homomorphic property of Pedersen commitments allows computing a commitment to the sum of all liabilities by simply multiplying the individual balance commitments.
Enter multiple account balances (comma-separated) to see how the homomorphic sum works.
This demonstration shows the complete flow: an exchange creates commitments for multiple customers, computes the total liability commitment, and then we verify one customer's balance.
| Property | Maxwell (Merkle Tree) | Provisions (Pedersen) |
|---|---|---|
| Total Liabilities | ❌ Public (in root) | ✓ Hidden |
| Individual Balances | ⚠️ Siblings revealed | ✓ Fully hidden |
| Exchange Addresses | ❌ Must be revealed | ✓ Anonymity set |
| Customer Count | ⚠️ Approximate (tree size) | ✓ Hidden |
| Cryptography Used | Hash functions (SHA-256) | Elliptic curves + ZK proofs |
| Proof Size | ✓ O(log n) per customer | ⚠️ O(n) total |
| Verification Cost | ✓ Fast (hash only) | ⚠️ Slower (EC operations) |
| Range Proofs | ❌ None (negative balances possible) | ✓ Built-in (binary decomposition) |
| Collusion Detection | ❌ Hard to detect | ✓ Optional extension |
See what information is leaked by each method for the same set of customers.
Maxwell's approach represents the classic tradeoff: simplicity and efficiency vs privacy and security. The Merkle tree approach is elegant and uses familiar Bitcoin primitives, but reveals too much information for many exchanges to be comfortable with.
Provisions solves this by introducing homomorphic commitments and zero-knowledge proofs, enabling the same verification guarantees while keeping all sensitive data hidden. The cost is computational complexity and larger proofs, but the paper demonstrates this is practical even for the largest exchanges.