Blockchains are difficult to run on most end-user devices.

Although MITM-proof proxies are a great way to address this problem, they are unlikely to scale well to all Internet users (not everyone will be able to run their own full node). Therefore, most people will need to rely on thin client techniques to reduce the trust placed in such proxies.

A thin client (or a light client) refers to software that downloads only a portion of the blockchain.1 This gives clients some ability to verify for themselves the authenticity of information within it.

Our focus now is on stimulating discussion of, and participating in, the definition of a blockchain agnostic and technique agnostic thin client specification.

Agnosticism is essential because:

Any blockchain may become abandoned by the Internet community.

The “ideal blockchain” is unknown and may not exist.

Non-agnostic protocols promote potentially harmful centralization.

Although most thin client techniques are derivatives of Satoshi’s original Simplified Payment Verification (SPV), it turns out there’s more than one way to skin a thin client. And so, in order to define a flexible thin client standard, we must find out just how different they can be.

Today we define a new thin client technique called Proof of Transition (PoT). A comparison to SPV is available here.

The following is a section from DNSChain’s Security Model document.

Proof-of-Transition (PoT) Definition

As the name suggests, blockchains are made of blocks chained together. Each block usually contains a list of transactions.

In Namecoin, .bit domains are mapped to the d/ namespace. So okturtles.bit can be registered by creating a transaction claiming ownership of d/okturtles (if no unexpired transaction already exist in the blockchain).

PoT behavior on initial identifier lookup

When a client looks up an identifier for the first time (such as okturtles.bit ), the proxy sends the following information (all of which is cached by the client):

The root transaction, which contains the most recent registration of the identifier.

transaction, which contains the most recent registration of the identifier. The current transaction, representing the current value and current owner of the identifier. This value is added to a Bloom filter (that’s associated with the root) to prevent replay attacks (discussed later in Forking Considerations and Thin Client Threat Models).

The security of PoT rests on establishing the validity of the root transaction, and therefore clients must retrieve the information above from at least two different proxies and verify that all responses match.

Securing the connection to proxies and reducing collusion risk

Connections to proxies are secured via public key pinning, similar to how browsers come with a list of Certificate Authorities (CAs) key pins.

Whereas security in today’s CA system decreases with the more CAs there are, the opposite is true with blockchain-based architectures: the more proxies that are queried, the greater the security.

Of greatest significance is that blockchains can be run and used by anyone to authenticate arbitrary Internet connections and end users can specify which proxies they trust. If the end user does not specify a trusted proxy, two or more proxies (belonging to separate organizations) can be chosen at random from a predefined list.

To prevent the likelihood of colluding proxies, the proxies that are used can be periodically changed (re-chosen at random). If a previously chosen set of proxies had colluded on the first-lookup of an identifier, this would be discovered once a proxy outside of that colluding set is used.

PoT behavior when an identifier’s value changes

When a previously queried identifier changes, PoT requires a proof be sent demonstrating the previously known owner authorized that change.

If the observed change is not the result of a fork, the entire protocol sequence would be as follows:

Client queries a proxy for the value of an identifier and receives a transaction that is different from its locally cached version. Client sends its cached transaction (the one labeled previous in the figure below) to the proxy and requests a PoT to the current transaction it received in (1). Proxy responds with the list of transactions between the previous txn sent in (2) and the current txn in (1). Client verifies the transaction chain: If verification is successful, the entire transaction chain is efficiently memorized by a Bloom filter and then discarded (except for the new current transaction for the identifier).

transaction for the identifier). If verification fails, an attack or data corruption is assumed. Client can either retry or switch to an honest proxy.

In the scenario depicted below, steps 2-3 are skipped because there are no transactions between previous and current, and so the PoT can be instantly verified at step 1:

Forking Considerations

Clients never discard the root transaction they receive in order to handle legitimate forks in the blockchain that override the previous cached transaction.

If such a situation occurs, the PoT protocol works exactly as described previously, except Step 3 is now:

The proxy sends a specially marked “fork PoT” that contains the entire transaction chain from the root to the current . The client verifies the signatures in the transaction chain and verifies that the Bloom filter has not seen the transaction at the end of the chain (the new current ). If signature verification fails, the client treats it as either an attack or data corruption and lets the user decide whether to retry or switch to a different proxy. If the Bloom filter reports it’s seen all of the transactions, this indicates either a replay attack or a poorly configured Bloom filter (making the probability of a false positive too high). Recovery proceeds the same as when recovering from a root mismatch (described next).

to the . The client verifies the signatures in the transaction chain verifies that the Bloom filter has seen the transaction at the end of the chain (the new ).

A dangerous situation can occur when a fork is so long that the block containing the root is overwritten. If such a fork were to occur, the thin client would have no way to obtain a PoT. This scenario is depicted in the figure below (where the red blocks are now the longest chain):

Clients have no way to distinguish this situation from an actual attack (where the proxy fabricates a fork to insert its own key as the root), and must therefore treat it as such.

Recovery could proceed as follows:

Inform the user that they may be under attack by the proxy they are using. Present a GUI to the user that allows them to choose two or more other proxies to query to re-establish a new root. Query those two proxies in addition to four other randomly chosen proxies to establish a quorum for a new root for the identifier. If quorum achieves 100% agreement, override the root . If the original proxy disagrees with the quorum, report it and use one of the two user-selected proxies in its place.

. If the original proxy disagrees with the quorum, report it and use one of the two user-selected proxies in its place. If quorum fails to achieve 100% agreement, inform the user and let them decide what to do next.

This scenario should be extremely rare since most root transactions will be buried deep in the blockchain.

Acknowledgements

Thanks to Dionysis Zindros for coming up with the original concept.

Edit July 25, 2015: Thanks to Jeremy Rand for pointing out that Ryan Castellucci was first to suggest a similar concept in a Google doc.

Further Reading

Discuss on Hacker News.

For updates, follow @okTurtles and @DNSChain on twitter.

Donating = Loving!

You can empower our work by donating!