You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

238 lines
5.2 KiB

8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
  1. package hd
  2. import (
  3. "bytes"
  4. "encoding/hex"
  5. "encoding/json"
  6. "fmt"
  7. "io/ioutil"
  8. "os"
  9. "testing"
  10. "github.com/stretchr/testify/assert"
  11. "github.com/tyler-smith/go-bip39"
  12. "github.com/tendermint/go-crypto"
  13. )
  14. type addrData struct {
  15. Mnemonic string
  16. Master string
  17. Seed string
  18. Priv string
  19. Pub string
  20. Addr string
  21. }
  22. // NOTE: atom fundraiser address
  23. // var hdPath string = "m/44'/118'/0'/0/0"
  24. var hdToAddrTable []addrData
  25. func init() {
  26. b, err := ioutil.ReadFile("test.json")
  27. if err != nil {
  28. fmt.Println(err)
  29. os.Exit(1)
  30. }
  31. err = json.Unmarshal(b, &hdToAddrTable)
  32. if err != nil {
  33. fmt.Println(err)
  34. os.Exit(1)
  35. }
  36. }
  37. func TestHDToAddr(t *testing.T) {
  38. for i, d := range hdToAddrTable {
  39. privB, _ := hex.DecodeString(d.Priv)
  40. pubB, _ := hex.DecodeString(d.Pub)
  41. addrB, _ := hex.DecodeString(d.Addr)
  42. seedB, _ := hex.DecodeString(d.Seed)
  43. masterB, _ := hex.DecodeString(d.Master)
  44. seed := bip39.NewSeed(d.Mnemonic, "")
  45. fmt.Println("================================")
  46. fmt.Println("ROUND:", i, "MNEMONIC:", d.Mnemonic)
  47. // master, priv, pub := tylerSmith(seed)
  48. // master, priv, pub := btcsuite(seed)
  49. master, priv, pub := gocrypto(seed)
  50. fmt.Printf("\tNODEJS GOLANG\n")
  51. fmt.Printf("SEED \t%X %X\n", seedB, seed)
  52. fmt.Printf("MSTR \t%X %X\n", masterB, master)
  53. fmt.Printf("PRIV \t%X %X\n", privB, priv)
  54. fmt.Printf("PUB \t%X %X\n", pubB, pub)
  55. _, _ = priv, privB
  56. assert.Equal(t, master, masterB, fmt.Sprintf("Expected masters to match for %d", i))
  57. assert.Equal(t, priv, privB, "Expected priv keys to match")
  58. assert.Equal(t, pub, pubB, fmt.Sprintf("Expected pub keys to match for %d", i))
  59. var pubT crypto.PubKeySecp256k1
  60. copy(pubT[:], pub)
  61. addr := pubT.Address()
  62. fmt.Printf("ADDR \t%X %X\n", addrB, addr)
  63. assert.Equal(t, addr, crypto.Address(addrB), fmt.Sprintf("Expected addresses to match %d", i))
  64. }
  65. }
  66. func TestReverseBytes(t *testing.T) {
  67. tests := [...]struct {
  68. v []byte
  69. want []byte
  70. }{
  71. {[]byte(""), []byte("")},
  72. {nil, nil},
  73. {[]byte("Tendermint"), []byte("tnimredneT")},
  74. {[]byte("T"), []byte("T")},
  75. {[]byte("Te"), []byte("eT")},
  76. }
  77. for i, tt := range tests {
  78. got := ReverseBytes(tt.v)
  79. if !bytes.Equal(got, tt.want) {
  80. t.Errorf("#%d:\ngot= (%x)\nwant=(%x)", i, got, tt.want)
  81. }
  82. }
  83. }
  84. /*
  85. func ifExit(err error, n int) {
  86. if err != nil {
  87. fmt.Println(n, err)
  88. os.Exit(1)
  89. }
  90. }
  91. */
  92. func gocrypto(seed []byte) ([]byte, []byte, []byte) {
  93. _, priv, ch := ComputeMastersFromSeed(string(seed))
  94. privBytes := DerivePrivateKeyForPath(
  95. HexDecode(priv),
  96. HexDecode(ch),
  97. "44'/118'/0'/0/0",
  98. )
  99. pubBytes := PubKeyBytesFromPrivKeyBytes(privBytes, true)
  100. return HexDecode(priv), privBytes, pubBytes
  101. }
  102. /*
  103. func btcsuite(seed []byte) ([]byte, []byte, []byte) {
  104. fmt.Println("HD")
  105. masterKey, err := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams)
  106. if err != nil {
  107. hmac := hmac.New(sha512.New, []byte("Bitcoin seed"))
  108. hmac.Write([]byte(seed))
  109. intermediary := hmac.Sum(nil)
  110. curve := btcutil.Secp256k1()
  111. curveParams := curve.Params()
  112. // Split it into our key and chain code
  113. keyBytes := intermediary[:32]
  114. fmt.Printf("\t%X\n", keyBytes)
  115. fmt.Printf("\t%X\n", curveParams.N.Bytes())
  116. keyInt, _ := binary.ReadVarint(bytes.NewBuffer(keyBytes))
  117. fmt.Printf("\t%d\n", keyInt)
  118. }
  119. fh := hdkeychain.HardenedKeyStart
  120. k, err := masterKey.Child(uint32(fh + 44))
  121. ifExit(err, 44)
  122. k, err = k.Child(uint32(fh + 118))
  123. ifExit(err, 118)
  124. k, err = k.Child(uint32(fh + 0))
  125. ifExit(err, 1)
  126. k, err = k.Child(uint32(0))
  127. ifExit(err, 2)
  128. k, err = k.Child(uint32(0))
  129. ifExit(err, 3)
  130. ecpriv, err := k.ECPrivKey()
  131. ifExit(err, 10)
  132. ecpub, err := k.ECPubKey()
  133. ifExit(err, 11)
  134. priv := ecpriv.Serialize()
  135. pub := ecpub.SerializeCompressed()
  136. mkey, _ := masterKey.ECPrivKey()
  137. return mkey.Serialize(), priv, pub
  138. }
  139. // return priv and pub
  140. func tylerSmith(seed []byte) ([]byte, []byte, []byte) {
  141. masterKey, err := bip32.NewMasterKey(seed)
  142. if err != nil {
  143. hmac := hmac.New(sha512.New, []byte("Bitcoin seed"))
  144. hmac.Write([]byte(seed))
  145. intermediary := hmac.Sum(nil)
  146. curve := btcutil.Secp256k1()
  147. curveParams := curve.Params()
  148. // Split it into our key and chain code
  149. keyBytes := intermediary[:32]
  150. fmt.Printf("\t%X\n", keyBytes)
  151. fmt.Printf("\t%X\n", curveParams.N.Bytes())
  152. keyInt, _ := binary.ReadVarint(bytes.NewBuffer(keyBytes))
  153. fmt.Printf("\t%d\n", keyInt)
  154. }
  155. ifExit(err, 0)
  156. fh := bip32.FirstHardenedChild
  157. k, err := masterKey.NewChildKey(fh + 44)
  158. ifExit(err, 44)
  159. k, err = k.NewChildKey(fh + 118)
  160. ifExit(err, 118)
  161. k, err = k.NewChildKey(fh + 0)
  162. ifExit(err, 1)
  163. k, err = k.NewChildKey(0)
  164. ifExit(err, 2)
  165. k, err = k.NewChildKey(0)
  166. ifExit(err, 3)
  167. priv := k.Key
  168. pub := k.PublicKey().Key
  169. return masterKey.Key, priv, pub
  170. }
  171. */
  172. // Benchmarks
  173. var revBytesCases = [][]byte{
  174. nil,
  175. []byte(""),
  176. []byte("12"),
  177. // 16byte case
  178. []byte("abcdefghijklmnop"),
  179. // 32byte case
  180. []byte("abcdefghijklmnopqrstuvwxyz123456"),
  181. // 64byte case
  182. []byte("abcdefghijklmnopqrstuvwxyz123456abcdefghijklmnopqrstuvwxyz123456"),
  183. }
  184. func BenchmarkReverseBytes(b *testing.B) {
  185. var sink []byte
  186. for i := 0; i < b.N; i++ {
  187. for _, tt := range revBytesCases {
  188. sink = ReverseBytes(tt)
  189. }
  190. }
  191. b.ReportAllocs()
  192. // sink is necessary to ensure if the compiler tries
  193. // to smart, that it won't optimize away the benchmarks.
  194. if sink != nil {
  195. _ = sink
  196. }
  197. }