diff --git a/pkg/keystorev3/scrypt.go b/pkg/keystorev3/scrypt.go index 40188687..2b772503 100644 --- a/pkg/keystorev3/scrypt.go +++ b/pkg/keystorev3/scrypt.go @@ -45,7 +45,16 @@ func mustGenerateDerivedScryptKey(password string, salt []byte, n, p int) []byte return b } +// creates an ethereum address wallet file func newScryptWalletFile(password string, keypair *secp256k1.KeyPair, n int, p int) WalletFile { + wf := newScryptWalletFileBytes(password, keypair.PrivateKeyBytes(), n, p) + wf.Address = ethtypes.AddressPlainHex(keypair.Address) + wf.keypair = keypair + return wf +} + +// this allows creation of any size/type of key in the store +func newScryptWalletFileBytes(password string, privateKey []byte, n int, p int) *walletFileScrypt { // Generate a sale for the scrypt salt := mustReadBytes(32, rand.Reader) @@ -60,17 +69,16 @@ func newScryptWalletFile(password string, keypair *secp256k1.KeyPair, n int, p i encryptKey := derivedKey[0:16] // Encrypt the private key with the encryption key - cipherText := mustAES128CtrEncrypt(encryptKey, iv, keypair.PrivateKeyBytes()) + cipherText := mustAES128CtrEncrypt(encryptKey, iv, privateKey) // Last 16 bytes of derived key are used for the MAC mac := generateMac(derivedKey[16:32], cipherText) return &walletFileScrypt{ walletFileBase: walletFileBase{ - Address: ethtypes.AddressPlainHex(keypair.Address), - ID: fftypes.NewUUID(), - Version: version3, - keypair: keypair, + ID: fftypes.NewUUID(), + Version: version3, + privateKey: privateKey, }, Crypto: cryptoScrypt{ cryptoCommon: cryptoCommon{ diff --git a/pkg/keystorev3/wallet.go b/pkg/keystorev3/wallet.go index 3319ed03..da27d2b1 100644 --- a/pkg/keystorev3/wallet.go +++ b/pkg/keystorev3/wallet.go @@ -39,6 +39,14 @@ func NewWalletFileStandard(password string, keypair *secp256k1.KeyPair) WalletFi return newScryptWalletFile(password, keypair, nStandard, pDefault) } +func NewWalletFileCustomBytesLight(password string, privateKey []byte) WalletFile { + return newScryptWalletFileBytes(password, privateKey, nStandard, pDefault) +} + +func NewWalletFileCustomBytesStandard(password string, privateKey []byte) WalletFile { + return newScryptWalletFileBytes(password, privateKey, nStandard, pDefault) +} + func ReadWalletFile(jsonWallet []byte, password []byte) (WalletFile, error) { var w walletFileCommon if err := json.Unmarshal(jsonWallet, &w); err != nil { diff --git a/pkg/keystorev3/wallet_test.go b/pkg/keystorev3/wallet_test.go index 9fe2ceb2..bfcc9209 100644 --- a/pkg/keystorev3/wallet_test.go +++ b/pkg/keystorev3/wallet_test.go @@ -123,3 +123,33 @@ func TestWalletFilePbkdf2JSON(t *testing.T) { assert.NoError(t, err) assert.Equal(t, w, w2) } + +func TestWalletFileCustomBytes(t *testing.T) { + customBytes := ([]byte)("planet refuse wheel robot position venue predict bring solid paper salmon bind") + + w := NewWalletFileCustomBytesStandard("correcthorsebatterystaple", customBytes) + + w, err := ReadWalletFile(w.JSON(), []byte("correcthorsebatterystaple")) + assert.NoError(t, err) + j := w.JSON() + w2, err := ReadWalletFile(j, []byte("correcthorsebatterystaple")) + assert.NoError(t, err) + assert.Equal(t, w, w2) + + assert.Equal(t, customBytes, w.PrivateKey()) +} + +func TestWalletFileCustomBytesLight(t *testing.T) { + customBytes := ([]byte)("planet refuse wheel robot position venue predict bring solid paper salmon bind") + + w := NewWalletFileCustomBytesLight("correcthorsebatterystaple", customBytes) + + w, err := ReadWalletFile(w.JSON(), []byte("correcthorsebatterystaple")) + assert.NoError(t, err) + j := w.JSON() + w2, err := ReadWalletFile(j, []byte("correcthorsebatterystaple")) + assert.NoError(t, err) + assert.Equal(t, w, w2) + + assert.Equal(t, customBytes, w.PrivateKey()) +}