nanocurrency / nano-node

Nano is digital currency. Its ticker is: XNO and its currency symbol is: Ӿ
https://nano.org
BSD 3-Clause "New" or "Revised" License
3.48k stars 787 forks source link

Deterministic wallets - BIP32/44? #601

Open fu5ha opened 6 years ago

fu5ha commented 6 years ago

Is there a record of discussion on why a new wallet seed technique was used over a BIP32/44-based scheme? Would there be interest in adding support for BIP32/44 to the wallet or at least standardizing a private/public key derivation scheme based on them so that new wallets in the future can support them?

PlasmaPower commented 6 years ago

Our private keys are half the size of Bitcoin's.

fu5ha commented 6 years ago

Well sure, but it would be quite easy to take standard derived keys and perform some agreed upon algorithm (either an extra round of hashing or simply taking the high or low bytes) so that you still conform to the standard. There's a lot of value in doing so in my opinion.

On Sat, Feb 10, 2018 at 3:56 PM Lee Bousfield notifications@github.com wrote:

Our private keys are half the size of Bitcoin's.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/clemahieu/raiblocks/issues/601#issuecomment-364702674, or mute the thread https://github.com/notifications/unsubscribe-auth/AA2Ln4myF17fCgz1Kk9H4xIu0jhmc8mGks5tTh6lgaJpZM4SBGpH .

eirikrye commented 6 years ago

One great feature of the BIP32/39/44 deterministic wallets is the ability to derive a public parent key (basically a public seed), which can only derive the public keys for your accounts.

This allows you to set up watch-only wallets or nodes to monitor your accounts, without exposing your seed or private keys.

For that reason alone, I support the idea to implement a more advanced key derivation algorithm.

PlasmaPower commented 6 years ago

@eirikrye unfortunately that won't work with our ed25519 signature algorithm.

eirikrye commented 6 years ago

@PlasmaPower That is unfortunate!

fu5ha commented 6 years ago

Haven't looked through this super hard yet to see if it's compatible with our implementation of ed25519 (which I know is already partially modified) or not, but thought I'd leave it here for now. https://github.com/WebOfTrustInfo/rebooting-the-web-of-trust-fall2016/blob/master/topics-and-advance-readings/HDKeys-Ed25519.pdf

ghost commented 6 years ago

So what if I said I got bip44 derivation working as part of doing the bananos ledger app?

The bip32 path derivation uses HMAC-SHA512: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki

The ledger nano implementation of bip032 allows you to pass in any curve (NEO uses secp256r1).

Which leaves you with a private key, based on your slip44 coin id (165): https://github.com/satoshilabs/slips/blob/master/slip-0044.md

You can then use that private key to derive a public key with ed25519.

So implementing a path derivation like they have here: https://iancoleman.io/bip39/

is as simple as changing the curve, as seen here: https://coranos.github.io/neo/ledger-nano-s/recovery/

clemahieu commented 6 years ago

If an ed25519 key is derived from the other curves private key point, does it retain the hierarchical property or is it only deterministic?

ghost commented 6 years ago

I don't think you understand what I'm saying.

the bip32 algorithm derives each node using secp256k1 by default.

the bip32 algorithm can be modified to use any elliptic curve, including ed25519.

So it is both hierarchical and deterministic. It wont match https://iancoleman.io/bip39/ but it will be both hierarchical and deterministic.

I did a similar thing for NEO with secp256r1, and that site is here: https://coranos.github.io/neo/ledger-nano-s/recovery/

Its a nearly identical site, only the secp256k1 curve was swapped to secp256r1.

A simmilar thing could be done with ed25519

fu5ha commented 6 years ago

Have you actually done it with ed25519? Because the bip32 algorithm relies on the fact that the curve it’s using has linearity of key pairs so that the chain codes work. The same algorithm will not work for curve 25519 because it does not have this property. https://datatracker.ietf.org/meeting/interim-2017-cfrg-01/materials/slides-interim-2017-cfrg-01-sessa-bip32-ed25519/

On Mar 13, 2018, at 7:29 PM, coranos notifications@github.com wrote:

I don't think you understand what I'm saying.

the bip32 algorithm derives each node using secp256k1 by default.

the bip32 algorithm can be modified to use any elliptic curve, including ed25519.

So it is both hierarchical and deterministic. It wont match https://iancoleman.io/bip39/ https://iancoleman.io/bip39/ but it will be both hierarchical and deterministic.

I did a similar thing for NEO with secp256r1, and that site is here: https://coranos.github.io/neo/ledger-nano-s/recovery/ https://coranos.github.io/neo/ledger-nano-s/recovery/ Its a nearly identical site, only the secp256k1 curve was swapped to secp256r1.

A simmilar thing could be done with ed25519

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/nanocurrency/raiblocks/issues/601#issuecomment-372884201, or mute the thread https://github.com/notifications/unsubscribe-auth/AA2LnyY3Nktmn6TqJVcxRHqq8lP4_0JVks5teICggaJpZM4SBGpH.

ghost commented 6 years ago

Well, I don't know what to tell you.

the ledger code allows me to pass in a ed25519 curve to their bip32 algorithm, and it gives me a private key.

https://github.com/coranos/blue-app-banano/blob/master/src/main.c#L208

clemahieu commented 6 years ago

The hierarchical part means a parent key can sign for a child key in the hierarchy, does your implementation have that property?

ghost commented 6 years ago

I don't know, I will have to build out the signing part, as part of banano integration.

ghost commented 6 years ago

