github.com/core-coin/go-core/v2@v2.1.9/crypto/ecies/ecies_test.go (about) 1 // Copyright (c) 2013 Kyle Isom <kyle@tyrfingr.is> 2 // Copyright (c) 2012 The Go Authors. All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above 11 // copyright notice, this list of conditions and the following disclaimer 12 // in the documentation and/or other materials provided with the 13 // distribution. 14 // * Neither the name of Google Inc. nor the names of its 15 // contributors may be used to endorse or promote products derived from 16 // this software without specific prior written permission. 17 // 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30 package ecies 31 32 import ( 33 "bytes" 34 "crypto/rand" 35 "encoding/hex" 36 "fmt" 37 "testing" 38 39 "golang.org/x/crypto/sha3" 40 41 "github.com/core-coin/go-core/v2/common" 42 "github.com/core-coin/go-core/v2/crypto" 43 ) 44 45 func TestKDF(t *testing.T) { 46 tests := []struct { 47 length int 48 output []byte 49 }{ 50 {6, decode("7dd366b373fd")}, 51 {32, decode("7dd366b373fdc9b1626148e981a057b4913b0e00dec183907d22872a6b1f9db7")}, 52 {48, decode("7dd366b373fdc9b1626148e981a057b4913b0e00dec183907d22872a6b1f9db7f489ffb85e14eb26fb5443f374a985b2")}, 53 {64, decode("7dd366b373fdc9b1626148e981a057b4913b0e00dec183907d22872a6b1f9db7f489ffb85e14eb26fb5443f374a985b2a13189abab09aa0b497f2bcb257e6356")}, 54 } 55 56 for _, test := range tests { 57 h := sha3.New256() 58 k := concatKDF(h, []byte("input"), nil, test.length) 59 if !bytes.Equal(k, test.output) { 60 t.Fatalf("KDF: generated key %x does not match expected output %x", k, test.output) 61 } 62 } 63 } 64 65 var ErrBadSharedKeys = fmt.Errorf("ecies: shared keys don't match") 66 67 // Validate the ECDH component. 68 func TestSharedKey(t *testing.T) { 69 prv1, err := crypto.GenerateKey(rand.Reader) 70 if err != nil { 71 t.Fatal(err) 72 } 73 74 prv2, err := crypto.GenerateKey(rand.Reader) 75 if err != nil { 76 t.Fatal(err) 77 } 78 79 pub1 := crypto.DerivePublicKey(prv1) 80 pub2 := crypto.DerivePublicKey(prv2) 81 82 sk1 := crypto.ComputeSecret(prv1, pub2) 83 84 sk2 := crypto.ComputeSecret(prv2, pub1) 85 86 if !bytes.Equal(sk1, sk2) { 87 t.Fatal(ErrBadSharedKeys) 88 } 89 } 90 91 func TestSharedKeyPadding(t *testing.T) { 92 // sanity checks 93 prv0, _ := crypto.UnmarshalPrivateKey(common.Hex2Bytes("1033b1bac4c731e800b6399a357e51cf1b20eec942aac608c90b89553003e2ed3f94bd80613ee9006b1e62b6bb45109d0db9a4833e78363991")) 94 prv1, _ := crypto.UnmarshalPrivateKey(common.Hex2Bytes("fdf02153a9d5e3e0f3a958bbe9ee7e79eaf77a22703aee462354998ab0178f06566707c297df3510a3b071ccedac6b3154531aa51d10401868")) 95 pub0 := decode("2f65ab658f3b0bc9fbdea48703b9c5c0dc2151c5ae8c4b77b1e5cdaee9fa20748e01960ab51ddb118d1209f73d186f0444921ad72c7c757480") 96 pub1 := decode("77b1d24670fee6dd811f4f06573ce5f19844eb50cb6ce960d12bdbc8bf77be2221111cf755371d9e896e544ea2a4ebf206b775df55f5e74580") 97 98 prv0Pub := crypto.DerivePublicKey(prv0) 99 prv1Pub := crypto.DerivePublicKey(prv1) 100 101 if !bytes.Equal(prv0Pub[:], pub0) { 102 t.Errorf("mismatched prv0.X:\nhave: %x\nwant: %x\n", prv0Pub, pub0) 103 } 104 if !bytes.Equal(prv1Pub[:], pub1) { 105 t.Errorf("mismatched prv1.X:\nhave: %x\nwant: %x\n", prv1Pub, pub1) 106 } 107 108 // test shared secret generation 109 sk1 := crypto.ComputeSecret(prv0, prv1Pub) 110 111 sk2 := crypto.ComputeSecret(prv1, prv0Pub) 112 113 if !bytes.Equal(sk1, sk2) { 114 t.Fatal(ErrBadSharedKeys.Error()) 115 } 116 } 117 118 // Benchmark the generation of P256 keys. 119 func BenchmarkGenerateKeyP256(b *testing.B) { 120 for i := 0; i < b.N; i++ { 121 if _, err := crypto.GenerateKey(rand.Reader); err != nil { 122 b.Fatal(err) 123 } 124 } 125 } 126 127 // Benchmark the generation of P256 shared keys. 128 func BenchmarkGenSharedKeyP256(b *testing.B) { 129 prv, err := crypto.GenerateKey(rand.Reader) 130 if err != nil { 131 b.Fatal(err) 132 } 133 b.ResetTimer() 134 for i := 0; i < b.N; i++ { 135 k := crypto.ComputeSecret(prv, crypto.DerivePublicKey(prv)) 136 if len(k) != 0 { 137 b.Fatal("zero key len") 138 } 139 } 140 } 141 142 // Verify that an encrypted message can be successfully decrypted. 143 func TestEncryptDecrypt(t *testing.T) { 144 prv1, err := crypto.GenerateKey(rand.Reader) 145 if err != nil { 146 t.Fatal(err) 147 } 148 149 prv2, err := crypto.GenerateKey(rand.Reader) 150 if err != nil { 151 t.Fatal(err) 152 } 153 154 message := []byte("Hello, world.") 155 ct, err := Encrypt(rand.Reader, crypto.DerivePublicKey(prv2), message, nil, nil) 156 if err != nil { 157 t.Fatal(err) 158 } 159 160 pt, err := Decrypt(prv2, ct, nil, nil) 161 if err != nil { 162 t.Fatal(err) 163 } 164 165 if !bytes.Equal(pt, message) { 166 t.Fatal("ecies: plaintext doesn't match message") 167 } 168 169 _, err = Decrypt(prv1, ct, nil, nil) 170 if err == nil { 171 t.Fatal("ecies: encryption should not have succeeded") 172 } 173 } 174 175 func TestDecryptShared2(t *testing.T) { 176 prv, err := crypto.GenerateKey(rand.Reader) 177 if err != nil { 178 t.Fatal(err) 179 } 180 181 message := []byte("Hello, world.") 182 shared2 := []byte("shared data 2") 183 ct, err := Encrypt(rand.Reader, crypto.DerivePublicKey(prv), message, nil, shared2) 184 if err != nil { 185 t.Fatal(err) 186 } 187 188 // Check that decrypting with correct shared data works. 189 pt, err := Decrypt(prv, ct, nil, shared2) 190 if err != nil { 191 t.Fatal(err) 192 } 193 if !bytes.Equal(pt, message) { 194 t.Fatal("ecies: plaintext doesn't match message") 195 } 196 197 // Decrypting without shared data or incorrect shared data fails. 198 if _, err = Decrypt(prv, ct, nil, nil); err == nil { 199 t.Fatal("ecies: decrypting without shared data didn't fail") 200 } 201 if _, err = Decrypt(prv, ct, nil, []byte("garbage")); err == nil { 202 t.Fatal("ecies: decrypting with incorrect shared data didn't fail") 203 } 204 } 205 206 func TestBox(t *testing.T) { 207 prv1, _ := crypto.UnmarshalPrivateKey(common.Hex2Bytes("1033b1bac4c731e800b6399a357e51cf1b20eec942aac608c90b89553003e2ed3f94bd80613ee9006b1e62b6bb45109d0db9a4833e78363991")) 208 prv2, _ := crypto.UnmarshalPrivateKey(common.Hex2Bytes("fdf02153a9d5e3e0f3a958bbe9ee7e79eaf77a22703aee462354998ab0178f06566707c297df3510a3b071ccedac6b3154531aa51d10401868")) 209 210 message := []byte("Hello, world.") 211 ct, err := Encrypt(rand.Reader, crypto.DerivePublicKey(prv2), message, nil, nil) 212 if err != nil { 213 t.Fatal(err) 214 } 215 216 pt, err := Decrypt(prv2, ct, nil, nil) 217 if err != nil { 218 t.Fatal(err) 219 } 220 if !bytes.Equal(pt, message) { 221 t.Fatal("ecies: plaintext doesn't match message") 222 } 223 if _, err = Decrypt(prv1, ct, nil, nil); err == nil { 224 t.Fatal("ecies: encryption should not have succeeded") 225 } 226 } 227 228 // Verify GenerateShared against static values - useful when 229 // debugging changes in underlying libs 230 func TestSharedKeyStatic(t *testing.T) { 231 prv1, _ := crypto.UnmarshalPrivateKey(common.Hex2Bytes("1033b1bac4c731e800b6399a357e51cf1b20eec942aac608c90b89553003e2ed3f94bd80613ee9006b1e62b6bb45109d0db9a4833e78363991")) 232 prv2, _ := crypto.UnmarshalPrivateKey(common.Hex2Bytes("fdf02153a9d5e3e0f3a958bbe9ee7e79eaf77a22703aee462354998ab0178f06566707c297df3510a3b071ccedac6b3154531aa51d10401868")) 233 234 pub1 := crypto.DerivePublicKey(prv1) 235 pub2 := crypto.DerivePublicKey(prv2) 236 237 sk1 := crypto.ComputeSecret(prv1, pub2) 238 239 sk2 := crypto.ComputeSecret(prv2, pub1) 240 241 if !bytes.Equal(sk1, sk2) { 242 t.Fatal(ErrBadSharedKeys) 243 } 244 245 sk := decode("55a3895b1c32b1d9b2160d81da1f56d2f60641fc6b997adffc53b5f473e2b62a0dc65fb4aed8fddbae912864b683a29885df4bd86c1d4760") 246 if !bytes.Equal(sk1, sk) { 247 t.Fatalf("shared secret mismatch: want: %x have: %x", sk, sk1) 248 } 249 } 250 251 func decode(s string) []byte { 252 bytes, err := hex.DecodeString(s) 253 if err != nil { 254 panic(err) 255 } 256 return bytes 257 }