dart-bitcoin / bip32-dart

A BIP32 compatible library for Flutter writing by Dart.
MIT License
19 stars 35 forks source link

invalid derivation result for specific path #1

Closed asssaf closed 4 years ago

asssaf commented 4 years ago

seed:xprv9s21ZrQH143K3Jpuz63XbuGs9CH9xG4sniVBBRVm6AJR57D9arxWz6FkXF3JSxSK7jUmVA11AdWa6ZsUtwGztE4QT5i8Y457RRPvMCc39rY path: m/1'/199007533'/627785449'/1521366139'/1' result: xprvA39a1i4ieYqGXFQSJ1HtoUVPqzUXU1JgUW4RMgzhv8HuPvkjWBKpMCxFGU4tJKfH83m6QmiWUe2w1zfQBxRkoAoSVtYE6ZbA9RDBjZiPU7M expected: xprvA39a1i4ieYqGUQ7G1KGnaGzGwm7v3emjms3QN4jZ3HPeubXjshA3XjD5XFaiNgWFvoyC2NV5jN4eFcsVhkrWkvwR4qjdPbue3kpt6Ur3JRf

expected value verified both using bitcoinjs/bip32 as well as bip32.org.

Looks like the derivation is skipping to the next index due to the check in bip_base.dart#109

Deriving m/1'/199007533'/627785449'/1521366139' produces the correct result so only the last segment causes the issue.

Test code:

  test('bug', () {
    final hd = BIP32.fromBase58('xprv9s21ZrQH143K3Jpuz63XbuGs9CH9xG4sniVBBRVm6AJR57D9arxWz6FkXF3JSxSK7jUmVA11AdWa6ZsUtwGztE4QT5i8Y457RRPvMCc39rY');
    final d = hd.derivePath("m/1'/199007533'/627785449'/1521366139'/1'");
    expect(d.toBase58(), 'xprvA39a1i4ieYqGUQ7G1KGnaGzGwm7v3emjms3QN4jZ3HPeubXjshA3XjD5XFaiNgWFvoyC2NV5jN4eFcsVhkrWkvwR4qjdPbue3kpt6Ur3JRf');
  });
asssaf commented 4 years ago

both libraries agree on the result of m/1'/199007533'/627785449'/1521366139'/2' so it looks like the difference is that this library skips the 1' index and the others don't.

rafa-js commented 4 years ago

Can you see if m/1'/199007533'/627785449'/1521366139' matches with m/1'/199007533'/627785449'/1521366140'?

It's what happen to me. So I guess the issue has something to do with this line: https://github.com/anicdh/bip32-dart/blob/master/lib/src/bip32_base.dart#L103

Looking deeper.

asssaf commented 4 years ago

Can you see if m/1'/199007533'/627785449'/1521366139' matches with m/1'/199007533'/627785449'/1521366140'?

That pair yields different results for me

keninqiu commented 4 years ago

When do Uint8List dt = toBuffer((dd + tt) % n); It will happened the length of dt is smaller than 32. We have to make sure the length is always 32.

I added if(dt.length < 32) { Uint8List newDt = new Uint8List(32); for(var i = 0; i < 32 - dt.length; i++) { newDt[i] = 0x00; } for(var i = 0; i < dt.length; i++) { newDt[32-dt.length + i] = dt[i]; } dt = newDt; } to ecurve.dart It will fix this issue. I already made a pull request.

longhoangwkm commented 4 years ago

Thanks everyone for report and helping