[continued from part IV]
Trust assumptions revisited
Purely cryptographic approaches to proving solvency are constrained by an ambitious dual mandate: achieve full public verifiability and guarantee full privacy for custodian assets. On the one hand, it aims for creating proofs that any one can verify without relying on the word of third parties. On the other hand, it protects the custodian against unnecessary of disclosure proprietary business information such as blockchain addresses or even total assets under management. The first objective is intrinsically incompatible with accommodating fiat balances, while the latter one may not provide as much value as expected.
First consider the nature of the privacy afforded to the custodian: its collection of assets— and by implication total balance— are hidden inside a larger “cover set” of other blockchain addresses chosen during the construction of the proof. Use of zero-knowledge techniques mean the distinction between real vs cover addresses will not be leaked by the proof. But there is no guarantee that outside observers will not be able to distinguish true addresses from the chaff using other signals. Many companies specialize in blockchain analytics: clustering and labeling addresses associated with specific actors and tracing flow of funds. For example, cold-wallet addresses for many exchanges are already well known. The prover could include some these in their cover set, unaware that the addresses have been deanonymized and associated with another actor. While the inclusion of such an address does not invalidate the proof, it provides no privacy benefit. Anyone looking at the proof can immediately eliminate those addresses as belonging to the custodian, leaving a smaller subset for real assets. That problem only gets worse over time: an address may not have been labeled when it was included in the cover set but future work— and new transactions involving that address— can reveal the identity behind it. The anonymity set contracts over time. In fact if Provisions-style approaches were widely deployed, participants may well undermine each other. When the same address appears in multiple proofs from different custodians, it can belong to at most one. For all others, that address can be ruled out as part of the wallet. Similarly, long-term stable addresses used by a custodian would jump out when comparing proofs over time. The cover set may change but real custodian addresses must appear in the proof as long as they carry non-zero balance.
Giving up on blockchain privacy
Another interesting datapoint is the existence of proposed and implemented proof strategies with complete transparency over blockchain addresses. For example a BIP from Blockstream proposes to use “almost-valid” transactions as proof. The custodian creates a single massive transaction consuming all of their valid unspent outputs and one bogus input. The bogus input serves two purposes. By incorporating some fresh information that can not be predicted in advance, it guarantees recency of the proof— since signatures of all the valid inputs must also reference the bogus input, they could not have been precomputed before that last input was known. Second by virtue of being an invalid input, its presence invalidates the entire transaction, preventing its unauthorized broadcast. (Recall that we want to prove control over funds at rest; we do not want to move them in the process.) As far as disclosure goes, this is radical transparency. Not only are all addresses and by implication total assets under custody revealed, the proof also gives away information about the construction of those addresses, such as the set of public-keys behind a multisig script which may never have appeared on the blockchain before. On the other hand, the proposal makes no attempt to address the liabilities side of the equation. Knowing a custodian can sign for 1000BTC is not helpful without the additional context of how much it was supposed to have in the first place.
The exchange Coinfloor uses a more comprehensive approach in its Provable Solvency Reports. They publish a pseudonymized version of the internal ledger, listing balances for every customer. These are not cryptographic commitments; actual amounts appear in cleartext. The only piece of information obscured is the identity of the account, which uses hash of API keys. Coinfloor then executes an actual bitcoin transaction moving the total amount on the blockchain. This approach reveals even more information than the Blockstream version. Individual balances are visible to everyone, not just that specific customer who is the only person in a position to verify if it is represented correctly. Pseudonyms help but can not prevent partial leaks. If the exchange is known to have customers with high balances (for example, hedge funds or accredited investors) their balances may stand out since the distribution is highly skewed. For example in the June 2018 report from Coinfloor, just ten customers account for close to 30% of all bitcoin under custody. Luckily the identifiers change over time by incorporating a timestamp in irreversible manner. Consistent identifiers would have provided even less privacy by allowing investors balances to be tracked over time, allowing others to observe which customers are building up or exiting their bitcoin positions.
Finding a middle ground
Merits of these specific proposals aside, there is a clear disconnect between the privacy and trust assumptions of solvency protocols that are deployed and those appearing in the literature. Relying on an independent third-party seems inescapable for two reasons: dealing with fiat currency balances and looking under the hood at the soundness of the overall storage system. (QuadrigaCX was in control of its keys, until one day when it was not not.) On the other hand, ledger verification is best outsourced to customers. They are both ideally positioned to check if their balance is recorded correctly and motivated to do so when their own funds are at stake. Building on this observation, we can explore other design options: proofs that are partially verifiable while still calling on trusted third-parties for specific tasks.