github.com/piotrnar/gocoin@v0.0.0-20240512203912-faa0448c5e96/lib/btc/wallethd_test.go (about) 1 /* 2 This code is taken from: 3 * https://github.com/WeMeetAgain/go-hdwallet 4 */ 5 6 package btc 7 8 import ( 9 "bytes" 10 "encoding/hex" 11 "testing" 12 ) 13 14 // implements https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#test-vectors 15 16 var ( 17 masterhex1 string = "000102030405060708090a0b0c0d0e0f" 18 m_pub1 string = "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8" 19 m_prv1 string = "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi" 20 m_0p_pub1 string = "xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw" 21 m_0p_prv1 string = "xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7" 22 m_0p_1_pub1 string = "xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ" 23 m_0p_1_prv1 string = "xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs" 24 m_0p_1_2p_pub1 string = "xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5" 25 m_0p_1_2p_prv1 string = "xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM" 26 m_0p_1_2p_2_pub1 string = "xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV" 27 m_0p_1_2p_2_prv1 string = "xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334" 28 m_0p_1_2p_2_1000000000_pub1 string = "xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy" 29 m_0p_1_2p_2_1000000000_prv1 string = "xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76" 30 masterhex2 string = "fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542" 31 m_pub2 string = "xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB" 32 m_prv2 string = "xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U" 33 m_0_pub2 string = "xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH" 34 m_0_prv2 string = "xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt" 35 m_0_2147483647p_pub2 string = "xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a" 36 m_0_2147483647p_prv2 string = "xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9" 37 m_0_2147483647p_1_pub2 string = "xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon" 38 m_0_2147483647p_1_prv2 string = "xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef" 39 m_0_2147483647p_1_2147483646p_pub2 string = "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL" 40 m_0_2147483647p_1_2147483646p_prv2 string = "xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc" 41 m_0_2147483647p_1_2147483646p_2_pub2 string = "xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt" 42 m_0_2147483647p_1_2147483646p_2_prv2 string = "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j" 43 ) 44 45 func testChild(t *testing.T, key, ref_key string, i uint32) { 46 child_key := StringChild(key, i) 47 if child_key != ref_key { 48 t.Errorf("\n%s\nsupposed to be\n%s", child_key, ref_key) 49 } 50 } 51 52 func testMasterKey(t *testing.T, seed []byte, ref_key string) { 53 masterprv := MasterKey(seed, false).String() 54 if masterprv != ref_key { 55 t.Errorf("\n%s\nsupposed to be\n%s", masterprv, ref_key) 56 } 57 } 58 59 func testPub(t *testing.T, prv, ref_pub string) { 60 w, err := StringWallet(prv) 61 if err != nil { 62 t.Errorf("%s should have been nil", err.Error()) 63 } 64 pub := w.Pub().String() 65 if pub != ref_pub { 66 t.Errorf("\n%s\nsupposed to be\n%s", pub, ref_pub) 67 } 68 } 69 70 func TestVector1(t *testing.T) { 71 seed, _ := hex.DecodeString(masterhex1) 72 t.Logf("master key") 73 testMasterKey(t, seed, m_prv1) 74 t.Logf("master key -> pub") 75 testPub(t, m_prv1, m_pub1) 76 var i uint32 77 i = 0x80000000 78 t.Logf("first child") 79 testChild(t, m_prv1, m_0p_prv1, i) 80 t.Logf("first child -> pub") 81 testPub(t, m_0p_prv1, m_0p_pub1) 82 t.Logf("second child") 83 testChild(t, m_0p_prv1, m_0p_1_prv1, 1) 84 t.Logf("second child -> pub") 85 testPub(t, m_0p_1_prv1, m_0p_1_pub1) 86 t.Logf("third child") 87 i = 0x80000002 88 testChild(t, m_0p_1_prv1, m_0p_1_2p_prv1, i) 89 t.Logf("third child -> pub") 90 testPub(t, m_0p_1_2p_prv1, m_0p_1_2p_pub1) 91 t.Logf("fourth child") 92 testChild(t, m_0p_1_2p_prv1, m_0p_1_2p_2_prv1, 2) 93 t.Logf("fourth child -> pub") 94 testPub(t, m_0p_1_2p_2_prv1, m_0p_1_2p_2_pub1) 95 t.Logf("fifth child") 96 i = 1000000000 % 0x80000000 97 testChild(t, m_0p_1_2p_2_prv1, m_0p_1_2p_2_1000000000_prv1, i) 98 t.Logf("fifth child -> pub") 99 testPub(t, m_0p_1_2p_2_1000000000_prv1, m_0p_1_2p_2_1000000000_pub1) 100 } 101 102 func TestVector2(t *testing.T) { 103 seed, _ := hex.DecodeString(masterhex2) 104 t.Logf("master key") 105 testMasterKey(t, seed, m_prv2) 106 t.Logf("master key -> pub") 107 testPub(t, m_prv2, m_pub2) 108 var i uint32 109 t.Logf("first child") 110 testChild(t, m_prv2, m_0_prv2, 0) 111 t.Logf("first child -> pub") 112 testPub(t, m_0_prv2, m_0_pub2) 113 i = 2147483647 + 0x80000000 114 t.Logf("second child") 115 testChild(t, m_0_prv2, m_0_2147483647p_prv2, i) 116 t.Logf("second child -> pub") 117 testPub(t, m_0_2147483647p_prv2, m_0_2147483647p_pub2) 118 t.Logf("third child") 119 testChild(t, m_0_2147483647p_prv2, m_0_2147483647p_1_prv2, 1) 120 t.Logf("third child -> pub") 121 testPub(t, m_0_2147483647p_1_prv2, m_0_2147483647p_1_pub2) 122 i = 2147483646 + 0x80000000 123 t.Logf("fourth child") 124 testChild(t, m_0_2147483647p_1_prv2, m_0_2147483647p_1_2147483646p_prv2, i) 125 t.Logf("fourth child -> pub") 126 testPub(t, m_0_2147483647p_1_2147483646p_prv2, m_0_2147483647p_1_2147483646p_pub2) 127 t.Logf("fifth child") 128 testChild(t, m_0_2147483647p_1_2147483646p_prv2, m_0_2147483647p_1_2147483646p_2_prv2, 2) 129 t.Logf("fifth child -> pub") 130 testPub(t, m_0_2147483647p_1_2147483646p_2_prv2, m_0_2147483647p_1_2147483646p_2_pub2) 131 } 132 133 func TestChildPub(t *testing.T) { 134 testChild(t, m_pub2, m_0_pub2, 0) 135 } 136 137 func TestChildPrv(t *testing.T) { 138 testChild(t, m_prv2, m_0_prv2, 0) 139 } 140 141 func TestSerialize(t *testing.T) { 142 w, err := StringWallet(m_prv2) 143 if err != nil { 144 t.Errorf("%s should have been nil", err.Error()) 145 } 146 if m_prv2 != w.String() { 147 t.Errorf("private key not de/reserializing properly") 148 } 149 w, err = StringWallet(m_pub2) 150 if err != nil { 151 t.Errorf("%s should have been nil", err.Error()) 152 } 153 if m_pub2 != w.String() { 154 t.Errorf("public key not de/reserializing properly") 155 } 156 } 157 158 // Used this site to create test http://gobittest.appspot.com/Address 159 // Public key: 04CBCAA9C98C877A26977D00825C956A238E8DDDFBD322CCE4F74B0B5BD6ACE4A77BD3305D363C26F82C1E41C667E4B3561C06C60A2104D2B548E6DD059056AA51 160 // Expected address: 1AEg9dFEw29kMgaN4BNHALu7AzX5XUfzSU 161 func TestAddress(t *testing.T) { 162 addr, err := StringAddress(m_pub2) 163 if err != nil { 164 t.Errorf("%s should have been nil", err.Error()) 165 } 166 expected_addr := "1JEoxevbLLG8cVqeoGKQiAwoWbNYSUyYjg" 167 if addr != expected_addr { 168 t.Errorf("\n%s\nshould be\n%s", addr, expected_addr) 169 } 170 } 171 172 func TestStringCheck(t *testing.T) { 173 if err := StringCheck(m_pub2); err != nil { 174 t.Errorf("%s should have been nil", err.Error()) 175 } 176 if err := StringCheck(m_prv2); err != nil { 177 t.Errorf("%s should have been nil", err.Error()) 178 } 179 } 180 181 func TestChildren(t *testing.T) { 182 hdwal := MasterKey([]byte("Random seed"), false) 183 hdpub := hdwal.Pub() 184 185 for i := 0; i < 1000; i++ { 186 prv := hdwal.Child(uint32(i|0x80000000)) 187 if len(prv.Key)!=33 || prv.Key[0]!=0 { 188 t.Error("Bad private derivated key", i) 189 } 190 191 prv = hdwal.Child(uint32(i)) 192 pub := hdpub.Child(uint32(i)) 193 if len(prv.Key)!=33 || prv.Key[0]!=0 { 194 t.Error("Bad private key", i) 195 } 196 if len(pub.Key)!=33 || (pub.Key[0]!=2 && pub.Key[0]!=3) { 197 t.Error("Bad public key", i) 198 } 199 pu2 := PublicFromPrivate(prv.Key[1:], true) 200 if !bytes.Equal(pub.Key, pu2) { 201 t.Error("Private/public mismatch on Child", i) 202 } 203 204 var p [32]byte 205 copy(p[:], prv.Key[1:]) 206 pu2 = PublicFromPrivate(p[:], true) 207 if !bytes.Equal(pub.Key, pu2) { 208 t.Error("Private/public other mismatch on Child", i) 209 } 210 } 211 } 212 213 // benchmarks 214 215 func BenchmarkStringChildPub(b *testing.B) { 216 for i := 0; i < b.N; i++ { 217 StringChild(m_pub2, 0) 218 } 219 } 220 221 func BenchmarkStringChildPrv(b *testing.B) { 222 var a uint32 223 a = 0x80000000 224 for i := 0; i < b.N; i++ { 225 StringChild(m_prv1, a) 226 } 227 } 228 229 func BenchmarkStringPubString(b *testing.B) { 230 for i := 0; i < b.N; i++ { 231 w, _ := StringWallet(m_prv2) 232 w.Pub().String() 233 } 234 } 235 236 func BenchmarkStringAddress(b *testing.B) { 237 for i := 0; i < b.N; i++ { 238 StringAddress(m_pub2) 239 } 240 } 241 242 func BenchmarkStringCheck(b *testing.B) { 243 for i := 0; i < b.N; i++ { 244 StringCheck(m_pub2) 245 } 246 }