github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/crypto/crypto_test.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:36</date> 10 //</624450084922200064> 11 12 13 package crypto 14 15 import ( 16 "bytes" 17 "crypto/ecdsa" 18 "encoding/hex" 19 "io/ioutil" 20 "math/big" 21 "os" 22 "reflect" 23 "testing" 24 25 "github.com/ethereum/go-ethereum/common" 26 "github.com/ethereum/go-ethereum/common/hexutil" 27 ) 28 29 var testAddrHex = "970e8128ab834e8eac17ab8e3812f010678cf791" 30 var testPrivHex = "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032" 31 32 //这些测试是健康检查。 33 //他们应该确保我们不使用sha3-224而不是sha3-256 34 //Sha3图书馆使用了keccak-f排列。 35 func TestKeccak256Hash(t *testing.T) { 36 msg := []byte("abc") 37 exp, _ := hex.DecodeString("4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45") 38 checkhash(t, "Sha3-256-array", func(in []byte) []byte { h := Keccak256Hash(in); return h[:] }, msg, exp) 39 } 40 41 func TestToECDSAErrors(t *testing.T) { 42 if _, err := HexToECDSA("0000000000000000000000000000000000000000000000000000000000000000"); err == nil { 43 t.Fatal("HexToECDSA should've returned error") 44 } 45 if _, err := HexToECDSA("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); err == nil { 46 t.Fatal("HexToECDSA should've returned error") 47 } 48 } 49 50 func BenchmarkSha3(b *testing.B) { 51 a := []byte("hello world") 52 for i := 0; i < b.N; i++ { 53 Keccak256(a) 54 } 55 } 56 57 func TestUnmarshalPubkey(t *testing.T) { 58 key, err := UnmarshalPubkey(nil) 59 if err != errInvalidPubkey || key != nil { 60 t.Fatalf("expected error, got %v, %v", err, key) 61 } 62 key, err = UnmarshalPubkey([]byte{1, 2, 3}) 63 if err != errInvalidPubkey || key != nil { 64 t.Fatalf("expected error, got %v, %v", err, key) 65 } 66 67 var ( 68 enc, _ = hex.DecodeString("04760c4460e5336ac9bbd87952a3c7ec4363fc0a97bd31c86430806e287b437fd1b01abc6e1db640cf3106b520344af1d58b00b57823db3e1407cbc433e1b6d04d") 69 dec = &ecdsa.PublicKey{ 70 Curve: S256(), 71 X: hexutil.MustDecodeBig("0x760c4460e5336ac9bbd87952a3c7ec4363fc0a97bd31c86430806e287b437fd1"), 72 Y: hexutil.MustDecodeBig("0xb01abc6e1db640cf3106b520344af1d58b00b57823db3e1407cbc433e1b6d04d"), 73 } 74 ) 75 key, err = UnmarshalPubkey(enc) 76 if err != nil { 77 t.Fatalf("expected no error, got %v", err) 78 } 79 if !reflect.DeepEqual(key, dec) { 80 t.Fatal("wrong result") 81 } 82 } 83 84 func TestSign(t *testing.T) { 85 key, _ := HexToECDSA(testPrivHex) 86 addr := common.HexToAddress(testAddrHex) 87 88 msg := Keccak256([]byte("foo")) 89 sig, err := Sign(msg, key) 90 if err != nil { 91 t.Errorf("Sign error: %s", err) 92 } 93 recoveredPub, err := Ecrecover(msg, sig) 94 if err != nil { 95 t.Errorf("ECRecover error: %s", err) 96 } 97 pubKey, _ := UnmarshalPubkey(recoveredPub) 98 recoveredAddr := PubkeyToAddress(*pubKey) 99 if addr != recoveredAddr { 100 t.Errorf("Address mismatch: want: %x have: %x", addr, recoveredAddr) 101 } 102 103 //应等于sigtopub 104 recoveredPub2, err := SigToPub(msg, sig) 105 if err != nil { 106 t.Errorf("ECRecover error: %s", err) 107 } 108 recoveredAddr2 := PubkeyToAddress(*recoveredPub2) 109 if addr != recoveredAddr2 { 110 t.Errorf("Address mismatch: want: %x have: %x", addr, recoveredAddr2) 111 } 112 } 113 114 func TestInvalidSign(t *testing.T) { 115 if _, err := Sign(make([]byte, 1), nil); err == nil { 116 t.Errorf("expected sign with hash 1 byte to error") 117 } 118 if _, err := Sign(make([]byte, 33), nil); err == nil { 119 t.Errorf("expected sign with hash 33 byte to error") 120 } 121 } 122 123 func TestNewContractAddress(t *testing.T) { 124 key, _ := HexToECDSA(testPrivHex) 125 addr := common.HexToAddress(testAddrHex) 126 genAddr := PubkeyToAddress(key.PublicKey) 127 //使用addr创建合同地址前的健全性检查 128 checkAddr(t, genAddr, addr) 129 130 caddr0 := CreateAddress(addr, 0) 131 caddr1 := CreateAddress(addr, 1) 132 caddr2 := CreateAddress(addr, 2) 133 checkAddr(t, common.HexToAddress("333c3310824b7c685133f2bedb2ca4b8b4df633d"), caddr0) 134 checkAddr(t, common.HexToAddress("8bda78331c916a08481428e4b07c96d3e916d165"), caddr1) 135 checkAddr(t, common.HexToAddress("c9ddedf451bc62ce88bf9292afb13df35b670699"), caddr2) 136 } 137 138 func TestLoadECDSAFile(t *testing.T) { 139 keyBytes := common.FromHex(testPrivHex) 140 fileName0 := "test_key0" 141 fileName1 := "test_key1" 142 checkKey := func(k *ecdsa.PrivateKey) { 143 checkAddr(t, PubkeyToAddress(k.PublicKey), common.HexToAddress(testAddrHex)) 144 loadedKeyBytes := FromECDSA(k) 145 if !bytes.Equal(loadedKeyBytes, keyBytes) { 146 t.Fatalf("private key mismatch: want: %x have: %x", keyBytes, loadedKeyBytes) 147 } 148 } 149 150 ioutil.WriteFile(fileName0, []byte(testPrivHex), 0600) 151 defer os.Remove(fileName0) 152 153 key0, err := LoadECDSA(fileName0) 154 if err != nil { 155 t.Fatal(err) 156 } 157 checkKey(key0) 158 159 //同样,这次使用saveecdsa而不是手动保存: 160 err = SaveECDSA(fileName1, key0) 161 if err != nil { 162 t.Fatal(err) 163 } 164 defer os.Remove(fileName1) 165 166 key1, err := LoadECDSA(fileName1) 167 if err != nil { 168 t.Fatal(err) 169 } 170 checkKey(key1) 171 } 172 173 func TestValidateSignatureValues(t *testing.T) { 174 check := func(expected bool, v byte, r, s *big.Int) { 175 if ValidateSignatureValues(v, r, s, false) != expected { 176 t.Errorf("mismatch for v: %d r: %d s: %d want: %v", v, r, s, expected) 177 } 178 } 179 minusOne := big.NewInt(-1) 180 one := common.Big1 181 zero := common.Big0 182 secp256k1nMinus1 := new(big.Int).Sub(secp256k1N, common.Big1) 183 184 //正确的V,R,S 185 check(true, 0, one, one) 186 check(true, 1, one, one) 187 //不正确的v,正确的r,s, 188 check(false, 2, one, one) 189 check(false, 3, one, one) 190 191 //不正确的V、不正确/正确的R、S组合在下限 192 check(false, 2, zero, zero) 193 check(false, 2, zero, one) 194 check(false, 2, one, zero) 195 check(false, 2, one, one) 196 197 //正确的V代表不正确的R,S组合 198 check(false, 0, zero, zero) 199 check(false, 0, zero, one) 200 check(false, 0, one, zero) 201 202 check(false, 1, zero, zero) 203 check(false, 1, zero, one) 204 check(false, 1, one, zero) 205 206 //用max r,s修正sig 207 check(true, 0, secp256k1nMinus1, secp256k1nMinus1) 208 //正确的V,上限不正确的R、S组合 209 check(false, 0, secp256k1N, secp256k1nMinus1) 210 check(false, 0, secp256k1nMinus1, secp256k1N) 211 check(false, 0, secp256k1N, secp256k1N) 212 213 //当前调用方确保r,s不能为负,但我们也要测试一下。 214 //因为加密包可以独立使用 215 check(false, 0, minusOne, one) 216 check(false, 0, one, minusOne) 217 } 218 219 func checkhash(t *testing.T, name string, f func([]byte) []byte, msg, exp []byte) { 220 sum := f(msg) 221 if !bytes.Equal(exp, sum) { 222 t.Fatalf("hash %s mismatch: want: %x have: %x", name, exp, sum) 223 } 224 } 225 226 func checkAddr(t *testing.T, addr0, addr1 common.Address) { 227 if addr0 != addr1 { 228 t.Fatalf("address mismatch: want: %x have: %x", addr0, addr1) 229 } 230 } 231 232 //测试以帮助Python团队集成libsecp256k1 233 //跳过,但完成后保留 234 func TestPythonIntegration(t *testing.T) { 235 kh := "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032" 236 k0, _ := HexToECDSA(kh) 237 238 msg0 := Keccak256([]byte("foo")) 239 sig0, _ := Sign(msg0, k0) 240 241 msg1 := common.FromHex("00000000000000000000000000000000") 242 sig1, _ := Sign(msg0, k0) 243 244 t.Logf("msg: %x, privkey: %s sig: %x\n", msg0, kh, sig0) 245 t.Logf("msg: %x, privkey: %s sig: %x\n", msg1, kh, sig1) 246 } 247