bip32

Pure Haskell BIP32 hierarchical deterministic wallets (docs.ppad.tech/bip32).
git clone git://git.ppad.tech/bip32.git
Log | Files | Refs | README | LICENSE

Main.hs (20402B)


      1 {-# OPTIONS_GHC -fno-warn-incomplete-uni-patterns -fno-warn-orphans #-}
      2 {-# LANGUAGE OverloadedStrings #-}
      3 
      4 module Main where
      5 
      6 import Crypto.HDKey.BIP32
      7 import qualified Data.ByteString as BS
      8 import qualified Data.ByteString.Base16 as B16
      9 import qualified Data.Word.Wider as W
     10 import Test.Tasty
     11 import qualified Test.Tasty.HUnit as H
     12 
     13 instance Eq XPrv where
     14   x1 == x2 = W.eq_vartime (xprv_key x1) (xprv_key x2)
     15           && xprv_cod x1 == xprv_cod x2
     16 
     17 instance Eq HDKey where
     18   HDKey k1 d1 p1 c1 == HDKey k2 d2 p2 c2 =
     19     eqKey k1 k2 && d1 == d2 && p1 == p2 && c1 == c2
     20     where
     21       eqKey (Left a) (Left b) = a == b
     22       eqKey (Right a) (Right b) = a == b
     23       eqKey _ _ = False
     24 
     25 -- for testing
     26 xprv_partial :: HDKey -> BS.ByteString
     27 xprv_partial val = case xprv val of
     28   Nothing -> error "bang"
     29   Just v -> v
     30 
     31 -- precomputed context for wNAF tests
     32 ctx :: Context
     33 ctx = precompute
     34 
     35 main :: IO ()
     36 main = defaultMain $ testGroup "BIP32 vectors" [
     37     testGroup "standard" [
     38         vector_1
     39       , vector_2
     40       , vector_3
     41       , vector_4
     42       , vector_5
     43       ]
     44   , testGroup "wNAF" [
     45         vector_1_wnaf
     46       , vector_2_wnaf
     47       , vector_3_wnaf
     48       , vector_4_wnaf
     49       ]
     50   ]
     51 
     52 seed_1 :: BS.ByteString
     53 seed_1 = case B16.decode "000102030405060708090a0b0c0d0e0f" of
     54   Nothing -> error "bang"
     55   Just b -> b
     56 
     57 xpub_1_m :: BS.ByteString
     58 xpub_1_m = "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8"
     59 
     60 xprv_1_m :: BS.ByteString
     61 xprv_1_m = "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi"
     62 
     63 xpub_1_m_0' :: BS.ByteString
     64 xpub_1_m_0' = "xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw"
     65 
     66 xprv_1_m_0' :: BS.ByteString
     67 xprv_1_m_0' = "xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7"
     68 
     69 xpub_1_m_0'_1 :: BS.ByteString
     70 xpub_1_m_0'_1 = "xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ"
     71 
     72 xprv_1_m_0'_1 :: BS.ByteString
     73 xprv_1_m_0'_1 = "xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs"
     74 
     75 xpub_1_m_0'_1_2' :: BS.ByteString
     76 xpub_1_m_0'_1_2' = "xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5"
     77 
     78 xprv_1_m_0'_1_2' :: BS.ByteString
     79 xprv_1_m_0'_1_2' = "xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM"
     80 
     81 xpub_1_m_0'_1_2'_2 :: BS.ByteString
     82 xpub_1_m_0'_1_2'_2 = "xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV"
     83 
     84 xprv_1_m_0'_1_2'_2 :: BS.ByteString
     85 xprv_1_m_0'_1_2'_2 = "xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334"
     86 
     87 xpub_1_m_0'_1_2'_2_1000000000 :: BS.ByteString
     88 xpub_1_m_0'_1_2'_2_1000000000 = "xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy"
     89 
     90 xprv_1_m_0'_1_2'_2_1000000000 :: BS.ByteString
     91 xprv_1_m_0'_1_2'_2_1000000000 = "xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76"
     92 
     93 vector_1 :: TestTree
     94 vector_1 = H.testCase "BIP32 vector 1" $ do
     95   let Just _m = master seed_1
     96   H.assertEqual "M" xpub_1_m (xpub _m)
     97   H.assertEqual "m" xprv_1_m (xprv_partial _m)
     98   let Just _m_0' = derive_child_priv _m 0x80000000
     99   H.assertEqual "M/0'" xpub_1_m_0' (xpub _m_0')
    100   H.assertEqual "m/0'" xprv_1_m_0' (xprv_partial _m_0')
    101   H.assertEqual "M/0', path" xpub_1_m_0' (xpub (derive_partial _m "m/0'"))
    102   H.assertEqual "m/0', path" xprv_1_m_0' (xprv_partial (derive_partial _m "m/0'"))
    103   let Just _m_0'_1 = derive_child_priv _m_0' 1
    104   H.assertEqual "M/0'/1" xpub_1_m_0'_1 (xpub _m_0'_1)
    105   H.assertEqual "m/0'/1" xprv_1_m_0'_1 (xprv_partial _m_0'_1)
    106   H.assertEqual "M/0'/1" xpub_1_m_0'_1 (xpub (derive_partial _m "m/0'/1"))
    107   H.assertEqual "m/0'/1" xprv_1_m_0'_1 (xprv_partial (derive_partial _m "m/0'/1"))
    108   let Just _m_0'_1_2' = derive_child_priv _m_0'_1 (0x80000000 + 2)
    109   H.assertEqual "M/0'/1/2'" xpub_1_m_0'_1_2' (xpub _m_0'_1_2')
    110   H.assertEqual "m/0'/1/2'" xprv_1_m_0'_1_2' (xprv_partial _m_0'_1_2')
    111   H.assertEqual "M/0'/1/2'" xpub_1_m_0'_1_2' (xpub (derive_partial _m "m/0'/1/2'"))
    112   H.assertEqual "m/0'/1/2'" xprv_1_m_0'_1_2' (xprv_partial (derive_partial _m "m/0'/1/2'"))
    113   let Just _m_0'_1_2'_2 = derive_child_priv _m_0'_1_2' 2
    114   H.assertEqual "M/0'/1/2'/2" xpub_1_m_0'_1_2'_2 (xpub _m_0'_1_2'_2)
    115   H.assertEqual "m/0'/1/2'/2" xprv_1_m_0'_1_2'_2 (xprv_partial _m_0'_1_2'_2)
    116   H.assertEqual "M/0'/1/2'/2" xpub_1_m_0'_1_2'_2
    117     (xpub (derive_partial _m "m/0'/1/2'/2"))
    118   H.assertEqual "m/0'/1/2'/2" xprv_1_m_0'_1_2'_2
    119     (xprv_partial (derive_partial _m "m/0'/1/2'/2"))
    120   let Just _m_0'_1_2'_2_1000000000 = derive_child_priv _m_0'_1_2'_2 1000000000
    121   H.assertEqual "M/0'/1/2'/2/1000000000" xpub_1_m_0'_1_2'_2_1000000000
    122     (xpub _m_0'_1_2'_2_1000000000)
    123   H.assertEqual "m/0'/1/2'/2/1000000000" xprv_1_m_0'_1_2'_2_1000000000
    124     (xprv_partial _m_0'_1_2'_2_1000000000)
    125   H.assertEqual "M/0'/1/2'/2/1000000000" xpub_1_m_0'_1_2'_2_1000000000
    126     (xpub (derive_partial _m "m/0'/1/2'/2/1000000000"))
    127   H.assertEqual "m/0'/1/2'/2/1000000000" xprv_1_m_0'_1_2'_2_1000000000
    128     (xprv_partial (derive_partial _m "m/0'/1/2'/2/1000000000"))
    129 
    130 seed_2 :: BS.ByteString
    131 seed_2 = case B16.decode "fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542" of
    132   Nothing -> error "bang"
    133   Just b -> b
    134 
    135 vector_2 :: TestTree
    136 vector_2 = H.testCase "BIP32 vector 2" $ do
    137   let Just mas = master seed_2
    138       _m = derive_partial mas "m"
    139   H.assertEqual "M" "xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB"
    140     (xpub _m)
    141   H.assertEqual "m" "xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U"
    142     (xprv_partial _m)
    143   let _m_0 = derive_partial mas "m/0"
    144   H.assertEqual "M/0" "xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH"
    145     (xpub _m_0)
    146   H.assertEqual "m/0" "xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt"
    147     (xprv_partial _m_0)
    148   let _m_0_2147483647' = derive_partial mas "m/0/2147483647'"
    149   H.assertEqual "M/0/2147483647'" "xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a"
    150     (xpub _m_0_2147483647')
    151   H.assertEqual "m/0/2147483647'" "xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9"
    152     (xprv_partial _m_0_2147483647')
    153   let _m_0_2147483647'_1 = derive_partial mas "m/0/2147483647'/1"
    154   H.assertEqual "M/0/2147483647'/1" "xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon"
    155     (xpub _m_0_2147483647'_1)
    156   H.assertEqual "m/0/2147483647'/1" "xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef"
    157     (xprv_partial _m_0_2147483647'_1)
    158   let _m_0_2147483647'_1_2147483646' =
    159         derive_partial mas "m/0/2147483647'/1/2147483646'"
    160   H.assertEqual "M/0/2147483647'/1/2147483646'" "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL"
    161     (xpub _m_0_2147483647'_1_2147483646')
    162   H.assertEqual "m/0/2147483647'/1/2147483646'" "xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc"
    163     (xprv_partial _m_0_2147483647'_1_2147483646')
    164   let _m_0_2147483647'_1_2147483646'_2 =
    165         derive_partial mas "m/0/2147483647'/1/2147483646'/2"
    166   H.assertEqual "M/0/2147483647'/1/2147483646'/2" "xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt"
    167     (xpub _m_0_2147483647'_1_2147483646'_2)
    168   H.assertEqual "m/0/2147483647'/1/2147483646'/2" "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j"
    169     (xprv_partial _m_0_2147483647'_1_2147483646'_2)
    170 
    171 seed_3 :: BS.ByteString
    172 seed_3 = case B16.decode "4b381541583be4423346c643850da4b320e46a87ae3d2a4e6da11eba819cd4acba45d239319ac14f863b8d5ab5a0d0c64d2e8a1e7d1457df2e5a3c51c73235be" of
    173   Nothing -> error "bang"
    174   Just b -> b
    175 
    176 vector_3 :: TestTree
    177 vector_3 = H.testCase "BIP32 vector 3" $ do
    178   let Just mas = master seed_3
    179       _m = derive_partial mas "m"
    180   H.assertEqual "M" "xpub661MyMwAqRbcEZVB4dScxMAdx6d4nFc9nvyvH3v4gJL378CSRZiYmhRoP7mBy6gSPSCYk6SzXPTf3ND1cZAceL7SfJ1Z3GC8vBgp2epUt13"
    181     (xpub _m)
    182   H.assertEqual "m" "xprv9s21ZrQH143K25QhxbucbDDuQ4naNntJRi4KUfWT7xo4EKsHt2QJDu7KXp1A3u7Bi1j8ph3EGsZ9Xvz9dGuVrtHHs7pXeTzjuxBrCmmhgC6"
    183     (xprv_partial _m)
    184   let _m_0' = derive_partial mas "m/0'"
    185   H.assertEqual "M/0'" "xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y"
    186     (xpub _m_0')
    187   H.assertEqual "m/0'" "xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L"
    188     (xprv_partial _m_0')
    189 
    190 seed_4 :: BS.ByteString
    191 seed_4 = case B16.decode "3ddd5602285899a946114506157c7997e5444528f3003f6134712147db19b678" of
    192   Nothing -> error "bang"
    193   Just b -> b
    194 
    195 vector_4 :: TestTree
    196 vector_4 = H.testCase "BIP32 vector 4" $ do
    197   let Just mas = master seed_4
    198       _m = derive_partial mas "m"
    199   H.assertEqual "M" "xpub661MyMwAqRbcGczjuMoRm6dXaLDEhW1u34gKenbeYqAix21mdUKJyuyu5F1rzYGVxyL6tmgBUAEPrEz92mBXjByMRiJdba9wpnN37RLLAXa"
    200     (xpub _m)
    201   H.assertEqual "m" "xprv9s21ZrQH143K48vGoLGRPxgo2JNkJ3J3fqkirQC2zVdk5Dgd5w14S7fRDyHH4dWNHUgkvsvNDCkvAwcSHNAQwhwgNMgZhLtQC63zxwhQmRv"
    202     (xprv_partial _m)
    203   let _m_0' = derive_partial mas "m/0'"
    204   H.assertEqual "M/0'" "xpub69AUMk3qDBi3uW1sXgjCmVjJ2G6WQoYSnNHyzkmdCHEhSZ4tBok37xfFEqHd2AddP56Tqp4o56AePAgCjYdvpW2PU2jbUPFKsav5ut6Ch1m"
    205     (xpub _m_0')
    206   H.assertEqual "m/0'" "xprv9vB7xEWwNp9kh1wQRfCCQMnZUEG21LpbR9NPCNN1dwhiZkjjeGRnaALmPXCX7SgjFTiCTT6bXes17boXtjq3xLpcDjzEuGLQBM5ohqkao9G"
    207     (xprv_partial _m_0')
    208   let _m_0'_1' = derive_partial mas "m/0'/1'"
    209   H.assertEqual "M/0'/1'" "xpub6BJA1jSqiukeaesWfxe6sNK9CCGaujFFSJLomWHprUL9DePQ4JDkM5d88n49sMGJxrhpjazuXYWdMf17C9T5XnxkopaeS7jGk1GyyVziaMt"
    210     (xpub _m_0'_1')
    211   H.assertEqual "m/0'/1'" "xprv9xJocDuwtYCMNAo3Zw76WENQeAS6WGXQ55RCy7tDJ8oALr4FWkuVoHJeHVAcAqiZLE7Je3vZJHxspZdFHfnBEjHqU5hG1Jaj32dVoS6XLT1"
    212     (xprv_partial _m_0'_1')
    213 
    214 vector_5 :: TestTree
    215 vector_5 = H.testCase "BIP32 vector 5" $ do
    216   H.assertEqual "k0" Nothing (parse "xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6LBpB85b3D2yc8sfvZU521AAwdZafEz7mnzBBsz4wKY5fTtTQBm")
    217   H.assertEqual "k1" Nothing (parse "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFGTQQD3dC4H2D5GBj7vWvSQaaBv5cxi9gafk7NF3pnBju6dwKvH")
    218   H.assertEqual "k2" Nothing (parse "xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6Txnt3siSujt9RCVYsx4qHZGc62TG4McvMGcAUjeuwZdduYEvFn")
    219   H.assertEqual "k3" Nothing (parse "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFGpWnsj83BHtEy5Zt8CcDr1UiRXuWCmTQLxEK9vbz5gPstX92JQ")
    220   H.assertEqual "k4" Nothing (parse "xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6N8ZMMXctdiCjxTNq964yKkwrkBJJwpzZS4HS2fxvyYUA4q2Xe4")
    221   H.assertEqual "k5" Nothing (parse "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFAzHGBP2UuGCqWLTAPLcMtD9y5gkZ6Eq3Rjuahrv17fEQ3Qen6J")
    222   H.assertEqual "k6" Nothing (parse "xprv9s2SPatNQ9Vc6GTbVMFPFo7jsaZySyzk7L8n2uqKXJen3KUmvQNTuLh3fhZMBoG3G4ZW1N2kZuHEPY53qmbZzCHshoQnNf4GvELZfqTUrcv")
    223   H.assertEqual "k7" Nothing (parse "xpub661no6RGEX3uJkY4bNnPcw4URcQTrSibUZ4NqJEw5eBkv7ovTwgiT91XX27VbEXGENhYRCf7hyEbWrR3FewATdCEebj6znwMfQkhRYHRLpJ")
    224   H.assertEqual "k8" Nothing (parse "xprv9s21ZrQH4r4TsiLvyLXqM9P7k1K3EYhA1kkD6xuquB5i39AU8KF42acDyL3qsDbU9NmZn6MsGSUYZEsuoePmjzsB3eFKSUEh3Gu1N3cqVUN")
    225   H.assertEqual "k9" Nothing (parse "xpub661MyMwAuDcm6CRQ5N4qiHKrJ39Xe1R1NyfouMKTTWcguwVcfrZJaNvhpebzGerh7gucBvzEQWRugZDuDXjNDRmXzSZe4c7mnTK97pTvGS8")
    226   H.assertEqual "k10" Nothing (parse "DMwo58pR1QLEFihHiXPVykYB6fJmsTeHvyTp7hRThAtCX8CvYzgPcn8XnmdfHGMQzT7ayAmfo4z3gY5KfbrZWZ6St24UVf2Qgo6oujFktLHdHY4")
    227   H.assertEqual "k11" Nothing (parse "DMwo58pR1QLEFihHiXPVykYB6fJmsTeHvyTp7hRThAtCX8CvYzgPcn8XnmdfHPmHJiEDXkTiJTVV9rHEBUem2mwVbbNfvT2MTcAqj3nesx8uBf9")
    228   H.assertEqual "k12" Nothing (parse "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzF93Y5wvzdUayhgkkFoicQZcP3y52uPPxFnfoLZB21Teqt1VvEHx")
    229   H.assertEqual "k13" Nothing (parse "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFAzHGBP2UuGCqWLTAPLcMtD5SDKr24z3aiUvKr9bJpdrcLg1y3G")
    230   H.assertEqual "k14" Nothing (parse "xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6Q5JXayek4PRsn35jii4veMimro1xefsM58PgBMrvdYre8QyULY")
    231   H.assertEqual "k15" Nothing (parse "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHL")
    232 
    233 -- wNAF variants --------------------------------------------------------------
    234 
    235 vector_1_wnaf :: TestTree
    236 vector_1_wnaf = H.testCase "BIP32 vector 1 (wNAF)" $ do
    237   let Just _m = master seed_1
    238   H.assertEqual "M" xpub_1_m (xpub _m)
    239   H.assertEqual "m" xprv_1_m (xprv_partial _m)
    240   let Just _m_0' = derive_child_priv' ctx _m 0x80000000
    241   H.assertEqual "M/0'" xpub_1_m_0' (xpub _m_0')
    242   H.assertEqual "m/0'" xprv_1_m_0' (xprv_partial _m_0')
    243   H.assertEqual "M/0', path" xpub_1_m_0'
    244     (xpub (derive_partial' ctx _m "m/0'"))
    245   H.assertEqual "m/0', path" xprv_1_m_0'
    246     (xprv_partial (derive_partial' ctx _m "m/0'"))
    247   let Just _m_0'_1 = derive_child_priv' ctx _m_0' 1
    248   H.assertEqual "M/0'/1" xpub_1_m_0'_1 (xpub _m_0'_1)
    249   H.assertEqual "m/0'/1" xprv_1_m_0'_1 (xprv_partial _m_0'_1)
    250   H.assertEqual "M/0'/1" xpub_1_m_0'_1
    251     (xpub (derive_partial' ctx _m "m/0'/1"))
    252   H.assertEqual "m/0'/1" xprv_1_m_0'_1
    253     (xprv_partial (derive_partial' ctx _m "m/0'/1"))
    254   let Just _m_0'_1_2' = derive_child_priv' ctx _m_0'_1 (0x80000000 + 2)
    255   H.assertEqual "M/0'/1/2'" xpub_1_m_0'_1_2' (xpub _m_0'_1_2')
    256   H.assertEqual "m/0'/1/2'" xprv_1_m_0'_1_2' (xprv_partial _m_0'_1_2')
    257   H.assertEqual "M/0'/1/2'" xpub_1_m_0'_1_2'
    258     (xpub (derive_partial' ctx _m "m/0'/1/2'"))
    259   H.assertEqual "m/0'/1/2'" xprv_1_m_0'_1_2'
    260     (xprv_partial (derive_partial' ctx _m "m/0'/1/2'"))
    261   let Just _m_0'_1_2'_2 = derive_child_priv' ctx _m_0'_1_2' 2
    262   H.assertEqual "M/0'/1/2'/2" xpub_1_m_0'_1_2'_2 (xpub _m_0'_1_2'_2)
    263   H.assertEqual "m/0'/1/2'/2" xprv_1_m_0'_1_2'_2 (xprv_partial _m_0'_1_2'_2)
    264   H.assertEqual "M/0'/1/2'/2" xpub_1_m_0'_1_2'_2
    265     (xpub (derive_partial' ctx _m "m/0'/1/2'/2"))
    266   H.assertEqual "m/0'/1/2'/2" xprv_1_m_0'_1_2'_2
    267     (xprv_partial (derive_partial' ctx _m "m/0'/1/2'/2"))
    268   let Just _m_0'_1_2'_2_1000000000 = derive_child_priv' ctx _m_0'_1_2'_2 1000000000
    269   H.assertEqual "M/0'/1/2'/2/1000000000" xpub_1_m_0'_1_2'_2_1000000000
    270     (xpub _m_0'_1_2'_2_1000000000)
    271   H.assertEqual "m/0'/1/2'/2/1000000000" xprv_1_m_0'_1_2'_2_1000000000
    272     (xprv_partial _m_0'_1_2'_2_1000000000)
    273   H.assertEqual "M/0'/1/2'/2/1000000000" xpub_1_m_0'_1_2'_2_1000000000
    274     (xpub (derive_partial' ctx _m "m/0'/1/2'/2/1000000000"))
    275   H.assertEqual "m/0'/1/2'/2/1000000000" xprv_1_m_0'_1_2'_2_1000000000
    276     (xprv_partial (derive_partial' ctx _m "m/0'/1/2'/2/1000000000"))
    277 
    278 vector_2_wnaf :: TestTree
    279 vector_2_wnaf = H.testCase "BIP32 vector 2 (wNAF)" $ do
    280   let Just mas = master seed_2
    281       _m = derive_partial' ctx mas "m"
    282   H.assertEqual "M"
    283     "xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB"
    284     (xpub _m)
    285   H.assertEqual "m"
    286     "xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U"
    287     (xprv_partial _m)
    288   let _m_0 = derive_partial' ctx mas "m/0"
    289   H.assertEqual "M/0"
    290     "xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH"
    291     (xpub _m_0)
    292   H.assertEqual "m/0"
    293     "xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt"
    294     (xprv_partial _m_0)
    295   let _m_0_2147483647' = derive_partial' ctx mas "m/0/2147483647'"
    296   H.assertEqual "M/0/2147483647'"
    297     "xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a"
    298     (xpub _m_0_2147483647')
    299   H.assertEqual "m/0/2147483647'"
    300     "xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9"
    301     (xprv_partial _m_0_2147483647')
    302   let _m_0_2147483647'_1 = derive_partial' ctx mas "m/0/2147483647'/1"
    303   H.assertEqual "M/0/2147483647'/1"
    304     "xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon"
    305     (xpub _m_0_2147483647'_1)
    306   H.assertEqual "m/0/2147483647'/1"
    307     "xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef"
    308     (xprv_partial _m_0_2147483647'_1)
    309   let _m_0_2147483647'_1_2147483646' =
    310         derive_partial' ctx mas "m/0/2147483647'/1/2147483646'"
    311   H.assertEqual "M/0/2147483647'/1/2147483646'"
    312     "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL"
    313     (xpub _m_0_2147483647'_1_2147483646')
    314   H.assertEqual "m/0/2147483647'/1/2147483646'"
    315     "xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc"
    316     (xprv_partial _m_0_2147483647'_1_2147483646')
    317   let _m_0_2147483647'_1_2147483646'_2 =
    318         derive_partial' ctx mas "m/0/2147483647'/1/2147483646'/2"
    319   H.assertEqual "M/0/2147483647'/1/2147483646'/2"
    320     "xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt"
    321     (xpub _m_0_2147483647'_1_2147483646'_2)
    322   H.assertEqual "m/0/2147483647'/1/2147483646'/2"
    323     "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j"
    324     (xprv_partial _m_0_2147483647'_1_2147483646'_2)
    325 
    326 vector_3_wnaf :: TestTree
    327 vector_3_wnaf = H.testCase "BIP32 vector 3 (wNAF)" $ do
    328   let Just mas = master seed_3
    329       _m = derive_partial' ctx mas "m"
    330   H.assertEqual "M"
    331     "xpub661MyMwAqRbcEZVB4dScxMAdx6d4nFc9nvyvH3v4gJL378CSRZiYmhRoP7mBy6gSPSCYk6SzXPTf3ND1cZAceL7SfJ1Z3GC8vBgp2epUt13"
    332     (xpub _m)
    333   H.assertEqual "m"
    334     "xprv9s21ZrQH143K25QhxbucbDDuQ4naNntJRi4KUfWT7xo4EKsHt2QJDu7KXp1A3u7Bi1j8ph3EGsZ9Xvz9dGuVrtHHs7pXeTzjuxBrCmmhgC6"
    335     (xprv_partial _m)
    336   let _m_0' = derive_partial' ctx mas "m/0'"
    337   H.assertEqual "M/0'"
    338     "xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y"
    339     (xpub _m_0')
    340   H.assertEqual "m/0'"
    341     "xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L"
    342     (xprv_partial _m_0')
    343 
    344 vector_4_wnaf :: TestTree
    345 vector_4_wnaf = H.testCase "BIP32 vector 4 (wNAF)" $ do
    346   let Just mas = master seed_4
    347       _m = derive_partial' ctx mas "m"
    348   H.assertEqual "M"
    349     "xpub661MyMwAqRbcGczjuMoRm6dXaLDEhW1u34gKenbeYqAix21mdUKJyuyu5F1rzYGVxyL6tmgBUAEPrEz92mBXjByMRiJdba9wpnN37RLLAXa"
    350     (xpub _m)
    351   H.assertEqual "m"
    352     "xprv9s21ZrQH143K48vGoLGRPxgo2JNkJ3J3fqkirQC2zVdk5Dgd5w14S7fRDyHH4dWNHUgkvsvNDCkvAwcSHNAQwhwgNMgZhLtQC63zxwhQmRv"
    353     (xprv_partial _m)
    354   let _m_0' = derive_partial' ctx mas "m/0'"
    355   H.assertEqual "M/0'"
    356     "xpub69AUMk3qDBi3uW1sXgjCmVjJ2G6WQoYSnNHyzkmdCHEhSZ4tBok37xfFEqHd2AddP56Tqp4o56AePAgCjYdvpW2PU2jbUPFKsav5ut6Ch1m"
    357     (xpub _m_0')
    358   H.assertEqual "m/0'"
    359     "xprv9vB7xEWwNp9kh1wQRfCCQMnZUEG21LpbR9NPCNN1dwhiZkjjeGRnaALmPXCX7SgjFTiCTT6bXes17boXtjq3xLpcDjzEuGLQBM5ohqkao9G"
    360     (xprv_partial _m_0')
    361   let _m_0'_1' = derive_partial' ctx mas "m/0'/1'"
    362   H.assertEqual "M/0'/1'"
    363     "xpub6BJA1jSqiukeaesWfxe6sNK9CCGaujFFSJLomWHprUL9DePQ4JDkM5d88n49sMGJxrhpjazuXYWdMf17C9T5XnxkopaeS7jGk1GyyVziaMt"
    364     (xpub _m_0'_1')
    365   H.assertEqual "m/0'/1'"
    366     "xprv9xJocDuwtYCMNAo3Zw76WENQeAS6WGXQ55RCy7tDJ8oALr4FWkuVoHJeHVAcAqiZLE7Je3vZJHxspZdFHfnBEjHqU5hG1Jaj32dVoS6XLT1"
    367     (xprv_partial _m_0'_1')