Merge pull request #2001 from nspcc-dev/tests/fix-failing-workflows

crypto: use non-default scrypt parameters for encrypting/decrypting
This commit is contained in:
Roman Khimov 2021-06-11 17:27:03 +03:00 committed by GitHub
commit d5e11e0a75
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 201 additions and 143 deletions

View file

@ -8,6 +8,7 @@ import (
"math/big"
"os"
"path"
"strings"
"testing"
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
@ -229,7 +230,8 @@ func TestNEP11_OwnerOf_BalanceOf_Transfer(t *testing.T) {
// properties: ok
e.Run(t, cmdProperties...)
e.checkNextLine(t, fmt.Sprintf(`{"name":"HASHY %s"}`, string(tokenID)))
marshalledID := strings.Replace(string(tokenID), "+", "\\u002B", -1)
require.Equal(t, fmt.Sprintf(`{"name":"HASHY %s"}`, marshalledID), e.getNextLine(t))
// tokensOf: good, several tokens
tokenID1 := mint(t)

View file

@ -744,7 +744,7 @@ func getAccFromContext(ctx *cli.Context) (*wallet.Account, *wallet.Wallet, error
return nil, nil, cli.NewExitError(err, 1)
}
pass := strings.TrimRight(string(rawPass), "\n")
err = acc.Decrypt(pass)
err = acc.Decrypt(pass, wall.Scrypt)
if err != nil {
return nil, nil, cli.NewExitError(err, 1)
}

View file

@ -3,7 +3,7 @@
"accounts": [
{
"address": "Nfyz4KcsgYepRJw1W5C2uKCi6QWKf7v6gG",
"key": "6PYVjvHy8n4suq81uxkWqriiffKWFpTFPve57HdzWdDhpYUUYRUTai1jZS",
"key": "6PYVjvHyAFQPXCU3PNsiRbF1RxEyyrT4PqLbSEEZcyYDFAMpSxPZnuRznY",
"label": "kek",
"contract": {
"script": "DCECl3UyEIq6T5RRIXS6z4tNdZPTzQ7NvXyx7FwK05d9UyZBVuezJw==",
@ -20,9 +20,9 @@
}
],
"scrypt": {
"n": 16384,
"r": 8,
"p": 8
"n": 2,
"r": 1,
"p": 1
},
"extra": {
"Tokens": null

View file

@ -1,28 +1,27 @@
{
"extra" : {
"Tokens" : null
},
"version": "3.0",
"accounts": [
{
"address": "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn",
"key": "6PYM8VdX3hY4B51UJxmm8D41RQMbpJT8aYHibyQ67gjkUPmvQgu51Y5UQR",
"label": "",
"key" : "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY",
"lock" : false,
"isDefault" : true,
"contract": {
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcJBVuezJw==",
"deployed" : false,
"parameters": [
{
"name": "parameter0",
"type": "Signature"
}
]
],
"deployed": false
},
"address" : "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn"
"lock": false,
"isDefault": true
},
{
"lock" : false,
"isDefault" : false,
"address": "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq",
"key": "6PYM8VdX3hY4B51UJxmm8D41RQMbpJT8aYHibyQ67gjkUPmvQgu51Y5UQR",
"label": "",
"contract": {
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEGe0Nw6",
"parameters": [
@ -35,50 +34,51 @@
"type": "Signature"
},
{
"type" : "Signature",
"name" : "parameter2"
"name": "parameter2",
"type": "Signature"
}
],
"deployed": false
},
"address" : "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq",
"label" : "",
"key" : "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY"
"lock": false,
"isDefault": false
},
{
"lock" : false,
"isDefault" : false,
"address": "NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP",
"key": "6PYM8VdX3hY4B51UJxmm8D41RQMbpJT8aYHibyQ67gjkUPmvQgu51Y5UQR",
"label": "",
"contract": {
"script": "EQwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CEUGe0Nw6",
"parameters": [
{
"name": "parameter0",
"type": "Signature"
}
],
"deployed" : false,
"script" : "EQwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CEUGe0Nw6"
"deployed": false
},
"address" : "NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP",
"label" : "",
"key" : "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY"
"lock": false,
"isDefault": false
},
{
"address": "NU4CTk9H2fgNCuC3ZPqX4LjUX3MHt3Rh6p",
"key": "6PYSATFztBa3CHjSR6sLAKungUEAbQUCVE16KzmaQQ38gLeYGZ9Knd5mGv",
"label": "verify",
"contract": {
"script": "EdsgQFcAA0BXAQR4eXp7VBTAcAwOT25ORVAxMVBheW1lbnRoUEGVAW9hIUA=",
"parameters": [],
"deployed": true
},
"lock": false,
"isDefault" : false,
"key" : "6PYSATFzuRXXUeq7tMDyA1AGxWdVcm7ftbkqtGBt69WJBapT1tkwjp1zpx",
"label" : "acc"
"isDefault": false
}
],
"version" : "3.0",
"scrypt": {
"r" : 8,
"n" : 16384,
"p" : 8
"n": 2,
"r": 1,
"p": 1
},
"extra": {
"Tokens": null
}
}

View file

@ -50,9 +50,9 @@ func newWalletV2FromFile(path string) (*walletV2, error) {
const simpleSigLen = 35
func (a *accountV2) convert(pass string) (*wallet.Account, error) {
func (a *accountV2) convert(pass string, scrypt keys.ScryptParams) (*wallet.Account, error) {
address.Prefix = address.NEO2Prefix
priv, err := keys.NEP2Decrypt(a.EncryptedWIF, pass)
priv, err := keys.NEP2Decrypt(a.EncryptedWIF, pass, scrypt)
if err != nil {
return nil, err
}
@ -83,7 +83,7 @@ func (a *accountV2) convert(pass string) (*wallet.Account, error) {
newAcc.Default = a.Default
newAcc.Label = a.Label
newAcc.Locked = a.Locked
return newAcc, newAcc.Encrypt(pass)
return newAcc, newAcc.Encrypt(pass, scrypt)
}
const (

View file

@ -214,7 +214,7 @@ func getDecryptedAccount(ctx *cli.Context, wall *wallet.Wallet, addr util.Uint16
if pass, err := input.ReadPassword("Password > "); err != nil {
fmt.Println("ERROR", pass, err)
return nil, err
} else if err := acc.Decrypt(pass); err != nil {
} else if err := acc.Decrypt(pass, wall.Scrypt); err != nil {
return nil, err
}
return acc, nil

View file

@ -297,13 +297,14 @@ func convertWallet(ctx *cli.Context) error {
return cli.NewExitError(err, 1)
}
defer newWallet.Close()
newWallet.Scrypt = wall.Scrypt
for _, acc := range wall.Accounts {
pass, err := input.ReadPassword(fmt.Sprintf("Enter passphrase for account %s (label '%s') > ", acc.Address, acc.Label))
if err != nil {
return cli.NewExitError(err, 1)
}
newAcc, err := acc.convert(pass)
newAcc, err := acc.convert(pass, wall.Scrypt)
if err != nil {
return cli.NewExitError(err, 1)
}
@ -374,7 +375,7 @@ loop:
return cli.NewExitError(err, 1)
}
pk, err := keys.NEP2Decrypt(wif, pass)
pk, err := keys.NEP2Decrypt(wif, pass, wall.Scrypt)
if err != nil {
return cli.NewExitError(err, 1)
}
@ -411,7 +412,7 @@ func importMultisig(ctx *cli.Context) error {
}
}
acc, err := newAccountFromWIF(ctx.App.Writer, ctx.String("wif"))
acc, err := newAccountFromWIF(ctx.App.Writer, ctx.String("wif"), wall.Scrypt)
if err != nil {
return cli.NewExitError(err, 1)
}
@ -443,7 +444,7 @@ func importDeployed(ctx *cli.Context) error {
return cli.NewExitError("contract hash was not provided", 1)
}
acc, err := newAccountFromWIF(ctx.App.Writer, ctx.String("wif"))
acc, err := newAccountFromWIF(ctx.App.Writer, ctx.String("wif"), wall.Scrypt)
if err != nil {
return cli.NewExitError(err, 1)
}
@ -492,7 +493,7 @@ func importWallet(ctx *cli.Context) error {
}
defer wall.Close()
acc, err := newAccountFromWIF(ctx.App.Writer, ctx.String("wif"))
acc, err := newAccountFromWIF(ctx.App.Writer, ctx.String("wif"), wall.Scrypt)
if err != nil {
return cli.NewExitError(err, 1)
}
@ -570,7 +571,7 @@ func dumpWallet(ctx *cli.Context) error {
}
for i := range wall.Accounts {
// Just testing the decryption here.
err := wall.Accounts[i].Decrypt(pass)
err := wall.Accounts[i].Decrypt(pass, wall.Scrypt)
if err != nil {
return cli.NewExitError(err, 1)
}
@ -685,7 +686,7 @@ func openWallet(path string) (*wallet.Wallet, error) {
return wallet.NewWalletFromFile(path)
}
func newAccountFromWIF(w io.Writer, wif string) (*wallet.Account, error) {
func newAccountFromWIF(w io.Writer, wif string, scrypt keys.ScryptParams) (*wallet.Account, error) {
// note: NEP2 strings always have length of 58 even though
// base58 strings can have different lengths even if slice lengths are equal
if len(wif) == 58 {
@ -694,7 +695,7 @@ func newAccountFromWIF(w io.Writer, wif string) (*wallet.Account, error) {
return nil, err
}
return wallet.NewAccountFromEncryptedWIF(wif, pass)
return wallet.NewAccountFromEncryptedWIF(wif, pass, scrypt)
}
acc, err := wallet.NewAccountFromWIF(wif)
@ -709,7 +710,7 @@ func newAccountFromWIF(w io.Writer, wif string) (*wallet.Account, error) {
}
acc.Label = name
if err := acc.Encrypt(pass); err != nil {
if err := acc.Encrypt(pass, scrypt); err != nil {
return nil, err
}

View file

@ -48,7 +48,7 @@ func TestWalletInit(t *testing.T) {
require.NoError(t, err)
require.Len(t, w.Accounts, 1)
require.Equal(t, "букandmore", w.Accounts[0].Label)
require.NoError(t, w.Accounts[0].Decrypt("пароль"))
require.NoError(t, w.Accounts[0].Decrypt("пароль", w.Scrypt))
w.Close()
})
@ -62,7 +62,7 @@ func TestWalletInit(t *testing.T) {
require.NoError(t, err)
require.Len(t, w.Accounts, 1)
require.Equal(t, w.Accounts[0].Label, "testname")
require.NoError(t, w.Accounts[0].Decrypt("testpass"))
require.NoError(t, w.Accounts[0].Decrypt("testpass", w.Scrypt))
w.Close()
t.Run("RemoveAccount", func(t *testing.T) {
@ -94,7 +94,7 @@ func TestWalletInit(t *testing.T) {
acc := w.GetAccount(priv.GetScriptHash())
require.NotNil(t, acc)
require.Equal(t, "test_account", acc.Label)
require.NoError(t, acc.Decrypt("qwerty"))
require.NoError(t, acc.Decrypt("qwerty", w.Scrypt))
t.Run("AlreadyExists", func(t *testing.T) {
e.In.WriteString("test_account_2\r")
@ -107,7 +107,7 @@ func TestWalletInit(t *testing.T) {
t.Run("EncryptedWIF", func(t *testing.T) {
acc, err := wallet.NewAccount()
require.NoError(t, err)
require.NoError(t, acc.Encrypt("somepass"))
require.NoError(t, acc.Encrypt("somepass", keys.NEP2ScryptParams()))
t.Run("InvalidPassword", func(t *testing.T) {
e.In.WriteString("password1\r")
@ -124,7 +124,7 @@ func TestWalletInit(t *testing.T) {
t.Cleanup(w.Close)
actual := w.GetAccount(acc.PrivateKey().GetScriptHash())
require.NotNil(t, actual)
require.NoError(t, actual.Decrypt("somepass"))
require.NoError(t, actual.Decrypt("somepass", w.Scrypt))
})
t.Run("Multisig", func(t *testing.T) {
privs, pubs := generateKeys(t, 4)
@ -160,7 +160,7 @@ func TestWalletInit(t *testing.T) {
t.Cleanup(w.Close)
actual := w.GetAccount(hash.Hash160(script))
require.NotNil(t, actual)
require.NoError(t, actual.Decrypt("multipass"))
require.NoError(t, actual.Decrypt("multipass", w.Scrypt))
require.Equal(t, script, actual.Contract.Script)
})
})
@ -174,7 +174,7 @@ func TestWalletExport(t *testing.T) {
"--wallet", validatorWallet, validatorAddr)
line, err := e.Out.ReadString('\n')
require.NoError(t, err)
enc, err := keys.NEP2Encrypt(validatorPriv, "one")
enc, err := keys.NEP2Encrypt(validatorPriv, "one", keys.ScryptParams{N: 2, R: 1, P: 1}) // these params used in validator wallet for better resources consumption
require.NoError(t, err)
require.Equal(t, enc, strings.TrimSpace(line))
})

View file

@ -142,7 +142,7 @@ func NewService(cfg Config) (Service, error) {
// Check that wallet password is correct for at least one account.
var ok bool
for _, acc := range srv.wallet.Accounts {
err := acc.Decrypt(srv.Config.Wallet.Password)
err := acc.Decrypt(srv.Config.Wallet.Password, srv.wallet.Scrypt)
if err == nil {
ok = true
break
@ -345,7 +345,7 @@ func (s *service) getKeyPair(pubs []crypto.PublicKey) (int, crypto.PrivateKey, c
key := acc.PrivateKey()
if acc.PrivateKey() == nil {
err := acc.Decrypt(s.Config.Wallet.Password)
err := acc.Decrypt(s.Config.Wallet.Password, s.wallet.Scrypt)
if err != nil {
s.log.Fatal("can't unlock account", zap.String("address", address.Uint160ToString(sh)))
break

View file

@ -449,7 +449,7 @@ func initBasicChain(t *testing.T, bc *Blockchain) {
// Designate new Notary node
ntr, err := wallet.NewWalletFromFile(path.Join(notaryModulePath, "./testdata/notary1.json"))
require.NoError(t, err)
require.NoError(t, ntr.Accounts[0].Decrypt("one"))
require.NoError(t, ntr.Accounts[0].Decrypt("one", ntr.Scrypt))
bc.setNodesByRole(t, true, noderoles.P2PNotary, keys.PublicKeys{ntr.Accounts[0].PrivateKey().PublicKey()})
t.Logf("Designated Notary node: %s", hex.EncodeToString(ntr.Accounts[0].PrivateKey().PublicKey().Bytes()))

View file

@ -52,7 +52,7 @@ func getTestNotary(t *testing.T, bc *Blockchain, walletPath, pass string, onTx f
w, err := wallet.NewWalletFromFile(path.Join(notaryModulePath, walletPath))
require.NoError(t, err)
require.NoError(t, w.Accounts[0].Decrypt(pass))
require.NoError(t, w.Accounts[0].Decrypt(pass, w.Scrypt))
return w.Accounts[0], ntr, mp
}

View file

@ -66,7 +66,7 @@ func getTestOracle(t *testing.T, bc *Blockchain, walletPath, pass string) (
w, err := wallet.NewWalletFromFile(path.Join(oracleModulePath, walletPath))
require.NoError(t, err)
require.NoError(t, w.Accounts[0].Decrypt(pass))
require.NoError(t, w.Accounts[0].Decrypt(pass, w.Scrypt))
return w.Accounts[0], orc, m, ch
}

View file

@ -172,7 +172,7 @@ func TestStateRootInitNonZeroHeight(t *testing.T) {
func createAndWriteWallet(t *testing.T, acc *wallet.Account, path, password string) *wallet.Wallet {
w, err := wallet.NewWallet(path)
require.NoError(t, err)
require.NoError(t, acc.Encrypt(password))
require.NoError(t, acc.Encrypt(password, w.Scrypt))
w.AddAccount(acc)
require.NoError(t, w.Save())
w.Close()

View file

@ -42,13 +42,13 @@ func NEP2ScryptParams() ScryptParams {
// NEP2Encrypt encrypts a the PrivateKey using a given passphrase
// under the NEP-2 standard.
func NEP2Encrypt(priv *PrivateKey, passphrase string) (s string, err error) {
func NEP2Encrypt(priv *PrivateKey, passphrase string, params ScryptParams) (s string, err error) {
address := priv.Address()
addrHash := hash.Checksum([]byte(address))
// Normalize the passphrase according to the NFC standard.
phraseNorm := norm.NFC.Bytes([]byte(passphrase))
derivedKey, err := scrypt.Key(phraseNorm, addrHash, n, r, p, keyLen)
derivedKey, err := scrypt.Key(phraseNorm, addrHash, params.N, params.R, params.P, keyLen)
if err != nil {
return s, err
}
@ -77,7 +77,7 @@ func NEP2Encrypt(priv *PrivateKey, passphrase string) (s string, err error) {
// NEP2Decrypt decrypts an encrypted key using a given passphrase
// under the NEP-2 standard.
func NEP2Decrypt(key, passphrase string) (*PrivateKey, error) {
func NEP2Decrypt(key, passphrase string, params ScryptParams) (*PrivateKey, error) {
b, err := base58.CheckDecode(key)
if err != nil {
return nil, err
@ -89,7 +89,7 @@ func NEP2Decrypt(key, passphrase string) (*PrivateKey, error) {
addrHash := b[3:7]
// Normalize the passphrase according to the NFC standard.
phraseNorm := norm.NFC.Bytes([]byte(passphrase))
derivedKey, err := scrypt.Key(phraseNorm, addrHash, n, r, p, keyLen)
derivedKey, err := scrypt.Key(phraseNorm, addrHash, params.N, params.R, params.P, keyLen)
if err != nil {
return nil, err
}

View file

@ -17,7 +17,7 @@ func TestNEP2Encrypt(t *testing.T) {
assert.Nil(t, err)
encryptedWif, err := NEP2Encrypt(privKey, testCase.Passphrase)
encryptedWif, err := NEP2Encrypt(privKey, testCase.Passphrase, NEP2ScryptParams())
assert.Nil(t, err)
assert.Equal(t, testCase.EncryptedWif, encryptedWif)
@ -26,7 +26,7 @@ func TestNEP2Encrypt(t *testing.T) {
func TestNEP2Decrypt(t *testing.T) {
for _, testCase := range keytestcases.Arr {
privKey, err := NEP2Decrypt(testCase.EncryptedWif, testCase.Passphrase)
privKey, err := NEP2Decrypt(testCase.EncryptedWif, testCase.Passphrase, NEP2ScryptParams())
if testCase.Invalid {
assert.Error(t, err)
continue
@ -48,12 +48,12 @@ func TestNEP2DecryptErrors(t *testing.T) {
// Not a base58-encoded value
s := "qazwsx"
_, err := NEP2Decrypt(s, p)
_, err := NEP2Decrypt(s, p, NEP2ScryptParams())
assert.Error(t, err)
// Valid base58, but not a NEP-2 format.
s = "KxhEDBQyyEFymvfJD96q8stMbJMbZUb6D1PmXqBWZDU2WvbvVs9o"
_, err = NEP2Decrypt(s, p)
_, err = NEP2Decrypt(s, p, NEP2ScryptParams())
assert.Error(t, err)
}

View file

@ -621,7 +621,7 @@ func TestSignAndPushP2PNotaryRequest(t *testing.T) {
w, err := wallet.NewWalletFromFile(notaryPath)
require.NoError(t, err)
ntr := w.Accounts[0]
err = ntr.Decrypt(notaryPass)
err = ntr.Decrypt(notaryPass, w.Scrypt)
require.NoError(t, err)
req.FallbackTransaction.Scripts[0] = transaction.Witness{
InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, ntr.PrivateKey().SignHashable(uint32(testchain.Network()), req.FallbackTransaction)...),

View file

@ -28,7 +28,7 @@ func (n *Notary) UpdateNotaryNodes(notaryNodes keys.PublicKeys) {
if acc.PrivateKey() != nil {
break
}
err := acc.Decrypt(n.Config.MainCfg.UnlockWallet.Password)
err := acc.Decrypt(n.Config.MainCfg.UnlockWallet.Password, n.wallet.Scrypt)
if err != nil {
n.Config.Log.Warn("can't unlock notary node account",
zap.String("address", address.Uint160ToString(acc.Contract.ScriptHash())),

View file

@ -33,7 +33,7 @@ func getTestNotary(t *testing.T, bc blockchainer.Blockchainer, walletPath, pass
w, err := wallet.NewWalletFromFile(walletPath)
require.NoError(t, err)
require.NoError(t, w.Accounts[0].Decrypt(pass))
require.NoError(t, w.Accounts[0].Decrypt(pass, w.Scrypt))
return w.Accounts[0], ntr, mp
}
@ -57,14 +57,14 @@ func TestUpdateNotaryNodes(t *testing.T) {
t.Run("good config password", func(t *testing.T) {
w, err := wallet.NewWalletFromFile("./testdata/notary1.json")
require.NoError(t, err)
require.NoError(t, w.Accounts[1].Decrypt("one"))
require.NoError(t, w.Accounts[1].Decrypt("one", w.Scrypt))
ntr.UpdateNotaryNodes(keys.PublicKeys{w.Accounts[1].PrivateKey().PublicKey()})
require.Equal(t, w.Accounts[1], ntr.currAccount)
})
t.Run("bad config password", func(t *testing.T) {
w, err := wallet.NewWalletFromFile("./testdata/notary1.json")
require.NoError(t, err)
require.NoError(t, w.Accounts[2].Decrypt("four"))
require.NoError(t, w.Accounts[2].Decrypt("four", w.Scrypt))
ntr.UpdateNotaryNodes(keys.PublicKeys{w.Accounts[2].PrivateKey().PublicKey()})
require.Nil(t, ntr.currAccount)
})

View file

@ -94,7 +94,7 @@ func NewNotary(cfg Config, net netmode.Magic, mp *mempool.Pool, onTransaction fu
haveAccount := false
for _, acc := range wallet.Accounts {
if err := acc.Decrypt(w.Password); err == nil {
if err := acc.Decrypt(w.Password, wallet.Scrypt); err == nil {
haveAccount = true
break
}

View file

@ -3,7 +3,7 @@
"accounts": [
{
"address": "Nbruchf1SGfar3sN4cPr1UG1bWqADrN5sh",
"key": "6PYRC8sNNB5rVx96ezh6Eefw8JcdQPRBfHx7hfe251m4bwHQnH2cZbcRk8",
"key": "6PYRC8sNMsyDRf8wVvQEpBJa5JXKbQ1SXGaXTvzW8u8mcpBTYs6E6kk1a6",
"label": "",
"contract": {
"script": "DCEDm5PmbOfVPmYXTSVW903XnOhhNBTsF9oDlVYusIH/ui1BVuezJw==",
@ -20,7 +20,7 @@
},
{
"address": "NiYvEoR2FTD8FmGXtg1WMhkaTS9A6VH7YV",
"key": "6PYMecvacj5qTSB771Q9k4wfqTRK4SXSQhmDsDAxZxBgEVJf4BsnrgrQYS",
"key": "6PYMecvacKctbTeqApPGuukViQ2bbvFG4qNNm7VJS4oGzTF3rpptsbDaKd",
"label": "",
"contract": {
"script": "DCEDHRWEIGXHCwUU2Fc7B0qrYPezXR0sfdEduRExyzIKVC9BVuezJw==",
@ -37,7 +37,7 @@
},
{
"address": "NcPWfiU7bJkUpBruEQcGRyo91bTWijcUXY",
"key": "6PYWH6sS2JVshBA5ijMAT1CtFbs9LcLuthYoR4eZMD8TyXShD1c2zLsfjC",
"key": "6PYWH6sS3VzGWq6K8oSoiRKDKSKkHHWhjHn9zQ8Qs2Zn9KboqWzseieXj2",
"label": "",
"contract": {
"script": "DCECmUfs/gqKHd3AdJm5+Ev6zkubV8pP8DZzgu8+t5WdphJBVuezJw==",
@ -54,9 +54,9 @@
}
],
"scrypt": {
"n": 16384,
"r": 8,
"p": 8
"n": 2,
"r": 1,
"p": 1
},
"extra": {
"Tokens": null

View file

@ -3,7 +3,7 @@
"accounts": [
{
"address": "NaVp3ZxwZWA84DRewRjnBLFstaeBuVMKwR",
"key": "6PYK1JEBNRL1jnqpD2Vct9sa5gjSfU5p42zavZBmWmKWR8oKvS5mPzcvqm",
"key": "6PYK1JEBNB9ndo7HmC9mXeNbdPi9NGb81C2tJrsTw4PBkcT64X6SQhnxHq",
"label": "",
"contract": {
"script": "DCECIcKj0GFdv4b1NZrw9X6zLNLWzmNKAxtw6olIMZxpPRRBVuezJw==",
@ -20,9 +20,9 @@
}
],
"scrypt": {
"n": 16384,
"r": 8,
"p": 8
"n": 2,
"r": 1,
"p": 1
},
"extra": {
"Tokens": null

View file

@ -33,7 +33,7 @@ func (o *Oracle) UpdateOracleNodes(oracleNodes keys.PublicKeys) {
if acc.PrivateKey() != nil {
break
}
err := acc.Decrypt(o.MainCfg.UnlockWallet.Password)
err := acc.Decrypt(o.MainCfg.UnlockWallet.Password, o.wallet.Scrypt)
if err != nil {
o.Log.Error("can't unlock account",
zap.String("address", address.Uint160ToString(acc.Contract.ScriptHash())),

View file

@ -130,7 +130,7 @@ func NewOracle(cfg Config) (*Oracle, error) {
haveAccount := false
for _, acc := range o.wallet.Accounts {
if err := acc.Decrypt(w.Password); err == nil {
if err := acc.Decrypt(w.Password, o.wallet.Scrypt); err == nil {
haveAccount = true
break
}

View file

@ -85,7 +85,7 @@ func New(cfg config.StateRoot, log *zap.Logger, bc blockchainer.Blockchainer, cb
haveAccount := false
for _, acc := range s.wallet.Accounts {
if err := acc.Decrypt(w.Password); err == nil {
if err := acc.Decrypt(w.Password, s.wallet.Scrypt); err == nil {
haveAccount = true
break
}
@ -141,7 +141,7 @@ func (s *service) updateValidators(height uint32, pubs keys.PublicKeys) {
s.acc = nil
for i := range pubs {
if acc := s.wallet.GetAccount(pubs[i].GetScriptHash()); acc != nil {
err := acc.Decrypt(s.MainCfg.UnlockWallet.Password)
err := acc.Decrypt(s.MainCfg.UnlockWallet.Password, s.wallet.Scrypt)
if err == nil {
s.acc = acc
s.accHeight = height

View file

@ -119,13 +119,13 @@ func (a *Account) GetVerificationScript() []byte {
// Decrypt decrypts the EncryptedWIF with the given passphrase returning error
// if anything goes wrong.
func (a *Account) Decrypt(passphrase string) error {
func (a *Account) Decrypt(passphrase string, scrypt keys.ScryptParams) error {
var err error
if a.EncryptedWIF == "" {
return errors.New("no encrypted wif in the account")
}
a.privateKey, err = keys.NEP2Decrypt(a.EncryptedWIF, passphrase)
a.privateKey, err = keys.NEP2Decrypt(a.EncryptedWIF, passphrase, scrypt)
if err != nil {
return err
}
@ -138,8 +138,8 @@ func (a *Account) Decrypt(passphrase string) error {
// Encrypt encrypts the wallet's PrivateKey with the given passphrase
// under the NEP-2 standard.
func (a *Account) Encrypt(passphrase string) error {
wif, err := keys.NEP2Encrypt(a.privateKey, passphrase)
func (a *Account) Encrypt(passphrase string, scrypt keys.ScryptParams) error {
wif, err := keys.NEP2Encrypt(a.privateKey, passphrase, scrypt)
if err != nil {
return err
}
@ -162,8 +162,8 @@ func NewAccountFromWIF(wif string) (*Account, error) {
}
// NewAccountFromEncryptedWIF creates a new Account from the given encrypted WIF.
func NewAccountFromEncryptedWIF(wif string, pass string) (*Account, error) {
priv, err := keys.NEP2Decrypt(wif, pass)
func NewAccountFromEncryptedWIF(wif string, pass string, scrypt keys.ScryptParams) (*Account, error) {
priv, err := keys.NEP2Decrypt(wif, pass, scrypt)
if err != nil {
return nil, err
}

View file

@ -22,7 +22,7 @@ func TestDecryptAccount(t *testing.T) {
for _, testCase := range keytestcases.Arr {
acc := &Account{EncryptedWIF: testCase.EncryptedWif}
assert.Nil(t, acc.PrivateKey())
err := acc.Decrypt(testCase.Passphrase)
err := acc.Decrypt(testCase.Passphrase, keys.NEP2ScryptParams())
if testCase.Invalid {
assert.Error(t, err)
continue
@ -34,7 +34,7 @@ func TestDecryptAccount(t *testing.T) {
}
// No encrypted key.
acc := &Account{}
require.Error(t, acc.Decrypt("qwerty"))
require.Error(t, acc.Decrypt("qwerty", keys.NEP2ScryptParams()))
}
func TestNewFromWif(t *testing.T) {
@ -52,7 +52,7 @@ func TestNewFromWif(t *testing.T) {
func TestNewAccountFromEncryptedWIF(t *testing.T) {
for _, tc := range keytestcases.Arr {
acc, err := NewAccountFromEncryptedWIF(tc.EncryptedWif, tc.Passphrase)
acc, err := NewAccountFromEncryptedWIF(tc.EncryptedWif, tc.Passphrase, keys.NEP2ScryptParams())
if tc.Invalid {
assert.Error(t, err)
continue

View file

@ -1,11 +1,17 @@
package wallet
import (
"encoding/json"
"fmt"
"io/ioutil"
"path"
"testing"
"github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
"github.com/stretchr/testify/require"
)
@ -37,9 +43,13 @@ func getKeys(t *testing.T) []*keys.PublicKey {
}
func getAccount(t *testing.T, wif, pass string) *Account {
return getAccountWithScrypt(t, wif, pass, keys.NEP2ScryptParams())
}
func getAccountWithScrypt(t *testing.T, wif, pass string, scrypt keys.ScryptParams) *Account {
acc, err := NewAccountFromWIF(wif)
require.NoError(t, err)
require.NoError(t, acc.Encrypt(pass))
require.NoError(t, acc.Encrypt(pass, scrypt))
return acc
}
@ -114,12 +124,13 @@ func TestRegenerateNotaryWallets(t *testing.T) {
acc4WIF = "L1ioz93TNt6Nu1aoMpZQ4zgdtgC8ZvJMC6pyHFkrovdR3SFwbn6n"
)
acc1 := getAccount(t, acc1WIF, "one")
acc2 := getAccount(t, acc2WIF, "one")
acc3 := getAccount(t, acc3WIF, "four")
scryptParams := keys.ScryptParams{N: 2, R: 1, P: 1}
acc1 := getAccountWithScrypt(t, acc1WIF, "one", scryptParams)
acc2 := getAccountWithScrypt(t, acc2WIF, "one", scryptParams)
acc3 := getAccountWithScrypt(t, acc3WIF, "four", scryptParams)
createWallet(t, path.Join(walletDir, "notary1.json"), acc1, acc2, acc3)
acc4 := getAccount(t, acc4WIF, "two")
acc4 := getAccountWithScrypt(t, acc4WIF, "two", scryptParams)
createWallet(t, path.Join(walletDir, "notary2.json"), acc4)
}
@ -163,7 +174,7 @@ func TestRegenerateCLITestwallet(t *testing.T) {
accWIF = "L23LrQNWELytYLvb5c6dXBDdF2DNPL9RRNWPqppv3roxacSnn8CN"
)
acc := getAccount(t, accWIF, "testpass")
acc := getAccountWithScrypt(t, accWIF, "testpass", keys.ScryptParams{N: 2, R: 1, P: 1})
acc.Label = "kek"
createWallet(t, walletPath, acc)
}
@ -184,9 +195,53 @@ func TestRegenerateCLITestwallet_NEO3(t *testing.T) {
func createWallet(t *testing.T, path string, accs ...*Account) {
w, err := NewWallet(path)
require.NoError(t, err)
if len(accs) == 0 {
t.Fatal("provide at least 1 account")
}
for _, acc := range accs {
w.AddAccount(acc)
}
require.NoError(t, w.savePretty())
w.Close()
}
func TestRegenerateCLIWallet1_solo(t *testing.T) {
if !regenerate {
return
}
const (
walletPath = "../../cli/testdata/wallet1_solo.json"
verifyWIF = "L3W8gi36Y3KPqyR54VJaE1agH9yPvW2hALNZy1BerDwWce9P9xEy"
verifyNEFPath = "../../cli/testdata/verify.nef"
verifyManifestPath = "../../cli/testdata/verify.manifest.json"
)
scrypt := keys.ScryptParams{N: 2, R: 1, P: 1}
wif := privnetWIFs[0]
acc1 := getAccountWithScrypt(t, wif, "one", scrypt)
acc1.Default = true
acc2 := getAccountWithScrypt(t, wif, "one", scrypt)
require.NoError(t, acc2.ConvertMultisig(3, getKeys(t)))
acc3 := getAccountWithScrypt(t, wif, "one", scrypt)
require.NoError(t, acc3.ConvertMultisig(1, keys.PublicKeys{getKeys(t)[0]}))
acc4 := getAccountWithScrypt(t, verifyWIF, "pass", scrypt) // deployed verify.go contract
f, err := ioutil.ReadFile(verifyNEFPath)
require.NoError(t, err)
nefFile, err := nef.FileFromBytes(f)
require.NoError(t, err)
manifestBytes, err := ioutil.ReadFile(verifyManifestPath)
require.NoError(t, err)
m := &manifest.Manifest{}
require.NoError(t, json.Unmarshal(manifestBytes, m))
hash := state.CreateContractHash(acc3.PrivateKey().GetScriptHash(), nefFile.Checksum, m.Name)
acc4.Address = address.Uint160ToString(hash)
acc4.Contract = &Contract{
Script: nefFile.Script,
Deployed: true,
Parameters: []ContractParam{},
}
acc4.Label = "verify"
createWallet(t, walletPath, acc1, acc2, acc3, acc4)
}

View file

@ -92,7 +92,7 @@ func (w *Wallet) CreateAccount(name, passphrase string) error {
return err
}
acc.Label = name
if err := acc.Encrypt(passphrase); err != nil {
if err := acc.Encrypt(passphrase, w.Scrypt); err != nil {
return err
}
w.AddAccount(acc)

View file

@ -108,7 +108,7 @@ func TestSave(t *testing.T) {
w2, err := NewWalletFromFile(openedWallet.path)
require.NoError(t, err)
require.Equal(t, 2, len(w2.Accounts))
require.NoError(t, w2.Accounts[1].Decrypt("pass"))
require.NoError(t, w2.Accounts[1].Decrypt("pass", w2.Scrypt))
require.Equal(t, openedWallet.Accounts, w2.Accounts)
})
}
@ -207,7 +207,7 @@ func TestWalletForExamples(t *testing.T) {
require.NoError(t, err)
require.Equal(t, 1, len(w.Accounts))
require.Equal(t, accountLabel, w.Accounts[0].Label)
require.NoError(t, w.Accounts[0].Decrypt(walletPass))
require.NoError(t, w.Accounts[0].Decrypt(walletPass, w.Scrypt))
// we need to keep the owner of the example contracts the same as the wallet account
require.Equal(t, "NbrUYaZgyhSkNoRo9ugRyEMdUZxrhkNaWB", w.Accounts[0].Address, "need to change `owner` in the example contracts")