crypto.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. package crypto
  2. import (
  3. "crypto/aes"
  4. "crypto/cipher"
  5. "crypto/ecdsa"
  6. "crypto/elliptic"
  7. "crypto/rand"
  8. "crypto/sha256"
  9. "fmt"
  10. "io"
  11. "io/ioutil"
  12. "os"
  13. "encoding/hex"
  14. "encoding/json"
  15. "errors"
  16. "code.google.com/p/go-uuid/uuid"
  17. "github.com/ethereum/go-ethereum/common"
  18. "github.com/ethereum/go-ethereum/crypto/ecies"
  19. "github.com/ethereum/go-ethereum/crypto/secp256k1"
  20. "github.com/ethereum/go-ethereum/crypto/sha3"
  21. "github.com/ethereum/go-ethereum/rlp"
  22. "golang.org/x/crypto/pbkdf2"
  23. "golang.org/x/crypto/ripemd160"
  24. )
  25. func init() {
  26. // specify the params for the s256 curve
  27. ecies.AddParamsForCurve(S256(), ecies.ECIES_AES128_SHA256)
  28. }
  29. func Sha3(data ...[]byte) []byte {
  30. d := sha3.NewKeccak256()
  31. for _, b := range data {
  32. d.Write(b)
  33. }
  34. return d.Sum(nil)
  35. }
  36. func Sha3Hash(data ...[]byte) (h common.Hash) {
  37. d := sha3.NewKeccak256()
  38. for _, b := range data {
  39. d.Write(b)
  40. }
  41. d.Sum(h[:0])
  42. return h
  43. }
  44. // Creates an ethereum address given the bytes and the nonce
  45. func CreateAddress(b common.Address, nonce uint64) common.Address {
  46. data, _ := rlp.EncodeToBytes([]interface{}{b, nonce})
  47. return common.BytesToAddress(Sha3(data)[12:])
  48. //return Sha3(common.NewValue([]interface{}{b, nonce}).Encode())[12:]
  49. }
  50. func Sha256(data []byte) []byte {
  51. hash := sha256.Sum256(data)
  52. return hash[:]
  53. }
  54. func Ripemd160(data []byte) []byte {
  55. ripemd := ripemd160.New()
  56. ripemd.Write(data)
  57. return ripemd.Sum(nil)
  58. }
  59. func Ecrecover(hash, sig []byte) ([]byte, error) {
  60. return secp256k1.RecoverPubkey(hash, sig)
  61. }
  62. // New methods using proper ecdsa keys from the stdlib
  63. func ToECDSA(prv []byte) *ecdsa.PrivateKey {
  64. if len(prv) == 0 {
  65. return nil
  66. }
  67. priv := new(ecdsa.PrivateKey)
  68. priv.PublicKey.Curve = S256()
  69. priv.D = common.BigD(prv)
  70. priv.PublicKey.X, priv.PublicKey.Y = S256().ScalarBaseMult(prv)
  71. return priv
  72. }
  73. func FromECDSA(prv *ecdsa.PrivateKey) []byte {
  74. if prv == nil {
  75. return nil
  76. }
  77. return prv.D.Bytes()
  78. }
  79. func ToECDSAPub(pub []byte) *ecdsa.PublicKey {
  80. if len(pub) == 0 {
  81. return nil
  82. }
  83. x, y := elliptic.Unmarshal(S256(), pub)
  84. return &ecdsa.PublicKey{S256(), x, y}
  85. }
  86. func FromECDSAPub(pub *ecdsa.PublicKey) []byte {
  87. if pub == nil || pub.X == nil || pub.Y == nil {
  88. return nil
  89. }
  90. return elliptic.Marshal(S256(), pub.X, pub.Y)
  91. }
  92. // HexToECDSA parses a secp256k1 private key.
  93. func HexToECDSA(hexkey string) (*ecdsa.PrivateKey, error) {
  94. b, err := hex.DecodeString(hexkey)
  95. if err != nil {
  96. return nil, errors.New("invalid hex string")
  97. }
  98. if len(b) != 32 {
  99. return nil, errors.New("invalid length, need 256 bits")
  100. }
  101. return ToECDSA(b), nil
  102. }
  103. // LoadECDSA loads a secp256k1 private key from the given file.
  104. // The key data is expected to be hex-encoded.
  105. func LoadECDSA(file string) (*ecdsa.PrivateKey, error) {
  106. buf := make([]byte, 64)
  107. fd, err := os.Open(file)
  108. if err != nil {
  109. return nil, err
  110. }
  111. defer fd.Close()
  112. if _, err := io.ReadFull(fd, buf); err != nil {
  113. return nil, err
  114. }
  115. key, err := hex.DecodeString(string(buf))
  116. if err != nil {
  117. return nil, err
  118. }
  119. return ToECDSA(key), nil
  120. }
  121. // SaveECDSA saves a secp256k1 private key to the given file with
  122. // restrictive permissions. The key data is saved hex-encoded.
  123. func SaveECDSA(file string, key *ecdsa.PrivateKey) error {
  124. k := hex.EncodeToString(FromECDSA(key))
  125. return ioutil.WriteFile(file, []byte(k), 0600)
  126. }
  127. func GenerateKey() (*ecdsa.PrivateKey, error) {
  128. return ecdsa.GenerateKey(S256(), rand.Reader)
  129. }
  130. func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) {
  131. s, err := Ecrecover(hash, sig)
  132. if err != nil {
  133. return nil, err
  134. }
  135. x, y := elliptic.Unmarshal(S256(), s)
  136. return &ecdsa.PublicKey{S256(), x, y}, nil
  137. }
  138. func Sign(hash []byte, prv *ecdsa.PrivateKey) (sig []byte, err error) {
  139. if len(hash) != 32 {
  140. return nil, fmt.Errorf("hash is required to be exactly 32 bytes (%d)", len(hash))
  141. }
  142. sig, err = secp256k1.Sign(hash, common.LeftPadBytes(prv.D.Bytes(), prv.Params().BitSize/8))
  143. return
  144. }
  145. func Encrypt(pub *ecdsa.PublicKey, message []byte) ([]byte, error) {
  146. return ecies.Encrypt(rand.Reader, ecies.ImportECDSAPublic(pub), message, nil, nil)
  147. }
  148. func Decrypt(prv *ecdsa.PrivateKey, ct []byte) ([]byte, error) {
  149. key := ecies.ImportECDSA(prv)
  150. return key.Decrypt(rand.Reader, ct, nil, nil)
  151. }
  152. // Used only by block tests.
  153. func ImportBlockTestKey(privKeyBytes []byte) error {
  154. ks := NewKeyStorePassphrase(common.DefaultDataDir() + "/keys")
  155. ecKey := ToECDSA(privKeyBytes)
  156. key := &Key{
  157. Id: uuid.NewRandom(),
  158. Address: PubkeyToAddress(ecKey.PublicKey),
  159. PrivateKey: ecKey,
  160. }
  161. err := ks.StoreKey(key, "")
  162. return err
  163. }
  164. // creates a Key and stores that in the given KeyStore by decrypting a presale key JSON
  165. func ImportPreSaleKey(keyStore KeyStore2, keyJSON []byte, password string) (*Key, error) {
  166. key, err := decryptPreSaleKey(keyJSON, password)
  167. if err != nil {
  168. return nil, err
  169. }
  170. key.Id = uuid.NewRandom()
  171. err = keyStore.StoreKey(key, password)
  172. return key, err
  173. }
  174. func decryptPreSaleKey(fileContent []byte, password string) (key *Key, err error) {
  175. preSaleKeyStruct := struct {
  176. EncSeed string
  177. EthAddr string
  178. Email string
  179. BtcAddr string
  180. }{}
  181. err = json.Unmarshal(fileContent, &preSaleKeyStruct)
  182. if err != nil {
  183. return nil, err
  184. }
  185. encSeedBytes, err := hex.DecodeString(preSaleKeyStruct.EncSeed)
  186. iv := encSeedBytes[:16]
  187. cipherText := encSeedBytes[16:]
  188. /*
  189. See https://github.com/ethereum/pyethsaletool
  190. pyethsaletool generates the encryption key from password by
  191. 2000 rounds of PBKDF2 with HMAC-SHA-256 using password as salt (:().
  192. 16 byte key length within PBKDF2 and resulting key is used as AES key
  193. */
  194. passBytes := []byte(password)
  195. derivedKey := pbkdf2.Key(passBytes, passBytes, 2000, 16, sha256.New)
  196. plainText, err := aesCBCDecrypt(derivedKey, cipherText, iv)
  197. ethPriv := Sha3(plainText)
  198. ecKey := ToECDSA(ethPriv)
  199. key = &Key{
  200. Id: nil,
  201. Address: PubkeyToAddress(ecKey.PublicKey),
  202. PrivateKey: ecKey,
  203. }
  204. derivedAddr := common.Bytes2Hex(key.Address)
  205. expectedAddr := preSaleKeyStruct.EthAddr
  206. if derivedAddr != expectedAddr {
  207. err = errors.New("decrypted addr not equal to expected addr")
  208. }
  209. return key, err
  210. }
  211. func aesCBCDecrypt(key []byte, cipherText []byte, iv []byte) (plainText []byte, err error) {
  212. aesBlock, err := aes.NewCipher(key)
  213. if err != nil {
  214. return plainText, err
  215. }
  216. decrypter := cipher.NewCBCDecrypter(aesBlock, iv)
  217. paddedPlainText := make([]byte, len(cipherText))
  218. decrypter.CryptBlocks(paddedPlainText, cipherText)
  219. plainText = PKCS7Unpad(paddedPlainText)
  220. if plainText == nil {
  221. err = errors.New("Decryption failed: PKCS7Unpad failed after decryption")
  222. }
  223. return plainText, err
  224. }
  225. // From https://leanpub.com/gocrypto/read#leanpub-auto-block-cipher-modes
  226. func PKCS7Pad(in []byte) []byte {
  227. padding := 16 - (len(in) % 16)
  228. if padding == 0 {
  229. padding = 16
  230. }
  231. for i := 0; i < padding; i++ {
  232. in = append(in, byte(padding))
  233. }
  234. return in
  235. }
  236. func PKCS7Unpad(in []byte) []byte {
  237. if len(in) == 0 {
  238. return nil
  239. }
  240. padding := in[len(in)-1]
  241. if int(padding) > len(in) || padding > aes.BlockSize {
  242. return nil
  243. } else if padding == 0 {
  244. return nil
  245. }
  246. for i := len(in) - 1; i > len(in)-int(padding)-1; i-- {
  247. if in[i] != padding {
  248. return nil
  249. }
  250. }
  251. return in[:len(in)-int(padding)]
  252. }
  253. func PubkeyToAddress(p ecdsa.PublicKey) []byte {
  254. pubBytes := FromECDSAPub(&p)
  255. return Sha3(pubBytes[1:])[12:]
  256. }