So regarding "The hierarchical part". the parent can't sign for the child, that's not the spec. The parent can derive the cildren. that's the spec, and this implementation does that.

The ed25519 curve implementation doesn't allow non-hardened children.

PlasmaPower commented 6 years ago

This is definitely possible: https://github.com/PlasmaPower/nano-bip32

My next step on this will be adding support for extended private keys to the node.

bmclain commented 6 years ago

@PlasmaPower when you say definitely possible do you mean that the parent can sign for the child, or that the private key can be derived deterministically alongside a public key, and then signed using that private key?

PlasmaPower commented 6 years ago

The latter. As you said, since ed25519 hashes in the address, a signature's address isn't malleable.

bmclain commented 6 years ago

@PlasmaPower using your nano-bip32 library, do you just import the private key via RPC and get the public address back out? Or do you have some code for generating the public address as well?

PlasmaPower commented 6 years ago

It requires some specialized code to sign using the private key it gives you, but that signature will be valid on the Nano network with the public key my program gives you.

superdarkbit commented 6 years ago

I created a webpage that demonstrates Nano addresses being made from parent public keys in accordance with BIP32 (it's based off the BIP32-Ed25519 Hierarchical Deterministic Keys over a Non-linear Keyspace paper, which @termhn linked to in one of their previous posts). You can use the instructions there to test out and see that Nano node's accept transactions signed with such BIP32-Ed25519 keys: https://superdarkbit.github.io/nano-bip32-ed25519/

Here’s a link to the code, which includes JavaScript and Python anyone can use for generating BIP32 keys for Nano, as well as signing with them: https://github.com/superdarkbit/nano-bip32-ed25519

SergiySW commented 5 years ago

Research for future

vongohren commented 4 years ago

@superdarkbit I just came over your site. A question though, would it be possible to take out a 12 word mnemocin from https://iancoleman.io/bip39/#english and derive key data from that into Ed25519 keys?

I see your implementation is generation 24 word mnemonic, and Im trying to input entropy and mnemoci myself to generate, but it just generates a new seed and mnemoic for me anyway. Is it because when I input the 12 word seed/entropy from https://iancoleman.io/bip39/#english it sees that it does not work and just generate on my behalf?

hskang9 commented 4 years ago

@termhn I believe Satoshilabs have been doing those things on SLIPS-10, and from that one can make a HD wallet library following their standard like this. However, I am not sure what curve Nano uses, and want to investigate.

clemahieu commented 4 years ago

One of our integrations has requested BIP32 hierarchical keys so we're starting to look at standardizing this kind of key derivation. The main changes we're looking at are using a single hashing algorithm, blake2, rather than a combination of them sha3 or sha512 though it looks like some have already moved this direction.

As far as packaging these up for users, we'd be looking to move/copy the proof of concept repos under the nanocurrency org though if any of the original maintainers would be interested in continuing maintenance it would be ideal.

Let me know if you guys have any thoughts about this approach. @superdarkbit @PlasmaPower

ghost commented 4 years ago

But bip32 doesn't use blake2, it uses HMAC-SHA512.

Ledger (Ledger Nano S, Ledger Nano S) and Trezor both implement the bip32 standard.

So unless you get the hardware wallets onboard, your hierarchical key derivation will still not match theirs.

This is important. When nanovault broke (wouldnt connect to ledger), funds on ledgers were unrecoverable except if you used roosma's recovery tool, which implements the bip32 standard, and gives you a regular private key.

So you can call it a bip32-like hierarchical key and use blake2, sure.

But you can't call it a bip32 standard derivation unless you use the standard implementation.

PlasmaPower commented 4 years ago

I think the biggest unresolved questions are around non-hardened derivation, which might not need to be resolved yet. Maybe for now nano could copy ledger.

clemahieu commented 4 years ago

But bip32 doesn't use blake2, it uses HMAC-SHA512.

Ledger (Ledger Nano S, Ledger Nano S) and Trezor both implement the bip32 standard.

So unless you get the hardware wallets onboard, your hierarchical key derivation will still not match theirs.

This is important. When nanovault broke (wouldnt connect to ledger), funds on ledgers were unrecoverable except if you used roosma's recovery tool, which implements the bip32 standard, and gives you a regular private key.

So you can call it a bip32-like hierarchical key and use blake2, sure.

But you can't call it a bip32 standard derivation unless you use the standard implementation.

I didn't elaborate on that fully, we're looking to get the non-hardened derivation standardized, we won't break any compatibility with existing users or the hardened key derivations.

cedvdb commented 2 years ago

While I don't understand fully all the jargon here I would like to know if something like this is deemed correct:

  final mnemonic = bip39.generateMnemonic(strength: 256);
  final seed = bip39.mnemonicToSeed(mnemonic, passphrase: 'password');
  final master = bip32.BIP32.fromSeed(seed);
  final derived = master.derivePath("m/44'/165'/0'/0/0");
  final derivedPrivHex = hex.HexEncoder().convert(derived.privateKey.toList());
  // is there a step missing here ?
  final nanoPrivateKey = nano.NanoKeys.seedToPrivate(derivedPrivHex, 0);
  final nanoPubKey = nano.NanoKeys.createPublicKey(nanoPrivateKey);
  final address =
      nano.NanoAccounts.createAccount(nano.NanoAccountType.NANO, nanoPubKey);
  print(address); // outputs nano_39pqb5grtggwnpn54xoig5r7ef6ijiwhbm4jhhqo3udc9g5yg1zpdows5ymy

From the discussion above what I understand is that it won't be possible to have a watch only wallet for nano using bip-44 ?