Skip to content

Commit

Permalink
BIP84 and BIP49 (#444)
Browse files Browse the repository at this point in the history
* BIP84 and BIP49

* Respond to code review

* Update HDChainType.scala
  • Loading branch information
torkelrogstad authored and Christewart committed May 3, 2019
1 parent 4933ca2 commit 884c261
Show file tree
Hide file tree
Showing 34 changed files with 1,562 additions and 743 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ package org.bitcoins.rpc.jsonmodels

import java.io.File

import org.bitcoins.core.crypto.bip32.BIP32Path
import org.bitcoins.core.crypto.{
DoubleSha256DigestBE,
ECPublicKey,
RipeMd160Digest,
DoubleSha256DigestBE,
ECPublicKey,
RipeMd160Digest,
Sha256Hash160Digest
}
import org.bitcoins.core.currency.Bitcoins
import org.bitcoins.core.hd.BIP32Path
import org.bitcoins.core.number.UInt32
import org.bitcoins.core.protocol.BitcoinAddress
import org.bitcoins.core.protocol.script.{ScriptPubKey, WitnessVersion}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package org.bitcoins.rpc.serializers
import java.io.File
import java.net.{InetAddress, URI}

import org.bitcoins.core.crypto.bip32.BIP32Path
import org.bitcoins.core.crypto._
import org.bitcoins.core.currency.{Bitcoins, Satoshis}
import org.bitcoins.core.hd.BIP32Path
import org.bitcoins.core.number.{Int32, UInt32, UInt64}
import org.bitcoins.core.protocol.blockchain.{Block, BlockHeader, MerkleBlock}
import org.bitcoins.core.protocol.script.{ScriptPubKey, ScriptSignature}
Expand Down
63 changes: 63 additions & 0 deletions core-test/src/test/resources/trezor.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
Mnemonic:
1. error
2. method
3. sample
4. almost
5. peanut
6. verify
7. merge
8. rapid
9. airport
10. bundle
11. execute
12. fork

$ trezorctl get-public-node -n "m/49'/0'/0'/0/0" -t p2shsegwit
node.depth: 5
node.fingerprint: fa67b318
node.child_num: 0
node.chain_code: daeb4b660634a30373623ed7f7b7929f3d017a5f0f0571df6ea7064ff5270747
node.public_key: 02b463757d4ae356b18b8a52e52da37cb5ac24f6beef443e1be4b8e0c0b253145f
xpub: ypub6c6461WnUp9LoRskZCU3bHBJahDvtrPwCCo1WEtuhsrFGZ8Mn2YMNGab2tj5eujgsMx5U1BZz7hA1q87ZdVSXZdArxM9G5Y9iZchQFrov4q

$ trezorctl get-public-node -n "m/49'/0'/0'/0/0" -t p2shsegwit -c Testnet
node.depth: 5
node.fingerprint: fa67b318
node.child_num: 0
node.chain_code: daeb4b660634a30373623ed7f7b7929f3d017a5f0f0571df6ea7064ff5270747
node.public_key: 02b463757d4ae356b18b8a52e52da37cb5ac24f6beef443e1be4b8e0c0b253145f
xpub: upub5JkzsLq7t5yRQF7HDmKYkvoHtpe98NRwXki8NfKNBrLj49sSmPt6t1x2x4tjfH81EoUrU6oL9UGxUgfrgqqPLctmPbZSvSGCdfN7qyMHU7g

$ trezorctl get-public-node -n "m/84'/0'/0'/0/0" -t segwit -c Testnet
node.depth: 5
node.fingerprint: deec7fdb
node.child_num: 0
node.chain_code: 3a9f77d25580c041782344080ca71a7c9ad2d9cb44e1ac09257698078477ddc8
node.public_key: 03ebc713dd017f62a8e20aeebaead00ca2e7d9ecb60eb8be10fc14c5ed55d27a88
xpub: vpub5dPYfuw6xbHfLiUh7kCoZUi1TxgCpKpkVqud5bf9JGHPUovtypqGULcWuUAwmSGx7bt5TmmWeCJnhqc3Xjchn35VJgZWcxBBws3Yy6zYa7G

$ trezorctl get-public-node -n "m/84'/0'/0'/0/0" -t segwit
node.depth: 5
node.fingerprint: deec7fdb
node.child_num: 0
node.chain_code: 3a9f77d25580c041782344080ca71a7c9ad2d9cb44e1ac09257698078477ddc8
node.public_key: 03ebc713dd017f62a8e20aeebaead00ca2e7d9ecb60eb8be10fc14c5ed55d27a88
xpub: zpub6vibtacmZKTajuFATBMJPq629qFzaonkAHzWDBEgpHnuhDBozTVWxbF4zJ1Hm4tdkAMJTg9kUqizEz4JQXGkxyotn3MCxbT92mJ8XVcNN5E

$ trezorctl get-public-node -n "m/44'/0'/0'/0/0" -t address
node.depth: 5
node.fingerprint: 003494b6
node.child_num: 0
node.chain_code: 9ae076ff814a8d178c018b3fd3068b88503c270108e766f6ace4ed49d618debe
node.public_key: 03df53b409712d73e951e269f73414c3986992189b3b78be3353678ff6951fc79c
xpub: xpub6FR8LqriB4qyPvdtZwhHW2HQP4daR2qXsYAAsfaiF8DoFJJ5AqGCpiGM3kFC4Z9AZWnReXrzp2nzhp91myPjz96e3wrJoMvgnCyMBjKz8vJ

$ trezorctl get-public-node -n "m/44'/0'/0'/0/0" -t address -c Testnet
node.depth: 5
node.fingerprint: 003494b6
node.child_num: 0
node.chain_code: 9ae076ff814a8d178c018b3fd3068b88503c270108e766f6ace4ed49d618debe
node.public_key: 03df53b409712d73e951e269f73414c3986992189b3b78be3353678ff6951fc79c
xpub: tpubDFnks5gPtLoRfipk28gNhwcmiBjEQRLbRAkUEDdrb2ygzaxnF47Hy9wBHnKyb46QMRKLG7NsM8d3PzddAqEysaYw7YbcUtavNAZkwjM7aqi


20 changes: 12 additions & 8 deletions core-test/src/test/scala/org/bitcoins/core/crypto/ExtKeyTest.scala
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package org.bitcoins.core.crypto

import org.bitcoins.core.crypto.ExtKeyVersion._
import org.bitcoins.core.crypto.bip32.BIP32Path
import org.bitcoins.core.hd.BIP32Path
import org.bitcoins.core.number.UInt32
import org.bitcoins.testkit.core.gen.{CryptoGenerators, NumberGenerator}
import org.bitcoins.testkit.core.gen.{
CryptoGenerators,
HDGenerators,
NumberGenerator
}
import org.bitcoins.testkit.util.BitcoinSUnitTest
import scodec.bits.HexStringSyntax

Expand Down Expand Up @@ -47,15 +51,15 @@ class ExtKeyTest extends BitcoinSUnitTest {
}

it must "derive private keys from a BIP32 path and an xpriv" in {
forAll(CryptoGenerators.extPrivateKey, CryptoGenerators.bip32Path) {
forAll(CryptoGenerators.extPrivateKey, HDGenerators.bip32Path) {
(priv, path) =>
priv.deriveChildPrivKey(path)
succeed
}
}

it must "derive public keys from a BIP32 path and an xpriv" in {
forAll(CryptoGenerators.extPrivateKey, CryptoGenerators.bip32Path) {
forAll(CryptoGenerators.extPrivateKey, HDGenerators.bip32Path) {
(priv, path) =>
val pub = priv.deriveChildPubKey(path)
pub match {
Expand All @@ -66,7 +70,7 @@ class ExtKeyTest extends BitcoinSUnitTest {
}

it must "fail to derive public keys from a hardened public key" in {
forAll(CryptoGenerators.extPrivateKey, CryptoGenerators.hardBip32Child) {
forAll(CryptoGenerators.extPrivateKey, HDGenerators.hardBip32Child) {
(priv, child) =>
val pub = priv.extPublicKey
val derivedPub = pub.deriveChildPubKey(child.toUInt32)
Expand All @@ -84,7 +88,7 @@ class ExtKeyTest extends BitcoinSUnitTest {

val path = BIP32Path.empty

val masterPriv = ExtPrivateKey(MainNetPriv, Some(seedBytes), path)
val masterPriv = ExtPrivateKey(LegacyMainNetPriv, Some(seedBytes), path)
masterPriv.toString must be(
"xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi")

Expand Down Expand Up @@ -145,7 +149,7 @@ class ExtKeyTest extends BitcoinSUnitTest {
hex"fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"

val masterPriv =
ExtPrivateKey(MainNetPriv, Some(seedBytes), BIP32Path.empty)
ExtPrivateKey(LegacyMainNetPriv, Some(seedBytes), BIP32Path.empty)
masterPriv.toString must be(
"xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U")

Expand Down Expand Up @@ -209,7 +213,7 @@ class ExtKeyTest extends BitcoinSUnitTest {
hex"4b381541583be4423346c643850da4b320e46a87ae3d2a4e6da11eba819cd4acba45d239319ac14f863b8d5ab5a0d0c64d2e8a1e7d1457df2e5a3c51c73235be"

val masterPrivKey =
ExtPrivateKey(MainNetPriv, Some(seedBytes), BIP32Path.empty)
ExtPrivateKey(LegacyMainNetPriv, Some(seedBytes), BIP32Path.empty)
masterPrivKey.toString must be(
"xprv9s21ZrQH143K25QhxbucbDDuQ4naNntJRi4KUfWT7xo4EKsHt2QJDu7KXp1A3u7Bi1j8ph3EGsZ9Xvz9dGuVrtHHs7pXeTzjuxBrCmmhgC6")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ class MnemonicCodeTest extends BitcoinSUnitTest {
val seed = BIP39Seed.fromMnemonic(code, "TREZOR")
seed must be(expectedSeed)

val xpriv = seed.toExtPrivateKey(ExtKeyVersion.MainNetPriv)
val xpriv = seed.toExtPrivateKey(ExtKeyVersion.LegacyMainNetPriv)
xpriv must be(expectedXPriv)
}
it must "pass all Trezor test vectors" in {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package org.bitcoins.core.crypto.bip32
package org.bitcoins.core.hd

import org.bitcoins.core.crypto.ExtKey
import org.bitcoins.core.crypto.ExtPublicKey
import org.bitcoins.testkit.core.gen.{CryptoGenerators, NumberGenerator}
import org.bitcoins.testkit.core.gen.{
CryptoGenerators,
HDGenerators,
NumberGenerator
}
import org.bitcoins.testkit.util.BitcoinSUnitTest
import org.scalacheck.{Gen, Shrink}
import org.scalatest.path
Expand Down Expand Up @@ -30,13 +35,13 @@ class BIP32PathTest extends BitcoinSUnitTest {
}

it must "have varargs and vector constructors what work the same way" in {
forAll(CryptoGenerators.bip32Path) { bip32 =>
forAll(HDGenerators.bip32Path) { bip32 =>
assert(BIP32Path(bip32.path) == BIP32Path(bip32.path: _*))
}
}

it must "derive public keys" in {
forAll(CryptoGenerators.extPrivateKey, CryptoGenerators.bip32Path) {
forAll(CryptoGenerators.extPrivateKey, HDGenerators.bip32Path) {
(priv, path) =>
val pub = priv.deriveChildPubKey(path)

Expand All @@ -46,7 +51,7 @@ class BIP32PathTest extends BitcoinSUnitTest {
}

it must "derive public and private keys symmetrically" in {
forAll(CryptoGenerators.extPrivateKey, CryptoGenerators.softBip32Path) {
forAll(CryptoGenerators.extPrivateKey, HDGenerators.softBip32Path) {
(priv, path) =>
val derivedPubFromPriv: Try[ExtPublicKey] = priv.deriveChildPubKey(path)
val pubFromDerivedPriv: ExtPublicKey =
Expand All @@ -66,7 +71,7 @@ class BIP32PathTest extends BitcoinSUnitTest {
}

it must "fail to parse a path beginning with the wrong character" in {
forAll(CryptoGenerators.bip32Path, Gen.alphaChar.suchThat(_ != 'm')) {
forAll(HDGenerators.bip32Path, Gen.alphaChar.suchThat(_ != 'm')) {
(path, char) =>
val badPathString = char + path.toString.drop(1)
assertThrows[IllegalArgumentException](
Expand Down Expand Up @@ -117,7 +122,7 @@ class BIP32PathTest extends BitcoinSUnitTest {

it must "have fromString and toString symmetry" in {
implicit val noShrink: Shrink[Nothing] = Shrink.shrinkAny
forAll(CryptoGenerators.bip32Path) { path =>
forAll(HDGenerators.bip32Path) { path =>
val toString = path.toString
assert(path == BIP32Path.fromString(toString))
}
Expand Down
Loading

0 comments on commit 884c261

Please sign in to comment.