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.

189 lines
4.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
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 ifExit(err error, n int) {
  74. if err != nil {
  75. fmt.Println(n, err)
  76. os.Exit(1)
  77. }
  78. }
  79. func gocrypto(seed []byte) ([]byte, []byte, []byte) {
  80. _, priv, ch, _ := ComputeMastersFromSeed(string(seed))
  81. privBytes := DerivePrivateKeyForPath(
  82. HexDecode(priv),
  83. HexDecode(ch),
  84. "44'/118'/0'/0/0",
  85. )
  86. pubBytes := PubKeyBytesFromPrivKeyBytes(privBytes, true)
  87. return HexDecode(priv), privBytes, pubBytes
  88. }
  89. func btcsuite(seed []byte) ([]byte, []byte, []byte) {
  90. fmt.Println("HD")
  91. masterKey, err := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams)
  92. if err != nil {
  93. hmac := hmac.New(sha512.New, []byte("Bitcoin seed"))
  94. hmac.Write([]byte(seed))
  95. intermediary := hmac.Sum(nil)
  96. curve := btcutil.Secp256k1()
  97. curveParams := curve.Params()
  98. // Split it into our key and chain code
  99. keyBytes := intermediary[:32]
  100. fmt.Printf("\t%X\n", keyBytes)
  101. fmt.Printf("\t%X\n", curveParams.N.Bytes())
  102. keyInt, _ := binary.ReadVarint(bytes.NewBuffer(keyBytes))
  103. fmt.Printf("\t%d\n", keyInt)
  104. }
  105. fh := hdkeychain.HardenedKeyStart
  106. k, err := masterKey.Child(uint32(fh + 44))
  107. ifExit(err, 44)
  108. k, err = k.Child(uint32(fh + 118))
  109. ifExit(err, 118)
  110. k, err = k.Child(uint32(fh + 0))
  111. ifExit(err, 1)
  112. k, err = k.Child(uint32(0))
  113. ifExit(err, 2)
  114. k, err = k.Child(uint32(0))
  115. ifExit(err, 3)
  116. ecpriv, err := k.ECPrivKey()
  117. ifExit(err, 10)
  118. ecpub, err := k.ECPubKey()
  119. ifExit(err, 11)
  120. priv := ecpriv.Serialize()
  121. pub := ecpub.SerializeCompressed()
  122. mkey, _ := masterKey.ECPrivKey()
  123. return mkey.Serialize(), priv, pub
  124. }
  125. // return priv and pub
  126. func tylerSmith(seed []byte) ([]byte, []byte, []byte) {
  127. masterKey, err := bip32.NewMasterKey(seed)
  128. if err != nil {
  129. hmac := hmac.New(sha512.New, []byte("Bitcoin seed"))
  130. hmac.Write([]byte(seed))
  131. intermediary := hmac.Sum(nil)
  132. curve := btcutil.Secp256k1()
  133. curveParams := curve.Params()
  134. // Split it into our key and chain code
  135. keyBytes := intermediary[:32]
  136. fmt.Printf("\t%X\n", keyBytes)
  137. fmt.Printf("\t%X\n", curveParams.N.Bytes())
  138. keyInt, _ := binary.ReadVarint(bytes.NewBuffer(keyBytes))
  139. fmt.Printf("\t%d\n", keyInt)
  140. }
  141. ifExit(err, 0)
  142. fh := bip32.FirstHardenedChild
  143. k, err := masterKey.NewChildKey(fh + 44)
  144. ifExit(err, 44)
  145. k, err = k.NewChildKey(fh + 118)
  146. ifExit(err, 118)
  147. k, err = k.NewChildKey(fh + 0)
  148. ifExit(err, 1)
  149. k, err = k.NewChildKey(0)
  150. ifExit(err, 2)
  151. k, err = k.NewChildKey(0)
  152. ifExit(err, 3)
  153. priv := k.Key
  154. pub := k.PublicKey().Key
  155. return masterKey.Key, priv, pub
  156. }