cosmos-sdk/crypto/keyring/keyring_test.go

1165 lines
35 KiB
Go
Raw Normal View History

package keyring
import (
"encoding/hex"
"fmt"
"strings"
"testing"
"github.com/99designs/keyring"
bip39 "github.com/cosmos/go-bip39"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/crypto"
"github.com/cosmos/cosmos-sdk/crypto/hd"
Migrate BaseAccount PubKey to use Any (#7268) * WIP on BaseAccount protobuf pub_key * WIP on BaseAccount.PubKey * WIP on BaseAccount pub key * Update PubKey * Update Account * Docs * WIP on protobuf keys * Use Type() and Bytes() in sr25519 pub key Equals * Add tests * Add few more tests * Update other pub/priv key types Equals * Fix PrivKey's Sign method * Rename variables in tests * Fix infinite recursive calls * Use tm ed25519 keys * Add Sign and VerifySignature tests * Remove ed25519 and sr25519 references * proto linting * Add proto crypto file * Implement some of the new multisig proto type methods * Add tests for MultisigThresholdPubKey * Add tests for pubkey pb/amino conversion functions * Move crypto types.go and register new proto pubkeys * Add missing pointer ref * Address review comments * panic in MultisigThresholdPubKey VerifySignature * Fix compile errors * Remove pk conversion in ante handler * Use internal crypto.PubKey in multisig * Add tests for MultisigThresholdPubKey VerifyMultisignature * Only keep LegacyAminoMultisigThresholdPubKey and move to proto keys to v1 * Remove conversion functions and introduce internal PubKey type * Override Amino marshaling for proto pubkeys * Merge master * Make proto-gen * Start removal of old PubKeyMultisigThreshold references * Fix tests * Fix solomachine * Fix ante handler tests * Pull latest go-amino * Remove ed25519 * Remove old secp256k1 PubKey and PrivKey * Uncomment test case * Fix linting issues * More linting * Revert tests keys values * Add Amino overrides to proto keys * Add pubkey test * Fix tests * Use threshold isntead of K * Standardize Type * Revert standardize types commit * Fix build * Fix lint * Fix lint * Add comment * Register crypto.PubKey * Add empty key in BuildSimTx * Simplify proto names * Unpack interfaces for signing desc * Fix IBC tests? * Format proto * Use secp256k1 in ibc * Fixed merge issues * Uncomment tests * Update x/ibc/testing/solomachine.go * UnpackInterfaces for solomachine types * Remove old multisig * Add amino marshal for multisig * Fix lint * Correctly register amino * One test left! * Remove old struct * Fix test * Fix test * Unpack into tmcrypto * Remove old threshold pubkey tests * Fix register amino * Fix lint * Use sdk crypto PubKey in multisig UnpackInterfaces * Potential fix? * Register LegacyAminoPubKey * Register our own PubKey * Register tmcrypto PubKey * Register both PubKeys * Register interfaces in test * Refactor fiels * Add comments * Remove old cosmos-sdk/crypto/keys reference * Use anil's suggestion * Add norace back * Use our own ed25519 * Fix pubkey types * Fix network tests * Fix more tests * Make ibc work? * Use TM pubkey in NewValidator * Fix lint * Put interface in tpyes * rerun CI * Better name register * Remove stray code * Add ed25519 tests * Check nil * Correct interface impl assert * rerun CI * Add fix for Bech32 * Address comments * FIx lint * Add tests for solomachine unpack interfaces * Fix query tx by hash * Better name in amino register * Fix lint * Add back ed25519 test (fixes #7352) * go mod tidy * Fix merge issues * Sort import * Add test for backwards-compatibility * Fix tests * Fix merge issue * Update client/context.go Co-authored-by: Cory <cjlevinson@gmail.com> * Update types/address.go Co-authored-by: Cory <cjlevinson@gmail.com> * Address feedback * Add comment * Fix BaseAccount SetPubKey and address further comments * Lint * Remove unnecessary use of copy in getPubKeyFromString * Update comment Co-authored-by: Aaron Craelius <aaronc@users.noreply.github.com> Co-authored-by: Aaron Craelius <aaron@regen.network> Co-authored-by: Amaury Martiny <amaury.martiny@protonmail.com> Co-authored-by: Alexander Bezobchuk <alexanderbez@users.noreply.github.com> Co-authored-by: colin axnér <25233464+colin-axner@users.noreply.github.com> Co-authored-by: Cory <cjlevinson@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2020-09-25 01:41:16 -07:00
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
Remove old PubKeyMultisigThreshold (#7284) * WIP on protobuf keys * Use Type() and Bytes() in sr25519 pub key Equals * Add tests * Add few more tests * Update other pub/priv key types Equals * Fix PrivKey's Sign method * Rename variables in tests * Fix infinite recursive calls * Use tm ed25519 keys * Add Sign and VerifySignature tests * Remove ed25519 and sr25519 references * proto linting * Add proto crypto file * Implement some of the new multisig proto type methods * Add tests for MultisigThresholdPubKey * Add tests for pubkey pb/amino conversion functions * Move crypto types.go and register new proto pubkeys * Add missing pointer ref * Address review comments * panic in MultisigThresholdPubKey VerifySignature * Use internal crypto.PubKey in multisig * Add tests for MultisigThresholdPubKey VerifyMultisignature * Only keep LegacyAminoMultisigThresholdPubKey and move to proto keys to v1 * Remove conversion functions and introduce internal PubKey type * Start removal of old PubKeyMultisigThreshold references * Remove old secp256k1 PubKey and PrivKey * Uncomment test case * Fix linting issues * More linting * Revert tests keys values * Add Amino overrides to proto keys * Add pubkey test * Fix tests * Use threshold isntead of K * Standardize Type * Revert standardize types commit * Add comment * Simplify proto names * Fixed merge issues * Uncomment tests * Remove old multisig * Add amino marshal for multisig * Fix lint * Correctly register amino * One test left! * Remove old struct * Fix test * Fix test * Unpack into tmcrypto * Remove old threshold pubkey tests * Fix register amino * Fix lint * Use sdk crypto PubKey in multisig UnpackInterfaces * Potential fix? * Use anil's suggestion Co-authored-by: Aaron Craelius <aaronc@users.noreply.github.com> Co-authored-by: Amaury Martiny <amaury.martiny@protonmail.com> Co-authored-by: Alexander Bezobchuk <alexanderbez@users.noreply.github.com> Co-authored-by: Alessio Treglia <alessio@tendermint.com>
2020-09-18 02:40:39 -07:00
"github.com/cosmos/cosmos-sdk/crypto/keys/multisig"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
"github.com/cosmos/cosmos-sdk/crypto/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)
const (
someKey = "theKey"
theID = "theID"
otherID = "otherID"
)
func init() {
crypto.BcryptSecurityParameter = 1
}
func TestNewKeyring(t *testing.T) {
dir := t.TempDir()
mockIn := strings.NewReader("")
kr, err := New("cosmos", BackendFile, dir, mockIn)
require.NoError(t, err)
nilKr, err := New("cosmos", "fuzzy", dir, mockIn)
require.Error(t, err)
require.Nil(t, nilKr)
require.Equal(t, "unknown keyring backend fuzzy", err.Error())
mockIn.Reset("password\npassword\n")
info, _, err := kr.NewMnemonic("foo", English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
require.NoError(t, err)
require.Equal(t, "foo", info.GetName())
}
func TestKeyManagementKeyRing(t *testing.T) {
kb, err := New("keybasename", "test", t.TempDir(), nil)
require.NoError(t, err)
algo := hd.Secp256k1
n1, n2, n3 := "personal", "business", "other"
// Check empty state
l, err := kb.List()
require.Nil(t, err)
require.Empty(t, l)
_, _, err = kb.NewMnemonic(n1, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, notSupportedAlgo{})
require.Error(t, err, "ed25519 keys are currently not supported by keybase")
// create some keys
_, err = kb.Key(n1)
require.Error(t, err)
i, _, err := kb.NewMnemonic(n1, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, algo)
require.NoError(t, err)
require.Equal(t, n1, i.GetName())
_, _, err = kb.NewMnemonic(n2, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, algo)
require.NoError(t, err)
// we can get these keys
i2, err := kb.Key(n2)
require.NoError(t, err)
_, err = kb.Key(n3)
require.NotNil(t, err)
_, err = kb.KeyByAddress(accAddr(i2))
require.NoError(t, err)
addr, err := sdk.AccAddressFromBech32("cosmos1yq8lgssgxlx9smjhes6ryjasmqmd3ts2559g0t")
require.NoError(t, err)
_, err = kb.KeyByAddress(addr)
require.NotNil(t, err)
// list shows them in order
keyS, err := kb.List()
require.NoError(t, err)
require.Equal(t, 2, len(keyS))
// note these are in alphabetical order
require.Equal(t, n2, keyS[0].GetName())
require.Equal(t, n1, keyS[1].GetName())
require.Equal(t, i2.GetPubKey(), keyS[0].GetPubKey())
// deleting a key removes it
err = kb.Delete("bad name")
require.NotNil(t, err)
err = kb.Delete(n1)
require.NoError(t, err)
keyS, err = kb.List()
require.NoError(t, err)
require.Equal(t, 1, len(keyS))
_, err = kb.Key(n1)
require.Error(t, err)
// create an offline key
o1 := "offline"
priv1 := ed25519.GenPrivKey()
pub1 := priv1.PubKey()
i, err = kb.SavePubKey(o1, pub1, hd.Ed25519Type)
require.Nil(t, err)
require.Equal(t, pub1, i.GetPubKey())
require.Equal(t, o1, i.GetName())
keyS, err = kb.List()
require.NoError(t, err)
require.Equal(t, 2, len(keyS))
// delete the offline key
err = kb.Delete(o1)
require.NoError(t, err)
keyS, err = kb.List()
require.NoError(t, err)
require.Equal(t, 1, len(keyS))
// addr cache gets nuked - and test skip flag
require.NoError(t, kb.Delete(n2))
}
func TestSignVerifyKeyRing(t *testing.T) {
dir := t.TempDir()
kb, err := New("keybasename", "test", dir, nil)
require.NoError(t, err)
algo := hd.Secp256k1
n1, n2, n3 := "some dude", "a dudette", "dude-ish"
// create two users and get their info
i1, _, err := kb.NewMnemonic(n1, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, algo)
require.Nil(t, err)
i2, _, err := kb.NewMnemonic(n2, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, algo)
require.Nil(t, err)
// let's try to sign some messages
d1 := []byte("my first message")
d2 := []byte("some other important info!")
d3 := []byte("feels like I forgot something...")
// try signing both data with both ..
s11, pub1, err := kb.Sign(n1, d1)
require.Nil(t, err)
require.Equal(t, i1.GetPubKey(), pub1)
s12, pub1, err := kb.Sign(n1, d2)
require.Nil(t, err)
require.Equal(t, i1.GetPubKey(), pub1)
s21, pub2, err := kb.Sign(n2, d1)
require.Nil(t, err)
require.Equal(t, i2.GetPubKey(), pub2)
s22, pub2, err := kb.Sign(n2, d2)
require.Nil(t, err)
require.Equal(t, i2.GetPubKey(), pub2)
// let's try to validate and make sure it only works when everything is proper
cases := []struct {
key types.PubKey
data []byte
sig []byte
valid bool
}{
// proper matches
{i1.GetPubKey(), d1, s11, true},
// change data, pubkey, or signature leads to fail
{i1.GetPubKey(), d2, s11, false},
{i2.GetPubKey(), d1, s11, false},
{i1.GetPubKey(), d1, s21, false},
// make sure other successes
{i1.GetPubKey(), d2, s12, true},
{i2.GetPubKey(), d1, s21, true},
{i2.GetPubKey(), d2, s22, true},
}
for i, tc := range cases {
valid := tc.key.VerifySignature(tc.data, tc.sig)
require.Equal(t, tc.valid, valid, "%d", i)
}
// Now try to sign data with a secret-less key
// Import a public key
armor, err := kb.ExportPubKeyArmor(n2)
require.NoError(t, err)
require.NoError(t, kb.Delete(n2))
require.NoError(t, kb.ImportPubKey(n3, armor))
i3, err := kb.Key(n3)
require.NoError(t, err)
require.Equal(t, i3.GetName(), n3)
_, _, err = kb.Sign(n3, d3)
require.Error(t, err)
require.Equal(t, "cannot sign with offline keys", err.Error())
}
func TestExportImportKeyRing(t *testing.T) {
kb, err := New("keybasename", "test", t.TempDir(), nil)
require.NoError(t, err)
info, _, err := kb.NewMnemonic("john", English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
require.NoError(t, err)
require.Equal(t, info.GetName(), "john")
john, err := kb.Key("john")
require.NoError(t, err)
require.Equal(t, info.GetName(), "john")
johnAddr := info.GetPubKey().Address()
armor, err := kb.ExportPrivKeyArmor("john", "apassphrase")
require.NoError(t, err)
err = kb.Delete("john")
require.NoError(t, err)
err = kb.ImportPrivKey("john2", armor, "apassphrase")
require.NoError(t, err)
john2, err := kb.Key("john2")
require.NoError(t, err)
require.Equal(t, john.GetPubKey().Address(), johnAddr)
require.Equal(t, john.GetName(), "john")
require.Equal(t, john.GetAddress(), john2.GetAddress())
require.Equal(t, john.GetAlgo(), john2.GetAlgo())
require.Equal(t, john.GetPubKey(), john2.GetPubKey())
require.Equal(t, john.GetType(), john2.GetType())
}
func TestExportImportPubKeyKeyRing(t *testing.T) {
kb, err := New("keybasename", "test", t.TempDir(), nil)
require.NoError(t, err)
algo := hd.Secp256k1
// CreateMnemonic a private-public key pair and ensure consistency
info, _, err := kb.NewMnemonic("john", English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, algo)
require.Nil(t, err)
require.NotEqual(t, info, "")
require.Equal(t, info.GetName(), "john")
addr := info.GetPubKey().Address()
john, err := kb.Key("john")
require.NoError(t, err)
require.Equal(t, john.GetName(), "john")
require.Equal(t, john.GetPubKey().Address(), addr)
// Export the public key only
armor, err := kb.ExportPubKeyArmor("john")
require.NoError(t, err)
err = kb.Delete("john")
require.NoError(t, err)
// Import it under a different name
err = kb.ImportPubKey("john-pubkey-only", armor)
require.NoError(t, err)
// Ensure consistency
john2, err := kb.Key("john-pubkey-only")
require.NoError(t, err)
// Compare the public keys
require.True(t, john.GetPubKey().Equals(john2.GetPubKey()))
// Ensure keys cannot be overwritten
err = kb.ImportPubKey("john-pubkey-only", armor)
require.NotNil(t, err)
}
func TestAdvancedKeyManagementKeyRing(t *testing.T) {
dir := t.TempDir()
kb, err := New("keybasename", "test", dir, nil)
require.NoError(t, err)
algo := hd.Secp256k1
n1, n2 := "old-name", "new name"
// make sure key works with initial password
_, _, err = kb.NewMnemonic(n1, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, algo)
require.Nil(t, err, "%+v", err)
_, err = kb.ExportPubKeyArmor(n1 + ".notreal")
require.NotNil(t, err)
_, err = kb.ExportPubKeyArmor(" " + n1)
require.NotNil(t, err)
_, err = kb.ExportPubKeyArmor(n1 + " ")
require.NotNil(t, err)
_, err = kb.ExportPubKeyArmor("")
require.NotNil(t, err)
exported, err := kb.ExportPubKeyArmor(n1)
require.Nil(t, err, "%+v", err)
err = kb.Delete(n1)
require.NoError(t, err)
// import succeeds
err = kb.ImportPubKey(n2, exported)
require.NoError(t, err)
// second import fails
err = kb.ImportPubKey(n2, exported)
require.NotNil(t, err)
}
func TestSeedPhraseKeyRing(t *testing.T) {
dir := t.TempDir()
kb, err := New("keybasename", "test", dir, nil)
require.NoError(t, err)
algo := hd.Secp256k1
n1, n2 := "lost-key", "found-again"
// make sure key works with initial password
info, mnemonic, err := kb.NewMnemonic(n1, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, algo)
require.Nil(t, err, "%+v", err)
require.Equal(t, n1, info.GetName())
require.NotEmpty(t, mnemonic)
// now, let us delete this key
err = kb.Delete(n1)
require.Nil(t, err, "%+v", err)
_, err = kb.Key(n1)
require.NotNil(t, err)
// let us re-create it from the mnemonic-phrase
params := *hd.NewFundraiserParams(0, sdk.CoinType, 0)
hdPath := params.String()
newInfo, err := kb.NewAccount(n2, mnemonic, DefaultBIP39Passphrase, hdPath, hd.Secp256k1)
require.NoError(t, err)
require.Equal(t, n2, newInfo.GetName())
require.Equal(t, info.GetPubKey().Address(), newInfo.GetPubKey().Address())
require.Equal(t, info.GetPubKey(), newInfo.GetPubKey())
}
func TestKeyringKeybaseExportImportPrivKey(t *testing.T) {
kb, err := New("keybasename", "test", t.TempDir(), nil)
require.NoError(t, err)
_, _, err = kb.NewMnemonic("john", English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
require.NoError(t, err)
keystr, err := kb.ExportPrivKeyArmor("john", "somepassword")
require.NoError(t, err)
require.NotEmpty(t, keystr)
err = kb.Delete("john")
require.NoError(t, err)
// try import the key - wrong password
err = kb.ImportPrivKey("john2", keystr, "bad pass")
require.Equal(t, "failed to decrypt private key: ciphertext decryption failed", err.Error())
// try import the key with the correct password
require.NoError(t, kb.ImportPrivKey("john2", keystr, "somepassword"))
// overwrite is not allowed
err = kb.ImportPrivKey("john2", keystr, "password")
require.Equal(t, "cannot overwrite key: john2", err.Error())
// try export non existing key
_, err = kb.ExportPrivKeyArmor("john3", "wrongpassword")
Remove bech32 PubKey support (#7477) * Move PubKey bech32 to legacy package and migrate the usage where possible * update /server * wip * move proto json encoding helper functions to internal * update internal/marshal * wip * update sections which needs legacybech32 * update validators output * fix conflicts * slashing update * add more tests and helper function for ANY JSON serialization * update slashing * Update function documentation * Rename code any-marshal helper functions * Update pubkey unpacking test * Update test comments * solve TestDecodeStore * solve legacytx issues * all code compiles * keyring tests * keyring cleanup * remove AssertMsg * fix some tests * fix add_ledger_test.go * update cli tests * debug cli test * rename clashed bech32 names * linter fixes * update tmservice tests * linter: update legacy deprecated checks * fix names * linting * legacybech32 pubkey type rename * fix staking client * fix test compilation * fix TestGetCmdQuerySigningInfo * rename NewIfcJSONAnyMarshaler * keyring: remove duplicated information from multinfo structure * todo cleanups * Update Changelog * remove some legacybech32 from tests * remove todos * remove printlnJSON from /server CLI and amino encoding * remove protocdc.MarshalJSON * client/show remove duplicated function * remove protocdc package * comment update * remove legacybech32.MustMarshalPubKey from a test * add todo * fix TestPublicKeyUnsafe test * review update * fix bech32 UnmarshalPubKey * Use codec.MarshalIfcJSON * fix linter issues * merging conflict: fix codec.Unmarshal calls * cleanups * Update CHANGELOG.md Co-authored-by: Aaron Craelius <aaron@regen.network> * Reword changelog updates * use pubkey.String for comparison in Test_runAddCmdLedgerWithCustomCoinType * Update GetCmdQuerySigningInfo example * cli: update keys add docs * Add errors AsOf and errors.ErrIO type * restore multisigPubKeyInfo structure bring it back to multiInfo struct * Update codec/proto_codec.go Co-authored-by: Marie Gauthier <marie.gauthier63@gmail.com> * Update crypto/keys/ed25519/ed25519_test.go Co-authored-by: Marie Gauthier <marie.gauthier63@gmail.com> * Update codec/proto_codec.go Co-authored-by: Marie Gauthier <marie.gauthier63@gmail.com> * move pubkey any marshaling tests * Apply suggestions from code review Co-authored-by: Marie Gauthier <marie.gauthier63@gmail.com> * review updates * adding missing return * errors: use IsOf instead of AsOf * keyring: add a correct check for key not found in keyring.Get * add checkKeyNotFound * fix linter issues * fix: keyring key not found check * fix keyring tests * fix linting issues * cli tests * fix: 'simd keys show <key> -p' * fix: TestVerifyMultisignature * rename keyring Bech32... functions to Mk... * fix RunAddCmd * Update pubkey display * wip * add more tests * udate keyring output tests * remove todo from ledger tests * rename MkKeyOutput * Changelog update * solve liner issues * add link to github issue Co-authored-by: Aaron Craelius <aaron@regen.network> Co-authored-by: Marie Gauthier <marie.gauthier63@gmail.com>
2021-03-25 07:53:22 -07:00
require.EqualError(t, err, "john3.info: key not found")
}
func TestInMemoryLanguage(t *testing.T) {
kb := NewInMemory()
_, _, err := kb.NewMnemonic("something", Japanese, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
require.Error(t, err)
require.Equal(t, "unsupported language: only english is supported", err.Error())
}
func TestInMemoryCreateMultisig(t *testing.T) {
kb, err := New("keybasename", "memory", "", nil)
require.NoError(t, err)
Remove old PubKeyMultisigThreshold (#7284) * WIP on protobuf keys * Use Type() and Bytes() in sr25519 pub key Equals * Add tests * Add few more tests * Update other pub/priv key types Equals * Fix PrivKey's Sign method * Rename variables in tests * Fix infinite recursive calls * Use tm ed25519 keys * Add Sign and VerifySignature tests * Remove ed25519 and sr25519 references * proto linting * Add proto crypto file * Implement some of the new multisig proto type methods * Add tests for MultisigThresholdPubKey * Add tests for pubkey pb/amino conversion functions * Move crypto types.go and register new proto pubkeys * Add missing pointer ref * Address review comments * panic in MultisigThresholdPubKey VerifySignature * Use internal crypto.PubKey in multisig * Add tests for MultisigThresholdPubKey VerifyMultisignature * Only keep LegacyAminoMultisigThresholdPubKey and move to proto keys to v1 * Remove conversion functions and introduce internal PubKey type * Start removal of old PubKeyMultisigThreshold references * Remove old secp256k1 PubKey and PrivKey * Uncomment test case * Fix linting issues * More linting * Revert tests keys values * Add Amino overrides to proto keys * Add pubkey test * Fix tests * Use threshold isntead of K * Standardize Type * Revert standardize types commit * Add comment * Simplify proto names * Fixed merge issues * Uncomment tests * Remove old multisig * Add amino marshal for multisig * Fix lint * Correctly register amino * One test left! * Remove old struct * Fix test * Fix test * Unpack into tmcrypto * Remove old threshold pubkey tests * Fix register amino * Fix lint * Use sdk crypto PubKey in multisig UnpackInterfaces * Potential fix? * Use anil's suggestion Co-authored-by: Aaron Craelius <aaronc@users.noreply.github.com> Co-authored-by: Amaury Martiny <amaury.martiny@protonmail.com> Co-authored-by: Alexander Bezobchuk <alexanderbez@users.noreply.github.com> Co-authored-by: Alessio Treglia <alessio@tendermint.com>
2020-09-18 02:40:39 -07:00
multi := multisig.NewLegacyAminoPubKey(
1, []types.PubKey{
Remove old PubKeyMultisigThreshold (#7284) * WIP on protobuf keys * Use Type() and Bytes() in sr25519 pub key Equals * Add tests * Add few more tests * Update other pub/priv key types Equals * Fix PrivKey's Sign method * Rename variables in tests * Fix infinite recursive calls * Use tm ed25519 keys * Add Sign and VerifySignature tests * Remove ed25519 and sr25519 references * proto linting * Add proto crypto file * Implement some of the new multisig proto type methods * Add tests for MultisigThresholdPubKey * Add tests for pubkey pb/amino conversion functions * Move crypto types.go and register new proto pubkeys * Add missing pointer ref * Address review comments * panic in MultisigThresholdPubKey VerifySignature * Use internal crypto.PubKey in multisig * Add tests for MultisigThresholdPubKey VerifyMultisignature * Only keep LegacyAminoMultisigThresholdPubKey and move to proto keys to v1 * Remove conversion functions and introduce internal PubKey type * Start removal of old PubKeyMultisigThreshold references * Remove old secp256k1 PubKey and PrivKey * Uncomment test case * Fix linting issues * More linting * Revert tests keys values * Add Amino overrides to proto keys * Add pubkey test * Fix tests * Use threshold isntead of K * Standardize Type * Revert standardize types commit * Add comment * Simplify proto names * Fixed merge issues * Uncomment tests * Remove old multisig * Add amino marshal for multisig * Fix lint * Correctly register amino * One test left! * Remove old struct * Fix test * Fix test * Unpack into tmcrypto * Remove old threshold pubkey tests * Fix register amino * Fix lint * Use sdk crypto PubKey in multisig UnpackInterfaces * Potential fix? * Use anil's suggestion Co-authored-by: Aaron Craelius <aaronc@users.noreply.github.com> Co-authored-by: Amaury Martiny <amaury.martiny@protonmail.com> Co-authored-by: Alexander Bezobchuk <alexanderbez@users.noreply.github.com> Co-authored-by: Alessio Treglia <alessio@tendermint.com>
2020-09-18 02:40:39 -07:00
secp256k1.GenPrivKey().PubKey(),
},
)
_, err = kb.SaveMultisig("multi", multi)
require.NoError(t, err)
}
func TestInMemoryCreateAccountInvalidMnemonic(t *testing.T) {
kb := NewInMemory()
_, err := kb.NewAccount(
"some_account",
"malarkey pair crucial catch public canyon evil outer stage ten gym tornado",
"", hd.CreateHDPath(118, 0, 0).String(), hd.Secp256k1)
require.Error(t, err)
require.Equal(t, "Invalid mnemonic", err.Error())
}
// TestInMemoryKeyManagement makes sure we can manipulate these keys well
func TestInMemoryKeyManagement(t *testing.T) {
// make the storage with reasonable defaults
cstore := NewInMemory()
algo := hd.Secp256k1
n1, n2, n3 := "personal", "business", "other"
// Check empty state
l, err := cstore.List()
require.Nil(t, err)
require.Empty(t, l)
_, _, err = cstore.NewMnemonic(n1, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, notSupportedAlgo{})
require.Error(t, err, "ed25519 keys are currently not supported by keybase")
// create some keys
_, err = cstore.Key(n1)
require.Error(t, err)
i, _, err := cstore.NewMnemonic(n1, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, algo)
require.NoError(t, err)
require.Equal(t, n1, i.GetName())
_, _, err = cstore.NewMnemonic(n2, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, algo)
require.NoError(t, err)
// we can get these keys
i2, err := cstore.Key(n2)
require.NoError(t, err)
_, err = cstore.Key(n3)
require.NotNil(t, err)
_, err = cstore.KeyByAddress(accAddr(i2))
require.NoError(t, err)
addr, err := sdk.AccAddressFromBech32("cosmos1yq8lgssgxlx9smjhes6ryjasmqmd3ts2559g0t")
require.NoError(t, err)
_, err = cstore.KeyByAddress(addr)
require.NotNil(t, err)
// list shows them in order
keyS, err := cstore.List()
require.NoError(t, err)
require.Equal(t, 2, len(keyS))
// note these are in alphabetical order
require.Equal(t, n2, keyS[0].GetName())
require.Equal(t, n1, keyS[1].GetName())
require.Equal(t, i2.GetPubKey(), keyS[0].GetPubKey())
// deleting a key removes it
err = cstore.Delete("bad name")
require.NotNil(t, err)
err = cstore.Delete(n1)
require.NoError(t, err)
keyS, err = cstore.List()
require.NoError(t, err)
require.Equal(t, 1, len(keyS))
_, err = cstore.Key(n1)
require.Error(t, err)
// create an offline key
o1 := "offline"
priv1 := ed25519.GenPrivKey()
pub1 := priv1.PubKey()
i, err = cstore.SavePubKey(o1, pub1, hd.Ed25519Type)
require.Nil(t, err)
require.Equal(t, pub1, i.GetPubKey())
require.Equal(t, o1, i.GetName())
iOffline := i.(*offlineInfo)
require.Equal(t, hd.Ed25519Type, iOffline.GetAlgo())
keyS, err = cstore.List()
require.NoError(t, err)
require.Equal(t, 2, len(keyS))
// delete the offline key
err = cstore.Delete(o1)
require.NoError(t, err)
keyS, err = cstore.List()
require.NoError(t, err)
require.Equal(t, 1, len(keyS))
// addr cache gets nuked - and test skip flag
err = cstore.Delete(n2)
require.NoError(t, err)
}
// TestInMemorySignVerify does some detailed checks on how we sign and validate
// signatures
func TestInMemorySignVerify(t *testing.T) {
cstore := NewInMemory()
algo := hd.Secp256k1
n1, n2, n3 := "some dude", "a dudette", "dude-ish"
// create two users and get their info
i1, _, err := cstore.NewMnemonic(n1, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, algo)
require.Nil(t, err)
i2, _, err := cstore.NewMnemonic(n2, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, algo)
require.Nil(t, err)
// let's try to sign some messages
d1 := []byte("my first message")
d2 := []byte("some other important info!")
d3 := []byte("feels like I forgot something...")
// try signing both data with both ..
s11, pub1, err := cstore.Sign(n1, d1)
require.Nil(t, err)
require.Equal(t, i1.GetPubKey(), pub1)
s12, pub1, err := cstore.Sign(n1, d2)
require.Nil(t, err)
require.Equal(t, i1.GetPubKey(), pub1)
s21, pub2, err := cstore.Sign(n2, d1)
require.Nil(t, err)
require.Equal(t, i2.GetPubKey(), pub2)
s22, pub2, err := cstore.Sign(n2, d2)
require.Nil(t, err)
require.Equal(t, i2.GetPubKey(), pub2)
// let's try to validate and make sure it only works when everything is proper
cases := []struct {
key types.PubKey
data []byte
sig []byte
valid bool
}{
// proper matches
{i1.GetPubKey(), d1, s11, true},
// change data, pubkey, or signature leads to fail
{i1.GetPubKey(), d2, s11, false},
{i2.GetPubKey(), d1, s11, false},
{i1.GetPubKey(), d1, s21, false},
// make sure other successes
{i1.GetPubKey(), d2, s12, true},
{i2.GetPubKey(), d1, s21, true},
{i2.GetPubKey(), d2, s22, true},
}
for i, tc := range cases {
valid := tc.key.VerifySignature(tc.data, tc.sig)
require.Equal(t, tc.valid, valid, "%d", i)
}
// Import a public key
armor, err := cstore.ExportPubKeyArmor(n2)
require.Nil(t, err)
err = cstore.Delete(n2)
require.NoError(t, err)
err = cstore.ImportPubKey(n3, armor)
require.NoError(t, err)
i3, err := cstore.Key(n3)
require.NoError(t, err)
require.Equal(t, i3.GetName(), n3)
// Now try to sign data with a secret-less key
_, _, err = cstore.Sign(n3, d3)
require.Error(t, err)
require.Equal(t, "cannot sign with offline keys", err.Error())
}
// TestInMemoryExportImport tests exporting and importing
func TestInMemoryExportImport(t *testing.T) {
// make the storage with reasonable defaults
cstore := NewInMemory()
info, _, err := cstore.NewMnemonic("john", English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
require.NoError(t, err)
require.Equal(t, info.GetName(), "john")
john, err := cstore.Key("john")
require.NoError(t, err)
require.Equal(t, info.GetName(), "john")
johnAddr := info.GetPubKey().Address()
armor, err := cstore.ExportPubKeyArmor("john")
require.NoError(t, err)
err = cstore.Delete("john")
require.NoError(t, err)
err = cstore.ImportPubKey("john2", armor)
require.NoError(t, err)
john2, err := cstore.Key("john2")
require.NoError(t, err)
require.Equal(t, john.GetPubKey().Address(), johnAddr)
require.Equal(t, john.GetName(), "john")
require.Equal(t, john.GetAddress(), john2.GetAddress())
require.Equal(t, john.GetAlgo(), john2.GetAlgo())
require.Equal(t, john.GetPubKey(), john2.GetPubKey())
}
func TestInMemoryExportImportPrivKey(t *testing.T) {
kb := NewInMemory()
info, _, err := kb.NewMnemonic("john", English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
require.NoError(t, err)
require.Equal(t, info.GetName(), "john")
priv1, err := kb.Key("john")
require.NoError(t, err)
armored, err := kb.ExportPrivKeyArmor("john", "secretcpw")
require.NoError(t, err)
// delete exported key
require.NoError(t, kb.Delete("john"))
_, err = kb.Key("john")
require.Error(t, err)
// import armored key
require.NoError(t, kb.ImportPrivKey("john", armored, "secretcpw"))
// ensure old and new keys match
priv2, err := kb.Key("john")
require.NoError(t, err)
require.True(t, priv1.GetPubKey().Equals(priv2.GetPubKey()))
}
func TestInMemoryExportImportPubKey(t *testing.T) {
// make the storage with reasonable defaults
cstore := NewInMemory()
// CreateMnemonic a private-public key pair and ensure consistency
info, _, err := cstore.NewMnemonic("john", English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
require.Nil(t, err)
require.NotEqual(t, info, "")
require.Equal(t, info.GetName(), "john")
addr := info.GetPubKey().Address()
john, err := cstore.Key("john")
require.NoError(t, err)
require.Equal(t, john.GetName(), "john")
require.Equal(t, john.GetPubKey().Address(), addr)
// Export the public key only
armor, err := cstore.ExportPubKeyArmor("john")
require.NoError(t, err)
err = cstore.Delete("john")
require.NoError(t, err)
// Import it under a different name
err = cstore.ImportPubKey("john-pubkey-only", armor)
require.NoError(t, err)
// Ensure consistency
john2, err := cstore.Key("john-pubkey-only")
require.NoError(t, err)
// Compare the public keys
require.True(t, john.GetPubKey().Equals(john2.GetPubKey()))
// Ensure keys cannot be overwritten
err = cstore.ImportPubKey("john-pubkey-only", armor)
require.NotNil(t, err)
}
// TestInMemoryAdvancedKeyManagement verifies update, import, export functionality
func TestInMemoryAdvancedKeyManagement(t *testing.T) {
// make the storage with reasonable defaults
cstore := NewInMemory()
algo := hd.Secp256k1
n1, n2 := "old-name", "new name"
// make sure key works with initial password
_, _, err := cstore.NewMnemonic(n1, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, algo)
require.Nil(t, err, "%+v", err)
// exporting requires the proper name and passphrase
_, err = cstore.ExportPubKeyArmor(n1 + ".notreal")
require.NotNil(t, err)
_, err = cstore.ExportPubKeyArmor(" " + n1)
require.NotNil(t, err)
_, err = cstore.ExportPubKeyArmor(n1 + " ")
require.NotNil(t, err)
_, err = cstore.ExportPubKeyArmor("")
require.NotNil(t, err)
exported, err := cstore.ExportPubKeyArmor(n1)
require.Nil(t, err, "%+v", err)
err = cstore.Delete(n1)
require.NoError(t, err)
// import succeeds
err = cstore.ImportPubKey(n2, exported)
require.NoError(t, err)
// second import fails
err = cstore.ImportPubKey(n2, exported)
require.NotNil(t, err)
}
// TestInMemorySeedPhrase verifies restoring from a seed phrase
func TestInMemorySeedPhrase(t *testing.T) {
// make the storage with reasonable defaults
cstore := NewInMemory()
algo := hd.Secp256k1
n1, n2 := "lost-key", "found-again"
// make sure key works with initial password
info, mnemonic, err := cstore.NewMnemonic(n1, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, algo)
require.Nil(t, err, "%+v", err)
require.Equal(t, n1, info.GetName())
require.NotEmpty(t, mnemonic)
// now, let us delete this key
err = cstore.Delete(n1)
require.Nil(t, err, "%+v", err)
_, err = cstore.Key(n1)
require.NotNil(t, err)
// let us re-create it from the mnemonic-phrase
params := *hd.NewFundraiserParams(0, sdk.CoinType, 0)
hdPath := params.String()
newInfo, err := cstore.NewAccount(n2, mnemonic, DefaultBIP39Passphrase, hdPath, algo)
require.NoError(t, err)
require.Equal(t, n2, newInfo.GetName())
require.Equal(t, info.GetPubKey().Address(), newInfo.GetPubKey().Address())
require.Equal(t, info.GetPubKey(), newInfo.GetPubKey())
}
func TestKeyChain_ShouldFailWhenAddingSameGeneratedAccount(t *testing.T) {
kr, err := New(t.Name(), BackendTest, t.TempDir(), nil)
require.NoError(t, err)
// Given we create a mnemonic
_, seed, err := kr.NewMnemonic("test", English, "", DefaultBIP39Passphrase, hd.Secp256k1)
require.NoError(t, err)
require.NoError(t, kr.Delete("test"))
path := hd.CreateHDPath(118, 0, 0).String()
_, err = kr.NewAccount("test1", seed, "", path, hd.Secp256k1)
require.NoError(t, err)
// Creating another account with different uid but same seed should fail due to have same pub address
_, err = kr.NewAccount("test2", seed, "", path, hd.Secp256k1)
require.Error(t, err)
}
func ExampleNew() {
// Select the encryption and storage for your cryptostore
cstore := NewInMemory()
sec := hd.Secp256k1
// Add keys and see they return in alphabetical order
bob, _, err := cstore.NewMnemonic("Bob", English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, sec)
if err != nil {
// this should never happen
fmt.Println(err)
} else {
// return info here just like in List
fmt.Println(bob.GetName())
}
_, _, _ = cstore.NewMnemonic("Alice", English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, sec)
_, _, _ = cstore.NewMnemonic("Carl", English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, sec)
info, _ := cstore.List()
for _, i := range info {
fmt.Println(i.GetName())
}
// We need to use passphrase to generate a signature
tx := []byte("deadbeef")
sig, pub, err := cstore.Sign("Bob", tx)
if err != nil {
fmt.Println("don't accept real passphrase")
}
// and we can validate the signature with publicly available info
binfo, _ := cstore.Key("Bob")
if !binfo.GetPubKey().Equals(bob.GetPubKey()) {
fmt.Println("Get and Create return different keys")
}
if pub.Equals(binfo.GetPubKey()) {
fmt.Println("signed by Bob")
}
if !pub.VerifySignature(tx, sig) {
fmt.Println("invalid signature")
}
// Output:
// Bob
// Alice
// Bob
// Carl
// signed by Bob
}
func TestAltKeyring_List(t *testing.T) {
dir := t.TempDir()
keyring, err := New(t.Name(), BackendTest, dir, nil)
require.NoError(t, err)
list, err := keyring.List()
require.NoError(t, err)
require.Empty(t, list)
// Fails on creating unsupported pubKeyType
_, _, err = keyring.NewMnemonic("failing", English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, notSupportedAlgo{})
require.EqualError(t, err, ErrUnsupportedSigningAlgo.Error())
// Create 3 keys
uid1, uid2, uid3 := "Zkey", "Bkey", "Rkey"
_, _, err = keyring.NewMnemonic(uid1, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
require.NoError(t, err)
_, _, err = keyring.NewMnemonic(uid2, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
require.NoError(t, err)
_, _, err = keyring.NewMnemonic(uid3, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
require.NoError(t, err)
list, err = keyring.List()
require.NoError(t, err)
require.Len(t, list, 3)
// Check they are in alphabetical order
require.Equal(t, uid2, list[0].GetName())
require.Equal(t, uid3, list[1].GetName())
require.Equal(t, uid1, list[2].GetName())
}
func TestAltKeyring_NewAccount(t *testing.T) {
keyring, err := New(t.Name(), BackendTest, t.TempDir(), nil)
require.NoError(t, err)
entropy, err := bip39.NewEntropy(defaultEntropySize)
require.NoError(t, err)
mnemonic, err := bip39.NewMnemonic(entropy)
require.NoError(t, err)
uid := "newUid"
// Fails on creating unsupported pubKeyType
_, err = keyring.NewAccount(uid, mnemonic, DefaultBIP39Passphrase, sdk.FullFundraiserPath, notSupportedAlgo{})
require.EqualError(t, err, ErrUnsupportedSigningAlgo.Error())
info, err := keyring.NewAccount(uid, mnemonic, DefaultBIP39Passphrase, sdk.FullFundraiserPath, hd.Secp256k1)
require.NoError(t, err)
require.Equal(t, uid, info.GetName())
list, err := keyring.List()
require.NoError(t, err)
require.Len(t, list, 1)
}
func TestAltKeyring_Get(t *testing.T) {
keyring, err := New(t.Name(), BackendTest, t.TempDir(), nil)
require.NoError(t, err)
uid := someKey
mnemonic, _, err := keyring.NewMnemonic(uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
require.NoError(t, err)
key, err := keyring.Key(uid)
require.NoError(t, err)
requireEqualInfo(t, mnemonic, key)
}
func TestAltKeyring_KeyByAddress(t *testing.T) {
keyring, err := New(t.Name(), BackendTest, t.TempDir(), nil)
require.NoError(t, err)
uid := someKey
mnemonic, _, err := keyring.NewMnemonic(uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
require.NoError(t, err)
key, err := keyring.KeyByAddress(mnemonic.GetAddress())
require.NoError(t, err)
requireEqualInfo(t, key, mnemonic)
}
func TestAltKeyring_Delete(t *testing.T) {
keyring, err := New(t.Name(), BackendTest, t.TempDir(), nil)
require.NoError(t, err)
uid := someKey
_, _, err = keyring.NewMnemonic(uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
require.NoError(t, err)
list, err := keyring.List()
require.NoError(t, err)
require.Len(t, list, 1)
err = keyring.Delete(uid)
require.NoError(t, err)
list, err = keyring.List()
require.NoError(t, err)
require.Empty(t, list)
}
func TestAltKeyring_DeleteByAddress(t *testing.T) {
keyring, err := New(t.Name(), BackendTest, t.TempDir(), nil)
require.NoError(t, err)
uid := someKey
mnemonic, _, err := keyring.NewMnemonic(uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
require.NoError(t, err)
list, err := keyring.List()
require.NoError(t, err)
require.Len(t, list, 1)
err = keyring.DeleteByAddress(mnemonic.GetAddress())
require.NoError(t, err)
list, err = keyring.List()
require.NoError(t, err)
require.Empty(t, list)
}
func TestAltKeyring_SavePubKey(t *testing.T) {
keyring, err := New(t.Name(), BackendTest, t.TempDir(), nil)
require.NoError(t, err)
list, err := keyring.List()
require.NoError(t, err)
require.Empty(t, list)
key := someKey
priv := ed25519.GenPrivKey()
pub := priv.PubKey()
info, err := keyring.SavePubKey(key, pub, hd.Secp256k1.Name())
require.Nil(t, err)
require.Equal(t, pub, info.GetPubKey())
require.Equal(t, key, info.GetName())
require.Equal(t, hd.Secp256k1.Name(), info.GetAlgo())
list, err = keyring.List()
require.NoError(t, err)
require.Equal(t, 1, len(list))
}
func TestAltKeyring_SaveMultisig(t *testing.T) {
keyring, err := New(t.Name(), BackendTest, t.TempDir(), nil)
require.NoError(t, err)
mnemonic1, _, err := keyring.NewMnemonic("key1", English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
require.NoError(t, err)
mnemonic2, _, err := keyring.NewMnemonic("key2", English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
require.NoError(t, err)
key := "multi"
Remove old PubKeyMultisigThreshold (#7284) * WIP on protobuf keys * Use Type() and Bytes() in sr25519 pub key Equals * Add tests * Add few more tests * Update other pub/priv key types Equals * Fix PrivKey's Sign method * Rename variables in tests * Fix infinite recursive calls * Use tm ed25519 keys * Add Sign and VerifySignature tests * Remove ed25519 and sr25519 references * proto linting * Add proto crypto file * Implement some of the new multisig proto type methods * Add tests for MultisigThresholdPubKey * Add tests for pubkey pb/amino conversion functions * Move crypto types.go and register new proto pubkeys * Add missing pointer ref * Address review comments * panic in MultisigThresholdPubKey VerifySignature * Use internal crypto.PubKey in multisig * Add tests for MultisigThresholdPubKey VerifyMultisignature * Only keep LegacyAminoMultisigThresholdPubKey and move to proto keys to v1 * Remove conversion functions and introduce internal PubKey type * Start removal of old PubKeyMultisigThreshold references * Remove old secp256k1 PubKey and PrivKey * Uncomment test case * Fix linting issues * More linting * Revert tests keys values * Add Amino overrides to proto keys * Add pubkey test * Fix tests * Use threshold isntead of K * Standardize Type * Revert standardize types commit * Add comment * Simplify proto names * Fixed merge issues * Uncomment tests * Remove old multisig * Add amino marshal for multisig * Fix lint * Correctly register amino * One test left! * Remove old struct * Fix test * Fix test * Unpack into tmcrypto * Remove old threshold pubkey tests * Fix register amino * Fix lint * Use sdk crypto PubKey in multisig UnpackInterfaces * Potential fix? * Use anil's suggestion Co-authored-by: Aaron Craelius <aaronc@users.noreply.github.com> Co-authored-by: Amaury Martiny <amaury.martiny@protonmail.com> Co-authored-by: Alexander Bezobchuk <alexanderbez@users.noreply.github.com> Co-authored-by: Alessio Treglia <alessio@tendermint.com>
2020-09-18 02:40:39 -07:00
pub := multisig.NewLegacyAminoPubKey(
2,
[]types.PubKey{
Remove old PubKeyMultisigThreshold (#7284) * WIP on protobuf keys * Use Type() and Bytes() in sr25519 pub key Equals * Add tests * Add few more tests * Update other pub/priv key types Equals * Fix PrivKey's Sign method * Rename variables in tests * Fix infinite recursive calls * Use tm ed25519 keys * Add Sign and VerifySignature tests * Remove ed25519 and sr25519 references * proto linting * Add proto crypto file * Implement some of the new multisig proto type methods * Add tests for MultisigThresholdPubKey * Add tests for pubkey pb/amino conversion functions * Move crypto types.go and register new proto pubkeys * Add missing pointer ref * Address review comments * panic in MultisigThresholdPubKey VerifySignature * Use internal crypto.PubKey in multisig * Add tests for MultisigThresholdPubKey VerifyMultisignature * Only keep LegacyAminoMultisigThresholdPubKey and move to proto keys to v1 * Remove conversion functions and introduce internal PubKey type * Start removal of old PubKeyMultisigThreshold references * Remove old secp256k1 PubKey and PrivKey * Uncomment test case * Fix linting issues * More linting * Revert tests keys values * Add Amino overrides to proto keys * Add pubkey test * Fix tests * Use threshold isntead of K * Standardize Type * Revert standardize types commit * Add comment * Simplify proto names * Fixed merge issues * Uncomment tests * Remove old multisig * Add amino marshal for multisig * Fix lint * Correctly register amino * One test left! * Remove old struct * Fix test * Fix test * Unpack into tmcrypto * Remove old threshold pubkey tests * Fix register amino * Fix lint * Use sdk crypto PubKey in multisig UnpackInterfaces * Potential fix? * Use anil's suggestion Co-authored-by: Aaron Craelius <aaronc@users.noreply.github.com> Co-authored-by: Amaury Martiny <amaury.martiny@protonmail.com> Co-authored-by: Alexander Bezobchuk <alexanderbez@users.noreply.github.com> Co-authored-by: Alessio Treglia <alessio@tendermint.com>
2020-09-18 02:40:39 -07:00
&secp256k1.PubKey{Key: mnemonic1.GetPubKey().Bytes()},
&secp256k1.PubKey{Key: mnemonic2.GetPubKey().Bytes()},
},
)
info, err := keyring.SaveMultisig(key, pub)
require.Nil(t, err)
require.Equal(t, pub, info.GetPubKey())
require.Equal(t, key, info.GetName())
list, err := keyring.List()
require.NoError(t, err)
require.Len(t, list, 3)
}
func TestAltKeyring_Sign(t *testing.T) {
keyring, err := New(t.Name(), BackendTest, t.TempDir(), nil)
require.NoError(t, err)
uid := "jack"
_, _, err = keyring.NewMnemonic(uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
require.NoError(t, err)
msg := []byte("some message")
sign, key, err := keyring.Sign(uid, msg)
require.NoError(t, err)
require.True(t, key.VerifySignature(msg, sign))
}
func TestAltKeyring_SignByAddress(t *testing.T) {
keyring, err := New(t.Name(), BackendTest, t.TempDir(), nil)
require.NoError(t, err)
uid := "jack"
mnemonic, _, err := keyring.NewMnemonic(uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
require.NoError(t, err)
msg := []byte("some message")
sign, key, err := keyring.SignByAddress(mnemonic.GetAddress(), msg)
require.NoError(t, err)
require.True(t, key.VerifySignature(msg, sign))
}
func TestAltKeyring_ImportExportPrivKey(t *testing.T) {
keyring, err := New(t.Name(), BackendTest, t.TempDir(), nil)
require.NoError(t, err)
uid := theID
_, _, err = keyring.NewMnemonic(uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
require.NoError(t, err)
passphrase := "somePass"
armor, err := keyring.ExportPrivKeyArmor(uid, passphrase)
require.NoError(t, err)
err = keyring.Delete(uid)
require.NoError(t, err)
newUID := otherID
// Should fail importing with wrong password
err = keyring.ImportPrivKey(newUID, armor, "wrongPass")
require.EqualError(t, err, "failed to decrypt private key: ciphertext decryption failed")
err = keyring.ImportPrivKey(newUID, armor, passphrase)
require.NoError(t, err)
// Should fail importing private key on existing key.
err = keyring.ImportPrivKey(newUID, armor, passphrase)
require.EqualError(t, err, fmt.Sprintf("cannot overwrite key: %s", newUID))
}
func TestAltKeyring_ImportExportPrivKey_ByAddress(t *testing.T) {
keyring, err := New(t.Name(), BackendTest, t.TempDir(), nil)
require.NoError(t, err)
uid := theID
mnemonic, _, err := keyring.NewMnemonic(uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
require.NoError(t, err)
passphrase := "somePass"
armor, err := keyring.ExportPrivKeyArmorByAddress(mnemonic.GetAddress(), passphrase)
require.NoError(t, err)
err = keyring.Delete(uid)
require.NoError(t, err)
newUID := otherID
// Should fail importing with wrong password
err = keyring.ImportPrivKey(newUID, armor, "wrongPass")
require.EqualError(t, err, "failed to decrypt private key: ciphertext decryption failed")
err = keyring.ImportPrivKey(newUID, armor, passphrase)
require.NoError(t, err)
// Should fail importing private key on existing key.
err = keyring.ImportPrivKey(newUID, armor, passphrase)
require.EqualError(t, err, fmt.Sprintf("cannot overwrite key: %s", newUID))
}
func TestAltKeyring_ImportExportPubKey(t *testing.T) {
keyring, err := New(t.Name(), BackendTest, t.TempDir(), nil)
require.NoError(t, err)
uid := theID
_, _, err = keyring.NewMnemonic(uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
require.NoError(t, err)
armor, err := keyring.ExportPubKeyArmor(uid)
require.NoError(t, err)
err = keyring.Delete(uid)
require.NoError(t, err)
newUID := otherID
err = keyring.ImportPubKey(newUID, armor)
require.NoError(t, err)
// Should fail importing private key on existing key.
err = keyring.ImportPubKey(newUID, armor)
require.EqualError(t, err, fmt.Sprintf("cannot overwrite key: %s", newUID))
}
func TestAltKeyring_ImportExportPubKey_ByAddress(t *testing.T) {
keyring, err := New(t.Name(), BackendTest, t.TempDir(), nil)
require.NoError(t, err)
uid := theID
mnemonic, _, err := keyring.NewMnemonic(uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
require.NoError(t, err)
armor, err := keyring.ExportPubKeyArmorByAddress(mnemonic.GetAddress())
require.NoError(t, err)
err = keyring.Delete(uid)
require.NoError(t, err)
newUID := otherID
err = keyring.ImportPubKey(newUID, armor)
require.NoError(t, err)
// Should fail importing private key on existing key.
err = keyring.ImportPubKey(newUID, armor)
require.EqualError(t, err, fmt.Sprintf("cannot overwrite key: %s", newUID))
}
func TestAltKeyring_UnsafeExportPrivKeyHex(t *testing.T) {
keyring, err := New(t.Name(), BackendTest, t.TempDir(), nil)
require.NoError(t, err)
uid := theID
_, _, err = keyring.NewMnemonic(uid, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
require.NoError(t, err)
unsafeKeyring := NewUnsafe(keyring)
privKey, err := unsafeKeyring.UnsafeExportPrivKeyHex(uid)
require.NoError(t, err)
require.Equal(t, 64, len(privKey))
_, err = hex.DecodeString(privKey)
require.NoError(t, err)
// test error on non existing key
_, err = unsafeKeyring.UnsafeExportPrivKeyHex("non-existing")
require.Error(t, err)
}
func TestAltKeyring_ConstructorSupportedAlgos(t *testing.T) {
keyring, err := New(t.Name(), BackendTest, t.TempDir(), nil)
require.NoError(t, err)
// should fail when using unsupported signing algorythm.
_, _, err = keyring.NewMnemonic("test", English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, notSupportedAlgo{})
require.EqualError(t, err, "unsupported signing algo")
// but works with default signing algo.
_, _, err = keyring.NewMnemonic("test", English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
require.NoError(t, err)
// but we can create a new keybase with our provided algos.
keyring2, err := New(t.Name(), BackendTest, t.TempDir(), nil, func(options *Options) {
options.SupportedAlgos = SigningAlgoList{
notSupportedAlgo{},
}
})
require.NoError(t, err)
// now this new keyring does not fail when signing with provided algo
_, _, err = keyring2.NewMnemonic("test", English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, notSupportedAlgo{})
require.NoError(t, err)
}
func TestBackendConfigConstructors(t *testing.T) {
backend := newKWalletBackendKeyringConfig("test", "", nil)
require.Equal(t, []keyring.BackendType{keyring.KWalletBackend}, backend.AllowedBackends)
require.Equal(t, "kdewallet", backend.ServiceName)
require.Equal(t, "test", backend.KWalletAppID)
backend = newPassBackendKeyringConfig("test", "directory", nil)
require.Equal(t, []keyring.BackendType{keyring.PassBackend}, backend.AllowedBackends)
require.Equal(t, "test", backend.ServiceName)
require.Equal(t, "keyring-test", backend.PassPrefix)
}
func requireEqualInfo(t *testing.T, key Info, mnemonic Info) {
require.Equal(t, key.GetName(), mnemonic.GetName())
require.Equal(t, key.GetAddress(), mnemonic.GetAddress())
require.Equal(t, key.GetPubKey(), mnemonic.GetPubKey())
require.Equal(t, key.GetAlgo(), mnemonic.GetAlgo())
require.Equal(t, key.GetType(), mnemonic.GetType())
}
func accAddr(info Info) sdk.AccAddress { return info.GetAddress() }