diff --git a/cli/nep11_test.go b/cli/nep11_test.go index b61350c03..a1d967cc9 100644 --- a/cli/nep11_test.go +++ b/cli/nep11_test.go @@ -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) diff --git a/cli/smartcontract/smart_contract.go b/cli/smartcontract/smart_contract.go index 2b9d2c557..89e80a5b6 100644 --- a/cli/smartcontract/smart_contract.go +++ b/cli/smartcontract/smart_contract.go @@ -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) } diff --git a/cli/testdata/testwallet.json b/cli/testdata/testwallet.json index 823445338..d68c14062 100644 --- a/cli/testdata/testwallet.json +++ b/cli/testdata/testwallet.json @@ -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 diff --git a/cli/testdata/wallet1_solo.json b/cli/testdata/wallet1_solo.json index 6cc20c33b..1e51ca921 100644 --- a/cli/testdata/wallet1_solo.json +++ b/cli/testdata/wallet1_solo.json @@ -1,84 +1,84 @@ { - "extra" : { - "Tokens" : null - }, - "accounts" : [ + "version": "3.0", + "accounts": [ { - "label" : "", - "key" : "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY", - "lock" : false, - "isDefault" : true, - "contract" : { - "script" : "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcJBVuezJw==", - "deployed" : false, - "parameters" : [ + "address": "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn", + "key": "6PYM8VdX3hY4B51UJxmm8D41RQMbpJT8aYHibyQ67gjkUPmvQgu51Y5UQR", + "label": "", + "contract": { + "script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcJBVuezJw==", + "parameters": [ { - "name" : "parameter0", - "type" : "Signature" - } - ] - }, - "address" : "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn" - }, - { - "lock" : false, - "isDefault" : false, - "contract" : { - "script" : "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEGe0Nw6", - "parameters" : [ - { - "name" : "parameter0", - "type" : "Signature" - }, - { - "name" : "parameter1", - "type" : "Signature" - }, - { - "type" : "Signature", - "name" : "parameter2" + "name": "parameter0", + "type": "Signature" } ], - "deployed" : false + "deployed": false }, - "address" : "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq", - "label" : "", - "key" : "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY" + "lock": false, + "isDefault": true }, { - "lock" : false, - "isDefault" : false, - "contract" : { - "parameters" : [ + "address": "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq", + "key": "6PYM8VdX3hY4B51UJxmm8D41RQMbpJT8aYHibyQ67gjkUPmvQgu51Y5UQR", + "label": "", + "contract": { + "script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEGe0Nw6", + "parameters": [ { - "name" : "parameter0", - "type" : "Signature" + "name": "parameter0", + "type": "Signature" + }, + { + "name": "parameter1", + "type": "Signature" + }, + { + "name": "parameter2", + "type": "Signature" } ], - "deployed" : false, - "script" : "EQwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CEUGe0Nw6" + "deployed": false }, - "address" : "NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP", - "label" : "", - "key" : "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY" + "lock": false, + "isDefault": false }, { - "address" : "NU4CTk9H2fgNCuC3ZPqX4LjUX3MHt3Rh6p", - "contract" : { - "script" : "EdsgQFcAA0BXAQR4eXp7VBTAcAwOT25ORVAxMVBheW1lbnRoUEGVAW9hIUA=", - "parameters" : [], - "deployed" : true + "address": "NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP", + "key": "6PYM8VdX3hY4B51UJxmm8D41RQMbpJT8aYHibyQ67gjkUPmvQgu51Y5UQR", + "label": "", + "contract": { + "script": "EQwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CEUGe0Nw6", + "parameters": [ + { + "name": "parameter0", + "type": "Signature" + } + ], + "deployed": false }, - "lock" : false, - "isDefault" : false, - "key" : "6PYSATFzuRXXUeq7tMDyA1AGxWdVcm7ftbkqtGBt69WJBapT1tkwjp1zpx", - "label" : "acc" + "lock": false, + "isDefault": false + }, + { + "address": "NU4CTk9H2fgNCuC3ZPqX4LjUX3MHt3Rh6p", + "key": "6PYSATFztBa3CHjSR6sLAKungUEAbQUCVE16KzmaQQ38gLeYGZ9Knd5mGv", + "label": "verify", + "contract": { + "script": "EdsgQFcAA0BXAQR4eXp7VBTAcAwOT25ORVAxMVBheW1lbnRoUEGVAW9hIUA=", + "parameters": [], + "deployed": true + }, + "lock": false, + "isDefault": false } ], - "version" : "3.0", - "scrypt" : { - "r" : 8, - "n" : 16384, - "p" : 8 + "scrypt": { + "n": 2, + "r": 1, + "p": 1 + }, + "extra": { + "Tokens": null } } diff --git a/cli/wallet/legacy.go b/cli/wallet/legacy.go index bace1cef9..38ac37fef 100644 --- a/cli/wallet/legacy.go +++ b/cli/wallet/legacy.go @@ -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 ( diff --git a/cli/wallet/validator.go b/cli/wallet/validator.go index c94a9c648..468e4a259 100644 --- a/cli/wallet/validator.go +++ b/cli/wallet/validator.go @@ -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 diff --git a/cli/wallet/wallet.go b/cli/wallet/wallet.go index 89df95be0..5b44b51b0 100644 --- a/cli/wallet/wallet.go +++ b/cli/wallet/wallet.go @@ -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 } diff --git a/cli/wallet_test.go b/cli/wallet_test.go index b21ac285e..2bd1298ce 100644 --- a/cli/wallet_test.go +++ b/cli/wallet_test.go @@ -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)) }) diff --git a/pkg/consensus/consensus.go b/pkg/consensus/consensus.go index 3321bb8c0..ee2cababd 100644 --- a/pkg/consensus/consensus.go +++ b/pkg/consensus/consensus.go @@ -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 diff --git a/pkg/core/helper_test.go b/pkg/core/helper_test.go index 227dce033..6ae741619 100644 --- a/pkg/core/helper_test.go +++ b/pkg/core/helper_test.go @@ -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())) diff --git a/pkg/core/notary_test.go b/pkg/core/notary_test.go index ebdea6f0d..c0089d809 100644 --- a/pkg/core/notary_test.go +++ b/pkg/core/notary_test.go @@ -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 } diff --git a/pkg/core/oracle_test.go b/pkg/core/oracle_test.go index ea266a63b..a9a263c6c 100644 --- a/pkg/core/oracle_test.go +++ b/pkg/core/oracle_test.go @@ -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 } diff --git a/pkg/core/stateroot_test.go b/pkg/core/stateroot_test.go index 39df0e959..c9c3ba4c1 100644 --- a/pkg/core/stateroot_test.go +++ b/pkg/core/stateroot_test.go @@ -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() diff --git a/pkg/crypto/keys/nep2.go b/pkg/crypto/keys/nep2.go index 505f13dd6..547c6c7c0 100644 --- a/pkg/crypto/keys/nep2.go +++ b/pkg/crypto/keys/nep2.go @@ -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 } diff --git a/pkg/crypto/keys/nep2_test.go b/pkg/crypto/keys/nep2_test.go index 78de1f5c6..44755281e 100644 --- a/pkg/crypto/keys/nep2_test.go +++ b/pkg/crypto/keys/nep2_test.go @@ -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) } diff --git a/pkg/rpc/server/client_test.go b/pkg/rpc/server/client_test.go index d06e02fd1..606750ef0 100644 --- a/pkg/rpc/server/client_test.go +++ b/pkg/rpc/server/client_test.go @@ -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)...), diff --git a/pkg/services/notary/node.go b/pkg/services/notary/node.go index 15df2a5e1..ea179baaa 100644 --- a/pkg/services/notary/node.go +++ b/pkg/services/notary/node.go @@ -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())), diff --git a/pkg/services/notary/node_test.go b/pkg/services/notary/node_test.go index 4c30f0b2c..4e69eb246 100644 --- a/pkg/services/notary/node_test.go +++ b/pkg/services/notary/node_test.go @@ -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) }) diff --git a/pkg/services/notary/notary.go b/pkg/services/notary/notary.go index 8ba2f2486..2e5c35be6 100644 --- a/pkg/services/notary/notary.go +++ b/pkg/services/notary/notary.go @@ -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 } diff --git a/pkg/services/notary/testdata/notary1.json b/pkg/services/notary/testdata/notary1.json index 264db186d..74f2bc13b 100644 --- a/pkg/services/notary/testdata/notary1.json +++ b/pkg/services/notary/testdata/notary1.json @@ -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 diff --git a/pkg/services/notary/testdata/notary2.json b/pkg/services/notary/testdata/notary2.json index a504340c7..dcdd214d4 100644 --- a/pkg/services/notary/testdata/notary2.json +++ b/pkg/services/notary/testdata/notary2.json @@ -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 diff --git a/pkg/services/oracle/nodes.go b/pkg/services/oracle/nodes.go index 87acd4a02..b20b806c0 100644 --- a/pkg/services/oracle/nodes.go +++ b/pkg/services/oracle/nodes.go @@ -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())), diff --git a/pkg/services/oracle/oracle.go b/pkg/services/oracle/oracle.go index be8b80db9..8369add20 100644 --- a/pkg/services/oracle/oracle.go +++ b/pkg/services/oracle/oracle.go @@ -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 } diff --git a/pkg/services/stateroot/service.go b/pkg/services/stateroot/service.go index 3b01a560e..6716d4b68 100644 --- a/pkg/services/stateroot/service.go +++ b/pkg/services/stateroot/service.go @@ -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 diff --git a/pkg/wallet/account.go b/pkg/wallet/account.go index fc624a683..160bc63b2 100644 --- a/pkg/wallet/account.go +++ b/pkg/wallet/account.go @@ -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 } diff --git a/pkg/wallet/account_test.go b/pkg/wallet/account_test.go index 19c74e022..23333d066 100644 --- a/pkg/wallet/account_test.go +++ b/pkg/wallet/account_test.go @@ -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 diff --git a/pkg/wallet/regenerate_test.go b/pkg/wallet/regenerate_test.go index 4332aaffa..28a4e6fc7 100644 --- a/pkg/wallet/regenerate_test.go +++ b/pkg/wallet/regenerate_test.go @@ -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) +} diff --git a/pkg/wallet/wallet.go b/pkg/wallet/wallet.go index e365849fb..c42e65ef1 100644 --- a/pkg/wallet/wallet.go +++ b/pkg/wallet/wallet.go @@ -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) diff --git a/pkg/wallet/wallet_test.go b/pkg/wallet/wallet_test.go index 03aded3fb..ccdf081b4 100644 --- a/pkg/wallet/wallet_test.go +++ b/pkg/wallet/wallet_test.go @@ -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")