Proposal:Friendslist Server

From Tox Wiki
Jump to: navigation, search

This is a proposal to give a standard way for clients to encrypt and back up their friendslist and private key to a handful of central servers. It is intended to be optional.

It borrows heavily from the Ripple Blob Vault.


Additional Goals

When a blob vault operator can no longer operate his server, he should be able to arrange for the blob vault to be merged with another blob vault that isn't going under.

We should not trust the blob vault any more than we absolutely must.

Users should be able to log in on a new device with no configuration besides username/password.

Searching for Friendslist, client side

  1. Take your H_LONG(username + password). This is the Base Encryption Key. This is never shared with a server.
  2. Derive a public/private keypair using H(BEK) as a seed. This public key is NOT used to encrypt the blob! Ask all the servers you know about whether have a blob with a matching public key.
  3. If one of the vaults responds that it does, prove that you have the private key by sending SIGN(server public key + server nonce + "READ")
  4. Receive the blob and decrypt it with your Base Encryption Key.

Remember Me?

Clients can implement a "Remember Me?" check box when the user logs in. If checked, the client saves the BEK to disk.

Searching for Friendslist, server side

On the server, you have 2 columns in your database: The encrypted blob, and the public key.

  1. When you receive a request, check your public key column to see if you have the correct blob. If so, respond to the client.
  2. Send the client a random nonce
  3. VERIFY(client response), if incorrect, close connection.
  4. Check that the text of the message is (server public key + server nonce + "READ"), and *nothing else*. If incorrect, close connection.
  5. If correct, send the blob.

Modifying Friendslist, client side

  1. Follow steps 1-2 of "Searching for friendslist"
  2. If one of the vaults responds, prove that you have the private key by sending SIGN(server public key + server nonce + "WRIT" + BSON encoding of the following)
    1. hash of old blob (optional, see below for why)
    2. new blob
    3. new public key (optional, see below)

Why have hash of old blob?

This allows a blob to be edited by multiple devices gracefully. If the hash is included, and it does not match the current blob, then the server gives an error message, and returns the old blob. The client merges its changes and tries again. If it fails 3 times, it just overwrites the old blob by omitting the old blob hash.

Optional New Public Key

This is used when you want to change your username/password.

Deleting Blob



Usernames are not guaranteed to be unique.


All communications between the blob vault and the client are encrypted. We avoid MITM by distributing the public key of the blob vault with the client.


  • crypto_secretbox for encryption of the friendslist. The nonce is regenerated each time, and prepended unencrypted to the blob.
  • H_LONG is a hash function that takes a long time (perhaps scrypt tuned for ~500ms and ~50MB of memory)
  • H is a normal hash function (perhaps SHA256?)


All nonces (except for the one used by crypto_secretbox) are randomly generated, and are exactly 64 bits long.


JSON-RPC over an encrypted connection, over TCP.


A Blob Vault is trusted in two ways:

  1. You're able to brute force usernames/passwords of your users faster than someone who merely had a network connection to you.
  2. You're trusted to be reliable. If the blob vault loses power because of a hurricane, users will not be able to log in. Clients can defend against this by distributing their friendslist across multiple servers, but that increases danger from #1.


Note: These should either be solved or moved to the "Trust" section.

  • An attacker finds out your public key whenever you log in, even if your blob is ultimately not stored on that server; they can start bruteforcing your username+password from that.
    • Solution: Use a Private Set Intersection protocol, where the the client has a set of 1 - the public key he's trying now.
      • Problem: How much overhead does this introduce?
      • Problem: Some PSI protocols are only secure against 'Honest-but-Curious' attackers, or only secure in the 'Random Oracle Model'
      • Problem: There doesn't seem to be an existing peer-reviewed PSI implementation, so this would involve rolling your own crypto.


This is a work in progress, and undoubtedly has many faults. If you have an improvement, please leave it below.

Slvrs' proposal (DEPRECIATED)

Popular opinion on usernames

Multiple Devices