Skip to content
This repository has been archived by the owner on Apr 17, 2023. It is now read-only.

Integrate a BIP44-compliant & multi-device HD keychain system #330

Closed
shea256 opened this issue Mar 21, 2017 · 50 comments
Closed

Integrate a BIP44-compliant & multi-device HD keychain system #330

shea256 opened this issue Mar 21, 2017 · 50 comments
Assignees

Comments

@shea256
Copy link
Contributor

shea256 commented Mar 21, 2017

Requirements:

  • private keys should never leave a device
  • users should be able to define the quorum of devices required to add additional devices or make name transactions
  • only the user should know which apps she uses
  • name keys should be generated deterministically given the device secret and the name index
  • apps should not be able to derive the keys of other apps
  • minimize bitcoin transactions where possible
  • minimize information disclosed
@shea256 shea256 added the v0.6.0 label Mar 21, 2017
@shea256 shea256 added this to the Release v0.6.0 milestone Mar 21, 2017
@shea256 shea256 self-assigned this Mar 21, 2017
@guylepage3 guylepage3 mentioned this issue Mar 22, 2017
47 tasks
@shea256 shea256 removed the v0.6.0 label Mar 24, 2017
@larrysalibra larrysalibra removed this from the Release v0.6.0 milestone Apr 3, 2017
@larrysalibra larrysalibra assigned larrysalibra and unassigned shea256 May 20, 2017
@shea256
Copy link
Contributor Author

shea256 commented May 20, 2017

We already worked out the HD paths here: #131

@larrysalibra larrysalibra added this to the Release v0.9.0 milestone May 20, 2017
@shea256
Copy link
Contributor Author

shea256 commented May 20, 2017

See this for the keychain model: https://forum.blockstack.org/t/blockstack-keychain-model-lets-discuss/726

@shea256
Copy link
Contributor Author

shea256 commented May 20, 2017

Device keychain --> identity branch --> name account --> owner, signing, encryption keychains

m / 888' / 0' / 0' / 0 = name owner
m / 888' / 0' / 0' / 1 = name admin
m / 888' / 0' / 0' / 2 = signature verifier
m / 888' / 0' / 0' / 3 = data encrypter
m / 888' / 0' / 0' / 0' = app keychain

@shea256
Copy link
Contributor Author

shea256 commented May 20, 2017

@larrysalibra Does this look good to you?

@shea256
Copy link
Contributor Author

shea256 commented May 20, 2017

Keychain model visual:

12bfb84bbf1efc0e957da0995a342a3418e94638

@shea256
Copy link
Contributor Author

shea256 commented May 20, 2017

For bitcoin, we'll simply use the following:

  • m / 44’ / 0’ / 0’ / 0 / 0

Later, we'll make the wallet multi-address and add the ability to have new paths:

  • m / 44’ / 0’ / 0’ / 0 / 1
  • m / 44’ / 0’ / 0’ / 0 / 2
  • m / 44’ / 0’ / 0’ / 1 / 0 (change)

@shea256
Copy link
Contributor Author

shea256 commented May 20, 2017

Some quick code I whipped up for this:

import {randomBytes} from 'crypto'
import {HDNode} from 'bitcoinjs-lib'

const masterKeychain = HDNode.fromSeedBuffer(randomBytes(32))
const masterKeychainID = masterKeychain.neutered()

const bitcoinKeychain = masterKeychain.deriveHardened(44).deriveHardened(0)
const firstBitcoinAddress = bitcoinKeychain.deriveHardened(0).derive(0)

const identityKeychain = masterKeychain.deriveHardened(888).deriveHardened(0)
const firstIdentityAddress = identityKeychain.derive(0)

@larrysalibra
Copy link
Collaborator

Awesome!

@shea256
Copy link
Contributor Author

shea256 commented Jun 8, 2017

@larrysalibra where is the requirements document?

@larrysalibra
Copy link
Collaborator

larrysalibra commented Jun 8, 2017

@shea256 it's just a list of bullet points at the top of this issue. no formal doc at the moment.

feel free to add.

@shea256
Copy link
Contributor Author

shea256 commented Jun 8, 2017

Alternatively, we could forgo any dedicated keys beneath an owner key, and say that everything is an app. If I want to send you an encrypted message, I'm going to be using an app to do so. That app can be built into Blockstack, but it's still an app and thus should still use an app-specific key.

Yes exactly. This was my thinking with the diagram above. There would be the branch m/888'/0'/0' and then there's the name owner key at the "0" leaf and then every app is a hardened leaf off of that. This would include the browser portal itself. The browser portal would be considered just another app.

App keys will generally be generated from domain names, icann or blockstack. It seems strange to me to diverge from this convention for encryption and signing keys by using arbitrary strings (that aren't registered domain names) to generate those keys.

Building off of this, we could have the browser portal's "domain" or "origin" be simply "localhost". The main purpose of our app-specific keys is to separate keys by origin. Local storage is organized by origin so this is a nice corollary.

@shea256
Copy link
Contributor Author

shea256 commented Jun 8, 2017

Along the lines of keys being used for a high volume of signatures, we'll need to be able to rotate the app-specific keys as well. This could be done simply by rotating the salt.

@larrysalibra
Copy link
Collaborator

Building off of this, we could have the browser portal's "domain" or "origin" be simply "localhost". The main purpose of our app-specific keys is to separate keys by origin. Local storage is organized by origin so this is a nice corollary.

Not sure this is such a good idea in that any app running on localhost would share the same keys as the portal. Is that something we want?

Along the lines of keys being used for a high volume of signatures, we'll need to be able to rotate the app-specific keys as well. This could be done simply by rotating the salt.

Where does the salt come from?

@shea256
Copy link
Contributor Author

shea256 commented Jun 8, 2017

Not sure this is such a good idea in that any app running on localhost would share the same keys as the portal. Is that something we want?

Sorry, to clarify, it would be "localhost:8888" instead of just localhost. Only one app can run on "localhost:8888" at a time and all such apps running on "localhost:8888" will share local storage anyway.

Along the lines of keys being used for a high volume of signatures, we'll need to be able to rotate the app-specific keys as well. This could be done simply by rotating the salt.

Jude and I figured out earlier we'd need a salt when we were exploring the int32(hash(appname)) stuff.

@kantai
Copy link
Collaborator

kantai commented Jun 8, 2017

I think for right now, it's important to spec out the paths that will ultimately require "update" transactions. App keys won't, so maybe we can fully decide on the app key paths at another time, and just go with something that works for them for now?

@larrysalibra
Copy link
Collaborator

Agree @kantai

@larrysalibra
Copy link
Collaborator

We need to encrypt the app key information to prevent others from knowing which apps you are using. To do this, we need the encrypt key to live outside of the app key hierarchy.

We plan to use a symmetric key to encrypt the app names, store the cipher text in the token file. Sharing that you are using an app with someone will involve sharing the symmetric key.

@larrysalibra
Copy link
Collaborator

I've merged the new keychain format into v0.10. Registrations from this commit on won't need to be migrated. 920e406

larrysalibra added a commit that referenced this issue Jun 16, 2017
larrysalibra added a commit that referenced this issue Jun 16, 2017
@larrysalibra
Copy link
Collaborator

larrysalibra commented Jun 16, 2017

Don't use hashcode #538

We'll also need to create a new issue to update token file to create the key delegation bundle before we can close this out.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants