crypto_test.go 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. // Copyright 2014 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. package crypto
  17. import (
  18. "bytes"
  19. "crypto/ecdsa"
  20. "encoding/hex"
  21. "io/ioutil"
  22. "math/big"
  23. "os"
  24. "reflect"
  25. "testing"
  26. "github.com/ethereum/go-ethereum/common"
  27. "github.com/ethereum/go-ethereum/common/hexutil"
  28. )
  29. var testAddrHex = "970e8128ab834e8eac17ab8e3812f010678cf791"
  30. var testPrivHex = "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032"
  31. // These tests are sanity checks.
  32. // They should ensure that we don't e.g. use Sha3-224 instead of Sha3-256
  33. // and that the sha3 library uses keccak-f permutation.
  34. func TestKeccak256Hash(t *testing.T) {
  35. msg := []byte("abc")
  36. exp, _ := hex.DecodeString("4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45")
  37. checkhash(t, "Sha3-256-array", func(in []byte) []byte { h := Keccak256Hash(in); return h[:] }, msg, exp)
  38. }
  39. func TestKeccak256Hasher(t *testing.T) {
  40. msg := []byte("abc")
  41. exp, _ := hex.DecodeString("4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45")
  42. hasher := NewKeccakState()
  43. checkhash(t, "Sha3-256-array", func(in []byte) []byte { h := HashData(hasher, in); return h[:] }, msg, exp)
  44. }
  45. func TestToECDSAErrors(t *testing.T) {
  46. if _, err := HexToECDSA("0000000000000000000000000000000000000000000000000000000000000000"); err == nil {
  47. t.Fatal("HexToECDSA should've returned error")
  48. }
  49. if _, err := HexToECDSA("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); err == nil {
  50. t.Fatal("HexToECDSA should've returned error")
  51. }
  52. }
  53. func BenchmarkSha3(b *testing.B) {
  54. a := []byte("hello world")
  55. for i := 0; i < b.N; i++ {
  56. Keccak256(a)
  57. }
  58. }
  59. func TestUnmarshalPubkey(t *testing.T) {
  60. key, err := UnmarshalPubkey(nil)
  61. if err != errInvalidPubkey || key != nil {
  62. t.Fatalf("expected error, got %v, %v", err, key)
  63. }
  64. key, err = UnmarshalPubkey([]byte{1, 2, 3})
  65. if err != errInvalidPubkey || key != nil {
  66. t.Fatalf("expected error, got %v, %v", err, key)
  67. }
  68. var (
  69. enc, _ = hex.DecodeString("04760c4460e5336ac9bbd87952a3c7ec4363fc0a97bd31c86430806e287b437fd1b01abc6e1db640cf3106b520344af1d58b00b57823db3e1407cbc433e1b6d04d")
  70. dec = &ecdsa.PublicKey{
  71. Curve: S256(),
  72. X: hexutil.MustDecodeBig("0x760c4460e5336ac9bbd87952a3c7ec4363fc0a97bd31c86430806e287b437fd1"),
  73. Y: hexutil.MustDecodeBig("0xb01abc6e1db640cf3106b520344af1d58b00b57823db3e1407cbc433e1b6d04d"),
  74. }
  75. )
  76. key, err = UnmarshalPubkey(enc)
  77. if err != nil {
  78. t.Fatalf("expected no error, got %v", err)
  79. }
  80. if !reflect.DeepEqual(key, dec) {
  81. t.Fatal("wrong result")
  82. }
  83. }
  84. func TestSign(t *testing.T) {
  85. key, _ := HexToECDSA(testPrivHex)
  86. addr := common.HexToAddress(testAddrHex)
  87. msg := Keccak256([]byte("foo"))
  88. sig, err := Sign(msg, key)
  89. if err != nil {
  90. t.Errorf("Sign error: %s", err)
  91. }
  92. recoveredPub, err := Ecrecover(msg, sig)
  93. if err != nil {
  94. t.Errorf("ECRecover error: %s", err)
  95. }
  96. pubKey, _ := UnmarshalPubkey(recoveredPub)
  97. recoveredAddr := PubkeyToAddress(*pubKey)
  98. if addr != recoveredAddr {
  99. t.Errorf("Address mismatch: want: %x have: %x", addr, recoveredAddr)
  100. }
  101. // should be equal to SigToPub
  102. recoveredPub2, err := SigToPub(msg, sig)
  103. if err != nil {
  104. t.Errorf("ECRecover error: %s", err)
  105. }
  106. recoveredAddr2 := PubkeyToAddress(*recoveredPub2)
  107. if addr != recoveredAddr2 {
  108. t.Errorf("Address mismatch: want: %x have: %x", addr, recoveredAddr2)
  109. }
  110. }
  111. func TestInvalidSign(t *testing.T) {
  112. if _, err := Sign(make([]byte, 1), nil); err == nil {
  113. t.Errorf("expected sign with hash 1 byte to error")
  114. }
  115. if _, err := Sign(make([]byte, 33), nil); err == nil {
  116. t.Errorf("expected sign with hash 33 byte to error")
  117. }
  118. }
  119. func TestNewContractAddress(t *testing.T) {
  120. key, _ := HexToECDSA(testPrivHex)
  121. addr := common.HexToAddress(testAddrHex)
  122. genAddr := PubkeyToAddress(key.PublicKey)
  123. // sanity check before using addr to create contract address
  124. checkAddr(t, genAddr, addr)
  125. caddr0 := CreateAddress(addr, 0)
  126. caddr1 := CreateAddress(addr, 1)
  127. caddr2 := CreateAddress(addr, 2)
  128. checkAddr(t, common.HexToAddress("333c3310824b7c685133f2bedb2ca4b8b4df633d"), caddr0)
  129. checkAddr(t, common.HexToAddress("8bda78331c916a08481428e4b07c96d3e916d165"), caddr1)
  130. checkAddr(t, common.HexToAddress("c9ddedf451bc62ce88bf9292afb13df35b670699"), caddr2)
  131. }
  132. func TestLoadECDSA(t *testing.T) {
  133. tests := []struct {
  134. input string
  135. err string
  136. }{
  137. // good
  138. {input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"},
  139. {input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n"},
  140. {input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n\r"},
  141. {input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\r\n"},
  142. {input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n\n"},
  143. {input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n\r"},
  144. // bad
  145. {
  146. input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde",
  147. err: "key file too short, want 64 hex characters",
  148. },
  149. {
  150. input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde\n",
  151. err: "key file too short, want 64 hex characters",
  152. },
  153. {
  154. input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdeX",
  155. err: "invalid hex character 'X' in private key",
  156. },
  157. {
  158. input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdefX",
  159. err: "invalid character 'X' at end of key file",
  160. },
  161. {
  162. input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n\n\n",
  163. err: "key file too long, want 64 hex characters",
  164. },
  165. }
  166. for _, test := range tests {
  167. f, err := ioutil.TempFile("", "loadecdsa_test.*.txt")
  168. if err != nil {
  169. t.Fatal(err)
  170. }
  171. filename := f.Name()
  172. f.WriteString(test.input)
  173. f.Close()
  174. _, err = LoadECDSA(filename)
  175. switch {
  176. case err != nil && test.err == "":
  177. t.Fatalf("unexpected error for input %q:\n %v", test.input, err)
  178. case err != nil && err.Error() != test.err:
  179. t.Fatalf("wrong error for input %q:\n %v", test.input, err)
  180. case err == nil && test.err != "":
  181. t.Fatalf("LoadECDSA did not return error for input %q", test.input)
  182. }
  183. }
  184. }
  185. func TestSaveECDSA(t *testing.T) {
  186. f, err := ioutil.TempFile("", "saveecdsa_test.*.txt")
  187. if err != nil {
  188. t.Fatal(err)
  189. }
  190. file := f.Name()
  191. f.Close()
  192. defer os.Remove(file)
  193. key, _ := HexToECDSA(testPrivHex)
  194. if err := SaveECDSA(file, key); err != nil {
  195. t.Fatal(err)
  196. }
  197. loaded, err := LoadECDSA(file)
  198. if err != nil {
  199. t.Fatal(err)
  200. }
  201. if !reflect.DeepEqual(key, loaded) {
  202. t.Fatal("loaded key not equal to saved key")
  203. }
  204. }
  205. func TestValidateSignatureValues(t *testing.T) {
  206. check := func(expected bool, v byte, r, s *big.Int) {
  207. if ValidateSignatureValues(v, r, s, false) != expected {
  208. t.Errorf("mismatch for v: %d r: %d s: %d want: %v", v, r, s, expected)
  209. }
  210. }
  211. minusOne := big.NewInt(-1)
  212. one := common.Big1
  213. zero := common.Big0
  214. secp256k1nMinus1 := new(big.Int).Sub(secp256k1N, common.Big1)
  215. // correct v,r,s
  216. check(true, 0, one, one)
  217. check(true, 1, one, one)
  218. // incorrect v, correct r,s,
  219. check(false, 2, one, one)
  220. check(false, 3, one, one)
  221. // incorrect v, combinations of incorrect/correct r,s at lower limit
  222. check(false, 2, zero, zero)
  223. check(false, 2, zero, one)
  224. check(false, 2, one, zero)
  225. check(false, 2, one, one)
  226. // correct v for any combination of incorrect r,s
  227. check(false, 0, zero, zero)
  228. check(false, 0, zero, one)
  229. check(false, 0, one, zero)
  230. check(false, 1, zero, zero)
  231. check(false, 1, zero, one)
  232. check(false, 1, one, zero)
  233. // correct sig with max r,s
  234. check(true, 0, secp256k1nMinus1, secp256k1nMinus1)
  235. // correct v, combinations of incorrect r,s at upper limit
  236. check(false, 0, secp256k1N, secp256k1nMinus1)
  237. check(false, 0, secp256k1nMinus1, secp256k1N)
  238. check(false, 0, secp256k1N, secp256k1N)
  239. // current callers ensures r,s cannot be negative, but let's test for that too
  240. // as crypto package could be used stand-alone
  241. check(false, 0, minusOne, one)
  242. check(false, 0, one, minusOne)
  243. }
  244. func checkhash(t *testing.T, name string, f func([]byte) []byte, msg, exp []byte) {
  245. sum := f(msg)
  246. if !bytes.Equal(exp, sum) {
  247. t.Fatalf("hash %s mismatch: want: %x have: %x", name, exp, sum)
  248. }
  249. }
  250. func checkAddr(t *testing.T, addr0, addr1 common.Address) {
  251. if addr0 != addr1 {
  252. t.Fatalf("address mismatch: want: %x have: %x", addr0, addr1)
  253. }
  254. }
  255. // test to help Python team with integration of libsecp256k1
  256. // skip but keep it after they are done
  257. func TestPythonIntegration(t *testing.T) {
  258. kh := "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032"
  259. k0, _ := HexToECDSA(kh)
  260. msg0 := Keccak256([]byte("foo"))
  261. sig0, _ := Sign(msg0, k0)
  262. msg1 := common.FromHex("00000000000000000000000000000000")
  263. sig1, _ := Sign(msg0, k0)
  264. t.Logf("msg: %x, privkey: %s sig: %x\n", msg0, kh, sig0)
  265. t.Logf("msg: %x, privkey: %s sig: %x\n", msg1, kh, sig1)
  266. }