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.

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