bitcoinjs / bitcoinjs-lib

A javascript Bitcoin library for node.js and browsers.
MIT License
5.62k stars 2.09k forks source link

BIP32 master key different from bitcoinj or NBitcoin? #1128

Closed sugarac closed 6 years ago

sugarac commented 6 years ago

When I tested the WIF and used fixed mnemonic, I found that the master key and child key generated by bitcoinjs-lib are different from those by bitcoinj or NBitcoin. Bitconj and NBitcoin can generate the same result from the same mnemonic.

Code is provided below. Hope somebody could help me! I don't know which step is wrong. In below code, I used my company's blockchain network, which is paicoin. All above mentioned tests used paicoin network. If you want more details, please let me know.

let words = 'social sustain scan pulp borrow immune sad quick pole boring plastic amused';
let seedHex = bip39.mnemonicToSeedHex(words);
console.log('seed: ' + seedHex); 

let paicoin = {
};

let root = bitcoin.HDNode.fromSeedHex(seedHex, paicoin);
console.log('Master key WIF: ' + root.keyPair.toWIF()); 
// dYoN7jThxt48LFLjpf9H1qwSqZptuKuY8vARZ9pZP5eRt8jUahas
// dd55nrZ2N4uTDMt83xYSS3hEKtZfeCgUsbck5DNyFwtjsmx7AFmq generated by Bitcoinj and NBitcoin

let child0 = root.derivePath("m/0'/0'/0'");
console.log("child0.keyPair.toWIF(): " + child0.keyPair.toWIF()); 
// dezhmG8JEw759TpKDLB419NN4SwTYxTpXhfw4UTF7126rjXwhyz6
// dZzJBEnJCTDhSs2d78DZ718DUP2UxAg5JUCMr6N9gQvomYE3S6kA generated by Bitcoinj and NBitcoin
dcousens commented 6 years ago

The network information shouldn't matter.

Can you post the output of bip39.mnemonicToSeedHex from this library, in comparison to libbitcoin or bitcoinj?

If they are the same, we can rule them out and focus on the BIP32 part, otherwise, focus on BIP39 part.

sugarac commented 6 years ago

bip39.mnemonicToSeedHex : 9777cf3bee893ac464452e464b73c307c454fced6a78b43658068a88add1d0afe65f27359492ddc48b4023f199f0edfd224c675cd5238672da346ce4910aba5c. The seed is the same as other libraries. @dcousens

dcousens commented 6 years ago

Then we can reduce your problematic code to

let seedHex = '9777cf3bee893ac464452e464b73c307c454fced6a78b43658068a88add1d0afe65f27359492ddc48b4023f199f0edfd224c675cd5238672da346ce4910aba5c'

let root = bitcoin.HDNode.fromSeedHex(seedHex)
console.log('Master WIF: ' + root.keyPair.toWIF()) 
// Master WIF: KwoL5Xaf8b2mNfmL1eB1H8gVDrvGZXe2mM2uy6bHx8xjNk5G2fLS
sugarac commented 6 years ago

let root = bitcoin.HDNode.fromSeedHex(seedHex, paicoin); The problem may be caused this code. But I don't know how it can cause any issue.

dabura667 commented 6 years ago

just out of curiosity, could you post the network info object used with the above code?

dcousens commented 6 years ago

@sugarac I updated my reduced test code above, could you compare results with bitcoinj/libbitcoin?

sugarac commented 6 years ago

Hi, I posted the network info at first. But my team leader said that I shouldn't post the specific info. The network info has same format as bitcoin. @dabura667

  bitcoin: {
    messagePrefix: '\x18Bitcoin Signed Message:\n',
    bech32: 'bc',
    bip32: {
      public: 0x0488b21e,
      private: 0x0488ade4
    },
    pubKeyHash: 0x00,
    scriptHash: 0x05,
    wif: 0x80
  },
sugarac commented 6 years ago

@dcousens Hi, thanks so much for your patience about my issue. I have changed code, but the result does not change, which is still different from other libraries.

dcousens commented 6 years ago

@sugarac can you compare the code in https://github.com/bitcoinjs/bitcoinjs-lib/issues/1128#issuecomment-405420094 with libbitcoin?

sugarac commented 6 years ago

@dcousens Hi, I had compared the bitcoinjs-lib code with bitcoinj code. But I founded that the specific steps have some difference.

String wordPhrase = "social sustain scan pulp borrow immune sad quick pole boring plastic amused";
List<String> words = Arrays.asList(wordPhrase.split(" "));
byte[] keyEntropy = code.toEntropy(words);
DeterministicKey masterKey = HDKeyDerivation.createMasterPrivateKey(keyEntropy);
String masterKeyWif = masterKey.getPrivateKeyAsWiF(params);
DeterministicKey childKey = HDKeyDerivation.deriveChildKey(masterKey, ChildNumber.ZERO_HARDENED);
System.out.println("WIF from Mnemonic phrase: " + childKey.getPrivateKeyAsWiF(params));
dcousens commented 6 years ago

@sugarac if your keyEntropy is guaranteed to be equivalent to 9777cf3bee893ac464452e464b73c307c454fced6a78b43658068a88add1d0afe65f27359492ddc48b4023f199f0edfd224c675cd5238672da346ce4910aba5c.

Then the only lines that matter here:

DeterministicKey masterKey = HDKeyDerivation.createMasterPrivateKey(keyEntropy);
String masterKeyWif = masterKey.getPrivateKeyAsWiF(params);

If you could print/show masterKeyWif, that'd be swell (with no custom network information).

sugarac commented 6 years ago

@dcousens masterKeyWif is dd55nrZ2N4uTDMt83xYSS3hEKtZfeCgUsbck5DNyFwtjsmx7AFmq, which is different from dYoN7jThxt48LFLjpf9H1qwSqZptuKuY8vARZ9pZP5eRt8jUahas by bitcoinjs-lib.

dcousens commented 6 years ago

If you could print/show masterKeyWif, that'd be swell (with no custom network information).

Emphasis added

junderw commented 6 years ago

What is params in masterKey.getPrivateKeyAsWiF(params)

junderw commented 6 years ago

Hi, I posted the network info at first. But my team leader said that I shouldn't post the specific info.

Your edit history is public. Anyone can see it, even if you close the issue... there's no way to completely delete data you post on Github.

That said, looking at your network info it doesn't look like it should cause problem.

junderw commented 6 years ago

Checking the two WIFs you sent: The formatting is proper but the private keys themselves are completely different.

f7 version
90bb094505d275f1ee261b6425fcdd43bbd7c8bd46323716e99f33b379ca59e0
01 compression byte
7b9f2148 checksum

f7
114b793ba22e6b8dfba435ecef1bb607a7f428fc3a3e32589d4afce9c3099a0f
01
d8997ea4
dcousens commented 6 years ago

Cannot reproduce this with libbitcoin, @sugarac you will need to provide more information. Closing until then.

Output KwoL5Xaf8b2mNfmL1eB1H8gVDrvGZXe2mM2uy6bHx8xjNk5G2fLS as expected.