Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Steem] Integrate 'cointype' and add specifications slip-48 for graphene based HD wallets #50

Closed
wants to merge 1 commit into from

Conversation

xeroc
Copy link
Contributor

@xeroc xeroc commented Oct 19, 2016

This is a Pull request - read for comment. It

  • adds the cointype 137 for Steem
  • adds a slip-48 draft specification to deal with multiple "accounts" on a single seed using deterministic key hierarchies
  • a demo script in python to derive keys according to bip44 specifically for slip48

@xeroc
Copy link
Contributor Author

xeroc commented Oct 20, 2016

Some thoughts from @arhag:

I'm commenting as I go. Why don't you just use a SHA256 hash as the index instead of a small integer? Then you can take the SHA256 of a unique string (the name of the network, account, etc.)?
I think permission should be role instead and it should always include an "other"
Then I think you should have multiple generations as a bottom leaf node in the hierarchy (still hardened of course).
I should be able to change a compromised posting key without needing to change my master key.
There are lots of advantages to using the SHA256 hash of a well understood string rather than defining constants for each network,permissions, etc. But one disadvantage is that you cannot have account discovery because you need to actually know the name of the account for which you want to check if your master key derives any currently active keys for that account.

xeroc [9:01 PM] :
@arhag we thought about using a sha hash for the account leaf aswell but it wont allow to list accounts that are on the device .. you would nees to know which accounts are on the device .. i dont think we really 'need' multiple sub keys per leaf .. why would you want to change accounts keys? And if you need you can just jump to an entire new leaf

[9:02] :
If you still allow subkeys .. then you would also need to scan previous subkeys ..

arhag [9:03 PM] :
I don't think of this standard as only be useful on a device like a Trezor

I want to be able to for example take the an account's current posting key and put it on a different device. (edited)
But if it gets compromised, I want my other more secure device to be able to generate the new generation of that posting key so I can replace it.
Without needing to change all my keys on all Graphene-based blockchain accounts.
You could still use sequence number indexing for the account level only to keep account discovery.
While still using SHA256 for network and role which would be more convenient and general.
Since people can add new roles or networks without needing to modify the standard.
Also you can technically have both sequence and string based indexing for the account level. Then by having both keys in the owner and/or active Graphene permission (both are not necessary to sign), you have a way of discovering accounts without needing to do that long time-consuming process if you already know all the accounts you care about. (edited)
Essentially, the sequence-based derived keys would just act as tags for account discovery.
You can even just include them in the JSON metadata actually.
SHA256 based indexing for accounts also enables an interesting feature: plausible deniability for accounts.
If you need a secret passphrase concatenated to the account name prior to SHA256 in order to derive the seed key at the account level, then you could have hidden accounts that can only be unlocked if you know the passphrase. (edited)

xeroc [9:11 PM] :
how does the sha bases indexing work exactly?
Trezor has a secret xor passphrase for the master seed

arhag [9:11 PM] :
https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
Basically modify this so that i is a 256-bit number that is serialized. (edited)
Hmm sure I guess xor-ing at the master seed level works too.

xeroc [9:14 PM] :
Need to think through account discovery .. which was my main motivation to do simple indexing ..

arhag [9:15 PM] :
Just include tags in the json meta-data

One of the branches of the hierarchy (under the network subtree) could be a "account-discovery" branch with a sequence index. Private keys are derived in that branch and their corresponding public key is the tag. A service returns all account names that have that (valid) tag in their json metadata. To be a valid tag, it needs to include that public key along with a signature with the corresponding private key of SHA256(public key || account name). Then you go through the set of returned accounts and check their permissions individually to verify if they are actually controlled by keys derived by the master key. (edited)

m / purpose' / network* / category*
                           |- "account-discovery" / index' 
                           |- "accounts" / account-name* / role* / gen'
  • is like ' (meaning it uses hardened child derivation) except it uses a SHA256 of a string as the index rather than a small number.

@xeroc
Copy link
Contributor Author

xeroc commented Oct 20, 2016

