Technical Deep Dive with David Braden

This is part two of a two-part series focusing on Holochain, Holo Accounts, and Cryptographic Key Management.

Last week, we talked about Holochain, Holo Accounts, and Cryptographic Key Management. This week, we’ll discuss DeepKey Key Management.

Highlights

3. DeepKey Key Management
3.1 A New DeepKey Keyset
3.2 DeepKey Management Actions
3.3 DeepKey Revocation
4. Are We There Yet?

Details

3 — DeepKey Key Management

DeepKey is recursive. It is a Holochain app that advertises to the world the current state of an agent’s keyset (A “keyset” is bundle of related key pairs associated with a single agent). Chain entries in DeepKey are signed with the private half of a public key that is registered as valid within the same DeepKey app… itself. Is everybody lost?

Back to setting up a new Holochain node or Holo account, we’ve created a revocation key and a list of application key pairs. If this is the first time you’ve interacted with a Holochain application, you now need to create a new DeepKey keyset.

3.1 — A New DeepKey Keyset

We need to create an initial entry in the DeepKey Holochain application that includes all the public keys we want to preauthorize for future application use. Next, we pick a revocation method. We’ll talk about the “M of N” revocation method later; for now, let’s use a simpler revocation key. We register the public half of the revocation key we generated in the key derivation step, as well as the public halves of all device application keys we may want to use in the future.

After the mandatory system Holochain app entries (the dna and agent entries), this entry is the the very first DeepKey app entry. It is signed twice. We need a verifiably unique, unchanging identifier that we can use as a reference across apps in the Holochain ecosystem. This gives us a touchpoint so we can do things — like upgrade to new keys — and validators will know how to look up or verify that the upgrade was legit.

We are calling this identifier your DeepKey Root ID, and it’s made from a pure entropy, one-time signing key pair. Per validation rules, this key pair is only allowed to make one single signature, signing an initial DeepKey keyset entry into existence. In fact, Holochain will immediately shred and forget the private portion as soon as the signature is generated. The public portion of the pair will become this keyset’s DeepKey Root ID and will be used as a reference touchpoint when tracking application key migrations and other manipulations of key management state.

Whew.

The second signature is the normal signature that is created when any Holochain entry is added to a chain. Now, there comes the recursive part. This second signature is only valid if the DeepKey application can validate it is an active key in this keyset. During the genesis for this particular application, we can construct it to use an agent key that is also included in this double-signed initial entry.

And voilà! We have an application that can tell us if a public key is valid for a keyset that includes itself.

Next, how do we add additional devices to our keyset?

DeepKey Key Management Interaction Flow

3.2 — DeepKey Management Actions

What if your device is lost, stolen, or broken? What if you get a new device or want to install a new application? What if you started your account as a Holo user, but want to upgrade your security? We need to be able to make changes to DeepKey keysets.

By the way, DeepKey is a play on DPKI — and much easier to say!

DPKI stands for “Distributed Public Key Infrastructure.” In Holochain’s case, this is no misnomer. Public keys are stored and shared over the DeepKey application’s distributed hash table. More than that, an individual agent may have many devices under the same DeepKey keyset, any number of which may be authorized to make DeepKey changes. Remember, source chains in Holochain reside in the context of a single device instance. This means that the state of a DeepKey keyset is an aggregation of all of these authorized devices’ DeepKey chains!

In the previous section, we talked about the Holochain entry that creates a new DeepKey keyset. What about the second device? Let’s say we generated five future devices preauthorizations when creating the keyset. We saved the encrypted device seed bundle for device number two. On initial launch, we provide the bundle, enter our passphrase, and we’re up and running. The first entry in the DeepKey app on this device references the original device’s chain.

Maybe you’re concerned about losing track of the preauthorization bundles, or you already have five devices. Your first option is to go to one of your existing devices, input your root seed, and generate additional preauthorizations. Or secondly, using any method (including root seed, or generating from pure entropy), generate keys on this new device and make a request to be added to the keyset. Then just go to one of your previous devices and approve the request.

We briefly mentioned another revocation method — what is it?

3.3 — DeepKey Revocation

The concept of a revocation key is pretty straightforward and has been used in other cryptography settings, like PGP or TLS certificates. But does it really provide the desired protection? It feels like something is missing, especially in the case of Holo end-users, where the application seed and revocation seed are both derived from the same password.

In Holochain or Holo, revocation is a process that also allows you to migrate from using an existing key pair to a new, hopefully secure, key pair within a particular app. You can also change your revocation key or method. A Holo user could always “revoke” their revocation key, replacing it with one they had generated offline. At that point, however, they may as well just download and run the Holochain application.

Enter the “M of N” revocation method.

You’ve been using Holochain or Holo for a while, set up a Holochat account, filled out your Persona, found some friends, and connected with people you know IRL (in real life). It’s time to upgrade your security. Pick four friends — ask them first! — then authorize them and yourself to be a “3 of 5” revocation group.

If you need to change something in your DeepKey keyset, request the change. You count as one signature. Connect with your friends through a different channel, preferably real life, video, or voice — that way they know it’s really you — and ask them to sign it. When you collect at least two more signatures, your change will be published.

4 — Are We There Yet?

Have we achieved a low barrier to entry that provides solid security, allows for more complex security upgrades, and that is understandable overall?

Allowing web users to log on with an email address and a password is a good start, but there are still a few problems:

  • We cannot, in good conscience, persist private keys in the browser to save the session if a tab is closed. Even if we tried to encrypt the keys to save in browser storage, they’d still have to enter a password to decrypt them.
  • There is no such thing as a password reset because we don’t have access to the password that generated your keys. If you forget or mistype it, there is no way forward.
  • Upgrading to an “M of N” revocation provides a lot of additional protection. But how likely are Holo users to choose this option? Efforts in education and gamification of account setup may help.
  • Even with the best password hashing scheme, a bad password will be easy to hack. Strong educational messaging recommending the use of a password manager will help.

5 — Algorithm Appendix

  • Signatures — crypto_sign_* — EdDSA Ed25519
  • Encryption
  • Key Exchange — crypto_kx_* — rx || tx = BLAKE2B-512(p.n || client_pk || server_pk)
  • Symmetric — crypto_aead_xchacha20poly1305_ietf_* — XChaCha20 stream cipher / Poly1305 MAC / IETF construct
  • Password Hashes — crypto_pwhash_* — Argon2id (“sensitive” ops and mem limits)
  • Entropy Derivation — crypto_kdf_* — BLAKE2B-256(key=key, message={}, salt=subkey_id || {0}, personal=ctx || {0})