Solidus: confidential distributed ledger transactions via PVORM Cecchetti et al., CCS’17
Tokens on blockchains can be used to represent assets, and the ledger provides trade settlement on-chain. In a straightforward public blockchain, pseudonyms and transaction values are all publicly visible. Uncovering the true identities behind the pseudonyms becomes a real possibility (‘A fistful of Bitcoins’). When the trading is directly between institutions, and the market participants are relatively fixed, one solution is to use private blockchains. Another option is to store only transaction digests on-chain, and keep key details elsewhere. This provides certification, but doesn’t permit on-chain settlement.
Solidus is designed for bank-intermediated systems in which financial institutions manage on-chain assets on behalf of their customers. Such a model replicates asset flows within modern financial institutions, and enables regulatory duties such as know-your-customer to be discharged (something not supported by anonymous trading). As presented in this paper though, I’m not sure Solidus would support anti-money laundering obligations. Still, I find it an exciting development and there’s a lot to like here.
Solidus supports strong confidentiality and high transaction rates for bank-intermediated ledgers. Solidus not only conceals transaction values, but also provides the much more technically challenging property of transaction-graph confidentiality. This means that a transaction’s sender and receiver cannot be publicly identified, even by pseudonyms. They can be identified by their respective banks, but other entities learn only the identities of the banks.
Fast transaction settlement
The big prize here is speeding up transaction settlement (the exchange of assets after clearing). Clearing and settling is typically done via clearing houses, and full settlement may take three days for securities.
This delay introduces systemic risk into the financial sector. Government agencies such as the Securities and Exchange Commission (SEC) are trying to reduce this delay and are looking to distributed ledgers as a long-term option. If asset titles — the authoritative record of ownership — are represented on a ledger, then trades could execute, clear, and settle nearly instantaneously.
Solidus high-level design and protocol
Solidus is designed to match the structure of the financial industry. Banks have a set of customers (users) who hold shares in some asset in their accounts. Asset notaries inject new assets into the system. Transactions involve a sending user at a sending bank, and a receiving user at a receiving bank. To initiate a transaction a sending user signs a transaction and gives it to their bank. The bank verifies the validity of the transaction then updates its on-ledger state to reflect the results of the transaction. The receiving bank performs a corresponding update on the receiving user’s account.
To keep account balances on the ledger, but maintain strong confidentiality, Solidus uses publicly-verifiable oblivious RAM (which we’ll look at shortly).
The confidentiality properties of PVORM ensure that another entity can learn only the identities of the sending and receiving banks, not (the amount transferred) or the identities of the transacting users. Indeed, even the sending bank cannot identify the receiving user nor the receiving bank of the sending user. The public verifiability of PVORM ensures that any entity with access to the ledger can verify that each transaction is correctly processed by both banks.
So while the sending bank doesn’t know where it is sending money (that’s the regulatory concern I alluded to earlier), the receiving bank does know where the money is going. And if the receiving bank is a regulated institution using KYC, then in the system overall the details of the transacting parties is known. Banks can prove correct decryption of on-chain data, providing transaction logs on-demand to auditors, who can verify the correctness and completeness. If a bank shares their private decryption key with an auditor, then the auditor is able to proactively monitor activity within the bank and its accounts, simply by observing the on-chain state.
We treat the ledger as a public append-only memory which verifies transactions. All banks have asynchronous authenticated read and write access and the ledger accepts only well-formed transactions not already present.
The transaction verification could happen e.g. via a smart contract and is application defined. For example, account balances must remain non-negative.
Let’s look at the lifecycle of a transaction between a sending user at bank and a receiving user at bank :
The sending user constructs a request consisting of:
- A unique transaction id
- The value to be transferred, encrypted with the public key of the sender
- The id of the intended recipient, encrypted using the receiving bank’s public key
- A hidden-public-key signature signed with with the private key of the sender. The hidden-public-key (HPK) scheme allows a signer to sign with respect to a signing public key that is in turn encrypted under a banks’ public key. Details are in appendix A.3 in the paper. The receiver learns that a valid signature was generated with respect to some key, but learns nothing about the key itself.
The sending bank verifies the received request and initiates the settlement process. First the bank generates a proof that the request is valid, and then it allocates a transaction id and sends the txId plus the details of the value to be transferred and the recipient, encoded using the receiving bank’s public key, and sends this to the receiving bank.
Both the sending bank and the receiving bank update their respective PVORMs and post all associated proofs and signatures onto the ledger.
Once the full transaction has been accepted by the ledger, the assets have been transferred and the transaction has settled.
The main Solidus protocol is captured in more detail in the following figure:
Publicly-verifiable Oblivious RAM machine (PVORM)
Each bank maintains a private data structure, M, containing each user’s balance and public key. A corresponding public data structure C is placed on the ledger with contents encrypted under the bank’s encryption key. M and C together constitute the memory in a PVORM.
The notion of PVORM is heavily inspired by Oblivious RAM (ORAM) – a cryptographic protocol that permits a client to safely store data on an untrusted server. Oblivious RAM conceals memory access patterns, providing the foundation for transaction graph confidentiality. ORAM as is is missing the capability to validate updates, and to provide public verifiability. PVORMs have four key differences from standard ORAM:
- Updates are constrained by a public function that updates M according to some update u. In the case of Solidus, this function guarantees that a single balance is updated to a non-negative value.
- Updates are publicly verifiable — whenever the client modifies C, it must prove (in zero-knowledge) that the change reflects a valid application of f.
- The client maintains all memory (both M and C). M remains hidden, but C is publicly visible on a ledger.
- There is no private stash: any data in M not represented in C would prevent the client from proving correctness of writes. Therefore PVORM works with a fixed-size public encrypted stash.
Solidus’ PVORM is instantiated by combining Circuit ORAM with several Generalized Schnorr Proofs (GSPs). The only thing I can tell you about GSPs is that they allow for practical zero-knowledge arguments (proofs) of knowledge to be constructed.
In appendix B we concretize this construction. We prove it correct, oblivious, and publicly verifiable in the extended paper.
Solidus actually doesn’t care what kind of ledger transactions are recorded on, so long as it is a public append-only memory. It could be a decentralised blockchain, or it could use a traditional consensus protocol, or it could even be a single trustworthy entity.
The cost of re-randomising ciphertexts while updating a PVORM can be reduced by pre-computing randomisation pairs during periods of lighter load. We can also reduce the requirement for every participant to cryptographically verify every update under certain circumstances:
- If a threshold number of trusted entities (large banks and regulators for example) have verified a transaction, other nodes may decide they only need to verify the signatures of the trusted entities (far faster than full verification).
- If the cost to reputation of being caught cheating is sufficient to deter bad behaviour, then online verification can be sidestepped altogether. Post-hoc identification of faulty transactions and the offending bank is trivial, meaning that banks will only submit valid transactions and proofs and the ledger can accept transaction immediately and verify later offline.
Finally, a bank can pipeline processing of transactions (which only need the state from one transaction to the next) while working on the associated proofs in parallel. Pipelining doesn’t reduce transaction latency, but it does drastically increase throughput.
Solidus is 4300 lines of Java code, 2000 of which are the PVORM. PVORM performance scales with the number of worker threads, and an update with proofs is about 114 KB compressed. When generating updates memory consumption peaks at 880MB.
We see pretty low throughput in the test (less than 10 transactions per second), however:
We emphasize that our performance results employ an unoptimized implementation and only one server per bank, highly limiting our parallelism. Solidus is designed to be highly parallelized, allowing it to scale up using multiple servers per bank to achieve vastly superior performance in practice.
Unless I’m missing something here though, the overall system throughput will still be limited by the transaction throughput of the chosen ledger.
The last word
We believe that Solidus is the first viable approach to building strongly verifiable and fully auditable bank-intermediated ledger transactions systems.
I’m sure there are companies to be built around this line of technology!