I'm commenting as I go. Why don't you just use a SHA256 hash as the index instead of a small integer? Then you can take the SHA256 of a unique string (the name of the network, account, etc.)?
I think permission should be role instead and it should always include an "other"
Then I think you should have multiple generations as a bottom leaf node in the hierarchy (still hardened of course).
I should be able to change a compromised posting key without needing to change my master key.
There are lots of advantages to using the SHA256 hash of a well understood string rather than defining constants for each network,permissions, etc. But one disadvantage is that you cannot have account discovery because you need to actually know the name of the account for which you want to check if your master key derives any currently active keys for that account.

I personally would prefer to have an account discovery integrated mostly because I don't want have to maintain a list of accounts that can be deal with using a wallet.

I want to be able to for example take the an account's current posting key and put it on a different device.
But if it gets compromised, I want my other more secure device to be able to generate the new generation of that posting key so I can replace it.
Without needing to change all my keys on all Graphene-based blockchain accounts.

This is a very good point!

You could still use sequence number indexing for the account level only to keep account discovery.
While still using SHA256 for network and role which would be more convenient and general.
Since people can add new roles or networks without needing to modify the standard.

They won't need to change the standard, each network has its own tree and can easily add new roles. All that is required is for them to agree on how they do things.
If we indexed roles with an incrementing integer, it's actually quite easy to figure out that there are some kind of new roles on other networks.
For instance, Steem knows a "posting" role, so we take the active or memo index, increment by one, derive a key and see that the blockchains knows an account for that key.
There obvisouly is a role to that index! This is something that the wallet (developers) needs to know, not necessarily the standard.

Also you can technically have both sequence and string based indexing for the account level. Then by having both keys in the owner and/or active Graphene permission (both are not necessary to sign), you have a way of discovering accounts without needing to do that long time-consuming process if you already know all the accounts you care about.
Essentially, the sequence-based derived keys would just act as tags for account discovery.
You can even just include them in the JSON metadata actually.

This sounds overcomplicated and because the BIP44 derivation of the keys can be done online from the master public key, I don't see why it is time-consuming.
It may require some more bandwidth to discover accounts and roles, but if we pick a small pubkey gap limit, this shouldn't be too bandwidth consuming.

SHA256 based indexing for accounts also enables an interesting feature: plausible deniability for accounts.
If you need a secret passphrase concatenated to the account name prior to SHA256 in order to derive the seed key at the account level, then you could have hidden accounts that can only be unlocked if you know the passphrase.

This can be done with the wallets passphrase aswell (which is an XOR on the master seed)

arhag [9:11 PM] :
https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
Basically modify this so that i is a 256-bit number that is serialized.
Hmm sure I guess xor-ing at the master seed level works too.

In the case of trezor, i think this is just overcomplicating things with no real benefit.

arhag [9:15 PM] :
One of the branches of the hierarchy (under the network subtree) could be a "account-discovery" branch with a sequence index. Private keys are derived in that branch and their corresponding public key is the tag. A service returns all account names that have that (valid) tag in their json metadata. To be a valid tag, it needs to include that public key along with a signature with the corresponding private key of SHA256(public key || account name). Then you go through the set of returned accounts and check their permissions individually to verify if they are actually controlled by keys derived by the master key.

We'd like to go productive on the trezor without needing to modify the graphene API code or setup another service.
The API currently already has an api that returns the accounts that are associated with a public key. That's why we would simply derive the pubkey from the tree and can obtain the account names directly from that. After finding the accounts and roles, we can simply let the wallet sign any transaction by providing the "tree" through the master seed.

Having another account-discovery branch requires accounts to have multiple keys in their roles for no real benefits except for faster (less processing/datarate consuming) discovery.
And since the current API cannot search for 'tags' in the meta data of an account (yet), we'd need to put the account discovery key somewhere in the roles. If we allowed the user to modify the the permissions and keys, then we end up in the same problem of having to go through multiple possible keys to discover accounts.

@prusnak
Copy link
Member

prusnak commented Nov 25, 2016

Can we use cointype 135 for Steem instead? This one is free and 137 already got reserved by oversight and is already used in the wild.

@xeroc
Copy link
Contributor Author

xeroc commented Nov 28, 2016

@prusnak sure

@prusnak
Copy link
Member

prusnak commented Nov 28, 2016

Merged manually in e488787

Thank you!

@prusnak prusnak closed this Nov 28, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants