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  }