Does Mnemonic implement BIP39?


(David) #1

It doesn’t mention anything about it in the documentation but I was wondering if the Mnemonic class implements BIP39. If not, why not? If so what am I doing wrong below? I believe this should give me the same address as Mycelium with the same word list but it doesn’t.

new bitcore.Address(new Mnemonic('poverty real nuclear heart social embody maximum excuse pluck stove license salad').toHDPrivateKey().derive("m/44'/0'/0'/0/0").publicKey, 'testnet').toString();
> "mrJD1EduPvpRAGR7LnaoVMM3GoTudi6Xrf"

On TestNet Mycelium I get msVh85jLty948Hvq5BcnHGa3nEHPWbet71


(Braydon Fuller) #2

How are you comparing results with Mycelium?


(David) #3

I tell Mycelium to restore from backup and type in the seed words.

Is bitcore Mnemonic supposed to implement BIP39 or not?


((micro-machine)) #4

Here’s how I did it, and got it to match Mycelium. Did not try it on testnet yet, but it matches for the livenet. It uses BIP32+BIP39+BIP44.

// Get a new Mnemonic seed:
var mnemonicSeed = new Mnemonic(Mnemonic.Words.ENGLISH);

// Calculate HD Master Extended Private Key:
var hdMastExtPrivKey = mnemonicSeed.toHDPrivateKey();

// Derived External HD Private Key:
var hdExternalPrivKey = hdMastExtPrivKey.derive("m/44'/0'/0'/0/0");

// Derived External Private Key:
var myExternalPrivKey = hdExternalPrivKey.privateKey;

// Derived External Public Key:
var myExternalPublKey = myExternalPrivKey.publicKey;

// Derived External Public Address:
var myExternalAddress = myExternalPublKey.toAddress();

So in shorthand form like what you have, I think that would be:

var myExternalAddress = new Mnemonic(Mnemonic.Words.ENGLISH).toHDPrivateKey().derive("m/44'/0'/0'/0/0").privateKey.publicKey.toAddress();

Don’t quote me on that second part… I may have made a typo, as I haven’t tested that shortened form out.

Comparing our methods, we do the “Address” call a little differently, but also I have “.privateKey” after the “derive” part. One of those two things might be the difference?

Let me know if any of this helps. BTW - I like your tool that you made. I’ll be sharing a project myself in the next week or two hopefully!


(David) #5

Where did you enter your 12 words?
I tried the code below but am still getting the same address.

Also, if it does indeed implement BIP39 I think it would be good to mention that in the documentation. It’s rather important.

// Get a new Mnemonic seed:
var mnemonicSeed = new Mnemonic('poverty real nuclear heart social embody maximum excuse pluck stove license salad', Mnemonic.Words.ENGLISH);

// Calculate HD Master Extended Private Key:
var hdMastExtPrivKey = mnemonicSeed.toHDPrivateKey('', 'testnet');

// Derived External HD Private Key:
var hdExternalPrivKey = hdMastExtPrivKey.derive("m/44'/0'/0'/0/0");

// Derived External Private Key:
var myExternalPrivKey = hdExternalPrivKey.privateKey;

// Derived External Public Key:
var myExternalPublKey = myExternalPrivKey.publicKey;

// Derived External Public Address:
var myExternalAddress = myExternalPublKey.toAddress('testnet');

window.console.log(myExternalAddress.toString());
> "mrJD1EduPvpRAGR7LnaoVMM3GoTudi6Xrf"

((micro-machine)) #6

I generated a new seed. When you call

var mnemonicSeed = new Mnemonic(Mnemonic.Words.ENGLISH);

you get a new seed. If you want to re-use your seed, it’s just

var mnemonicSeed = new Mnemonic('poverty real nuclear heart social embody maximum excuse pluck stove license salad');

I don’t think you need to include the Mnemonic.Words.ENGLISH part.

BIP39 is just Mnemonic. When you go to Bitcore.io’s Mnemonic documentation, BIP39 is mentioned.


((micro-machine)) #7

As I was submitting my last reply, your problem dawned on me. As per BIP44, the Bitcoin Testnet has a different Coin Type as the bitcoin mainnet. Try derive("m/44'/1'/0'/0/0").


(David) #8

Yes, of course! Why didn’t I think of that? It worked.
It would be nice if there was an API that implements BIP44 so that it’s harder to make stupid mistakes like this.

BIP39 is just Mnemonic. When you go to Bitcore.io’s Mnemonic2 documentation, BIP39 is mentioned.

I looked at the API documentation which doesn’t mention BIP39 anywhere.

I don’t think you need to include the Mnemonic.Words.ENGLISH part.

When you create a random seed, you don’t need to specify the word list either. I just tried to make my code as similar as possible to yours.


Useful info to add to Bitcore API
((micro-machine)) #9

Glad that was the solution! It’s nice to think these things through with other folks from time to time. And you’re right, it’s only in the “guide/docs” and not the “api” information.

I’m going to link this thread to the Website and Docs page to bring attention to your point about BIP39 not being mentioned on the API page.


(Manuel Araoz) #10

Again, sorry for the late answer, my email notifications were disabled for some reason.

I’m happy to see @mike helped you sort this out.
@dskloet: It’s true, the API documentation doesn’t mention BIP39. I have fixed that in this PR, so the docs will be updated next time we release bitcore (next week). https://github.com/bitpay/bitcore-mnemonic/pull/16

Regarding the BIP44 implementation, we thought about adding simple support for that (BIP43, BIP45 too probably). Do you have any ideas on this? Maybe a bitcore-paths module? EDIT: I opened an issue to discuss this: https://github.com/bitpay/bitcore/issues/1121


(David) #11

I have no opinion on what goes into which module but I thought BIP44 could be a simple extension to PrivateKey and PublicKey. BIP44 uses accounts as a metaphor so that may be useful in naming. Something like

var privateAccount = privateKey.getAccount(n, network);
var privateKey = privateAccount.getPrivateKey(k);
var changePrivateKey = privateAccount.getChangePrivateKey(c);```
etc.