github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/identity/keystore_filesystem_test.go (about) 1 /* 2 * Copyright (C) 2020 The "MysteriumNetwork/node" Authors. 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU 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 * This program 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 General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 package identity 19 20 import ( 21 "testing" 22 23 "github.com/ethereum/go-ethereum/accounts" 24 ethKs "github.com/ethereum/go-ethereum/accounts/keystore" 25 "github.com/ethereum/go-ethereum/common" 26 "github.com/ethereum/go-ethereum/crypto" 27 "github.com/pkg/errors" 28 "github.com/stretchr/testify/assert" 29 ) 30 31 const secretMessage = "I like trains. A LOT. Choo CHOO" 32 33 var ( 34 encryptionAddress = common.HexToAddress("53a835143c0ef3bbcbfa796d7eb738ca7dd28f68") 35 encryptionAccount = accounts.Account{Address: encryptionAddress} 36 encryptionKey, _ = crypto.HexToECDSA("6f88637b68ee88816e73f663aef709d7009836c98ae91ef31e3dfac7be3a1657") 37 ) 38 39 func Test_DerivedEncryption(t *testing.T) { 40 ks := NewKeystoreFilesystem("", ðKeystoreMock{account: encryptionAccount}) 41 ks.loadKey = func(addr common.Address, filename, auth string) (*ethKs.Key, error) { 42 return ðKs.Key{Address: addr, PrivateKey: encryptionKey}, nil 43 } 44 45 t.Run("Fails to decrypt or encrypt if account is locked", func(t *testing.T) { 46 encrypted, err := ks.Encrypt(encryptionAddress, []byte(secretMessage)) 47 assert.Error(t, err) 48 49 _, err = ks.Decrypt(encryptionAddress, encrypted) 50 assert.Error(t, err) 51 }) 52 53 err := ks.Unlock(encryptionAccount, "") 54 assert.NoError(t, err) 55 56 t.Run("Encrypts and decrypts messages with the derived key", func(t *testing.T) { 57 encrypted, err := ks.Encrypt(encryptionAddress, []byte(secretMessage)) 58 assert.NoError(t, err) 59 assert.NotEqual(t, []byte(secretMessage), encrypted) 60 61 decrypted, err := ks.Decrypt(encryptionAddress, encrypted) 62 assert.NoError(t, err) 63 64 assert.Equal(t, secretMessage, string(decrypted)) 65 }) 66 67 t.Run("Errors if message is tampered with", func(t *testing.T) { 68 encrypted, err := ks.Encrypt(encryptionAddress, []byte(secretMessage)) 69 assert.NoError(t, err) 70 assert.NotEqual(t, []byte(secretMessage), encrypted) 71 72 encrypted[1] = 0x1 73 _, err = ks.Decrypt(encryptionAddress, encrypted) 74 assert.Error(t, err) 75 }) 76 } 77 78 var result []byte 79 80 func Benchmark_DerivedEncryption(b *testing.B) { 81 ks := NewKeystoreFilesystem("", ðKeystoreMock{account: encryptionAccount}) 82 ks.loadKey = func(addr common.Address, filename, auth string) (*ethKs.Key, error) { 83 return ðKs.Key{}, nil 84 } 85 _ = ks.Unlock(encryptionAccount, "") 86 87 var r []byte 88 for n := 0; n < b.N; n++ { 89 encrypted, _ := ks.Encrypt(encryptionAddress, []byte(secretMessage)) 90 r = encrypted 91 } 92 93 result = r 94 } 95 96 func Benchmark_DerivedDecryption(b *testing.B) { 97 ks := NewKeystoreFilesystem("", ðKeystoreMock{account: encryptionAccount}) 98 ks.loadKey = func(addr common.Address, filename, auth string) (*ethKs.Key, error) { 99 return ðKs.Key{}, nil 100 } 101 _ = ks.Unlock(encryptionAccount, "") 102 encrypted, _ := ks.Encrypt(encryptionAddress, []byte(secretMessage)) 103 104 var r []byte 105 for n := 0; n < b.N; n++ { 106 decrypted, _ := ks.Decrypt(encryptionAddress, encrypted) 107 r = decrypted 108 } 109 110 result = r 111 } 112 113 type ethKeystoreMock struct { 114 account accounts.Account 115 unlocked bool 116 } 117 118 func (ekm *ethKeystoreMock) Unlock(a accounts.Account, passphrase string) error { 119 ekm.unlocked = true 120 return nil 121 } 122 123 func (ekm *ethKeystoreMock) Delete(a accounts.Account, passphrase string) error { 124 if a.Address == ekm.account.Address { 125 ekm.account = accounts.Account{} 126 } 127 128 return nil 129 } 130 131 func (ekm *ethKeystoreMock) Export(a accounts.Account, passphrase, newPassphrase string) ([]byte, error) { 132 return []byte("exported"), nil 133 } 134 135 func (ekm *ethKeystoreMock) Import(keyJSON []byte, passphrase, newPassphrase string) (accounts.Account, error) { 136 return ekm.account, nil 137 } 138 139 func (ekm *ethKeystoreMock) Accounts() []accounts.Account { 140 return []accounts.Account{ekm.account} 141 } 142 143 func (ekm *ethKeystoreMock) Find(a accounts.Account) (accounts.Account, error) { 144 if ekm.account.Address == a.Address { 145 return ekm.account, nil 146 } 147 return accounts.Account{}, errors.New("not found") 148 } 149 150 func (ekm *ethKeystoreMock) NewAccount(passphrase string) (accounts.Account, error) { 151 return accounts.Account{}, errors.New("not implemented yet") 152 }