I'll describe the technical challenges faced by the Pillar Project team while designing our "Personal Data Locker": a way to interact with others and services while respecting users’ privacy and identity.
Pillar was meant from the beginning to be much more than a crypto wallet. It’s a radical shift in the way people interact with digital services: from discovery (the Pull model and semantic search) to interaction (decentralised user accounts). It was also meant from the beginning to include social features — "connections".
The first part of this series will deal with how we chose to implement connections: which tradeoffs we chose, the shortcomings we encountered, and what we plan for the future.
As we started designing the wallet, our goal was always ease-of-use above all other priorities. Rather than cutting and pasting Ethereum addresses, we wanted our users to connect using a ‘friends list’ mechanism, similar to Skype’s. Then people can just send to another person, rather than to an address.
This challenge illustrates the tradeoffs we must make as we balance privacy and ease of use. While interesting from a UX standpoint, I was uncomfortable with centralizing all the names and contact information. Pillar would have access to the full social graph for its users, something that goes against our ethos.
We looked at several options. Ultimately, Jegor, one of our star developers, came up with a good solution: the shared-secret approach.
In shared secret, each party randomly generates a secret (a really big number) and two parties exchange this secret between them. Here’s how it looks in Node.JS:
As you can see, each entry only refers to a single user — if you think of connections as part of a graph, each entry represents a node. If you have both access keys, you can find the corresponding edge of the social graph.
This allowed us to maintain the list of connections for a given user without knowing who is connected to whom. There is no way to data mine or provide a complete connection graph for any user.
There are drawbacks to this approach. The first is centralisation. This was a design decision. The user-lookup feature requires some degree of centralisation to make it efficient (think how you connect to another user on Skype).
There are two risks here. The risk of centralization is the risk that someone or group could take control of our servers and cause problems with or delete the database of users and connections. This is not a big risk, because there is very little economic value there. Thieves have much more incentives to hack Skype for their list of credit cards than for their list of names and connections.
The more important risk is phishing — a malicious actor can pose as someone, make a connection, and request ether or some other asset. This is a very real risk that we take seriously. While it isn’t very consequential on Skype, it’s our job to protect our users from the loss of their assets. Decentralizing our address book doesn’t change the phishing attack surface. We know very well that as the Pillar network grows we will need to take more and more steps to a) educate users about phishing attacks and b) prevent them on our end as much as possible.
We believe decentralization plays an important role when safeguarding valuable assets. It is less important for the “connective tissue” that helps us serve our customers quickly.
The second one was state management. The wallet must maintain a set of shared secrets. This creates trouble when a user deletes the app from his or her phone and then re-import it. If there are no backups, the connections are lost for the user, but his connections will still have him in their contact lists. If she adds her connections again, they will have duplicate connections.
Instead of using random access keys, we decided to do something harder but better: derive sets of private keys from an HD Wallet. This solves the state-management issue. It does change the schema slightly, but the overall structure remains the same.
One major consideration for the future is data in transit. While the current approach is safe in regards to data at rest (the data we keep in our servers) while the data being sent around between wallets and our servers it's still at risk.
We plan to approach this using zero-knowledge proofs of set membership, which I'll expand later in this series.