From fea199d1c8ef8198bde5d6a8af81c4c65db53312 Mon Sep 17 00:00:00 2001 From: Shun Usami Date: Thu, 12 Sep 2019 22:12:19 +0900 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fix=20Private=20key=20derivation?= =?UTF-8?q?=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Pads with 0 if length is less than 32 bytes --- .../BitcoinKit.Private.swift | 5 ++++- Tests/BitcoinKitTests/HDPrivateKeyTests.swift | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Sources/BitcoinKitPrivate/BitcoinKit.Private.swift b/Sources/BitcoinKitPrivate/BitcoinKit.Private.swift index c6e581fd..81dd1634 100644 --- a/Sources/BitcoinKitPrivate/BitcoinKit.Private.swift +++ b/Sources/BitcoinKitPrivate/BitcoinKit.Private.swift @@ -180,7 +180,7 @@ public class _HDKey { return nil } - var result: Data = Data() + var result: Data if let privateKey = self.privateKey { let privateKeyNum = BN_new()! defer { @@ -205,6 +205,9 @@ public class _HDKey { BN_bn2bin(privateKeyNum, ptr) return } + if result.count < 32 { + result = Data(repeating: 0, count: 32 - result.count) + result // 0 padding + } } else { let publicKeyNum = BN_new() defer { diff --git a/Tests/BitcoinKitTests/HDPrivateKeyTests.swift b/Tests/BitcoinKitTests/HDPrivateKeyTests.swift index 7d605605..725c5334 100644 --- a/Tests/BitcoinKitTests/HDPrivateKeyTests.swift +++ b/Tests/BitcoinKitTests/HDPrivateKeyTests.swift @@ -174,4 +174,23 @@ class HDPrivateKeyTests: XCTestCase { let m011pub = try! m01prv.extendedPublicKey().derived(at: 1) XCTAssertEqual(m011pub.extended(), "xpub6D4BDPcEgbv6teFCGk7PMijta2aSGvRbvFX8dthHedYVVMM8QBf9xp9TF6TeuHYD9xiHGcuGNZQkKmD9jvojPj7YqnqtB3iYXv3f8s1JzwS") } + + // https://github.com/yenom/BitcoinKit/issues/73 + func testDeriveProblem() { + let seed = Data(hex: "f27fd395d30d00f1c11b7551a93961ca41c0a78bce21e9a618e83a99cf74aec159139ef3ef078bc0038557b7cb689933d0806ce33571df78bc4397e7f9976ff2")! + + let key = try! HDPrivateKey(seed: seed, network: .mainnet) + .derived(at: 44, hardened: true) + .derived(at: 0, hardened: true) + .derived(at: 0, hardened: true) + .derived(at: 1) + .derived(at: 19) + + let privKey = key.privateKey() + XCTAssertEqual(privKey.data.count, 32) + XCTAssertEqual(privKey.data.hex, "00f2c37dad54d1d2be57b06653ea655c6fd8eb3ca3f0b9671e036d50061d265b") + XCTAssertEqual(privKey.description, "KwFZ6jFtuvBu7w4R4x4WpzQgSSYTHLEw8Pr2PUkWjADkHJUPNDVg") + XCTAssertEqual(privKey.publicKey().description, "02a712f894d58baef44e4fbbc26ed6ca89487db1f17e944f9b45ca2ae666e99d72") + XCTAssertEqual(privKey.publicKey().toLegacy().description, "1DPUysR46jraybTwP3PfSbcBENeLScLxx") + } }