diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c31551b5..dd7c1039f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.9.0 + +BREAKING CHANGES + +- `priv.PubKey()` no longer returns an error. Any applicable errors (such as when fetching the public key from a hardware wallet) should be checked and returned when constructing the private key. + ## 0.8.0 **TBD** diff --git a/Gopkg.lock b/Gopkg.lock index a475c6656..fbfd54dcf 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -99,8 +99,8 @@ "assert", "require" ] - revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71" - version = "v1.2.1" + revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686" + version = "v1.2.2" [[projects]] branch = "master" @@ -181,11 +181,11 @@ branch = "master" name = "golang.org/x/sys" packages = ["cpu"] - revision = "9527bec2660bd847c050fda93a0f0c6dee0800bb" + revision = "a9e25c09b96b8870693763211309e213c6ef299d" [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "f20e34cd998442d4ffe2f9aa45ab87a55ba6e4cd19f29009adaadac3b5dccf26" + inputs-digest = "1731880d432026bbd22865582cf7c7dd6d5c65618149de586e30ce156d338c01" solver-name = "gps-cdcl" solver-version = 1 diff --git a/encode_test.go b/encode_test.go index ed5395db8..025b09c80 100644 --- a/encode_test.go +++ b/encode_test.go @@ -91,8 +91,7 @@ func TestKeyEncodings(t *testing.T) { assert.EqualValues(t, sig1, sig3) // Check (de/en)codings of PubKeys. - pubKey, err := tc.privKey.PubKey() - assert.NoError(t, err) + pubKey := tc.privKey.PubKey() var pub2, pub3 PubKey checkAminoBinary(t, pubKey, &pub2, tc.pubSize) assert.EqualValues(t, pubKey, pub2) diff --git a/keys/keybase.go b/keys/keybase.go index 39a3de59e..79e6f15fa 100644 --- a/keys/keybase.go +++ b/keys/keybase.go @@ -68,10 +68,7 @@ func (kb dbKeybase) CreateLedger(name string, path crypto.DerivationPath, algo S if err != nil { return nil, err } - pub, err := priv.PubKey() - if err != nil { - return nil, err - } + pub := priv.PubKey() return kb.writeLedgerKey(pub, path, name), nil } @@ -169,10 +166,7 @@ func (kb dbKeybase) Sign(name, passphrase string, msg []byte) (sig crypto.Signat if err != nil { return nil, nil, err } - pub, err = priv.PubKey() - if err != nil { - return nil, nil, err - } + pub = priv.PubKey() return sig, pub, nil } @@ -290,10 +284,7 @@ func (kb dbKeybase) writeLocalKey(priv crypto.PrivKey, name, passphrase string) // encrypt private key using passphrase privArmor := encryptArmorPrivKey(priv, passphrase) // make Info - pub, err := priv.PubKey() - if err != nil { - panic(err) - } + pub := priv.PubKey() info := newLocalInfo(name, pub, privArmor) kb.writeInfo(info, name) return info diff --git a/keys/keybase_test.go b/keys/keybase_test.go index 3627626cb..5caf82af8 100644 --- a/keys/keybase_test.go +++ b/keys/keybase_test.go @@ -70,8 +70,7 @@ func TestKeyManagement(t *testing.T) { // create an offline key o1 := "offline" priv1 := crypto.GenPrivKeyEd25519() - pub1, err := priv1.PubKey() - require.Nil(t, err) + pub1 := priv1.PubKey() i, err = cstore.CreateOffline(o1, pub1) require.Nil(t, err) require.Equal(t, pub1, i.GetPubKey()) diff --git a/ledger_secp256k1.go b/ledger_secp256k1.go index 1a7887ad3..21dfbb8b5 100644 --- a/ledger_secp256k1.go +++ b/ledger_secp256k1.go @@ -44,10 +44,12 @@ type PrivKeyLedgerSecp256k1 struct { func NewPrivKeyLedgerSecp256k1(path DerivationPath) (PrivKey, error) { var pk PrivKeyLedgerSecp256k1 pk.Path = path - // getPubKey will cache the pubkey for later use, - // this allows us to return an error early if the ledger - // is not plugged in - _, err := pk.getPubKey() + // cache the pubkey for later use + pubKey, err := pk.getPubKey() + if err != nil { + return nil, err + } + pk.CachedPubKey = pubKey return &pk, err } @@ -55,8 +57,7 @@ func NewPrivKeyLedgerSecp256k1(path DerivationPath) (PrivKey, error) { // after loading it from disk func (pk PrivKeyLedgerSecp256k1) ValidateKey() error { // getPubKey will return an error if the ledger is not - // properly set up... - pub, err := pk.forceGetPubKey() + pub, err := pk.getPubKey() if err != nil { return err } @@ -86,45 +87,22 @@ func (pk PrivKeyLedgerSecp256k1) Sign(msg []byte) (Signature, error) { if err != nil { return nil, err } - sig, err := signLedgerSecp256k1(dev, pk.Path, msg) if err != nil { return nil, err } - - pub, err := pubkeyLedgerSecp256k1(dev, pk.Path) - if err != nil { - return nil, err - } - - // if we have no pubkey yet, store it for future queries - if pk.CachedPubKey == nil { - pk.CachedPubKey = pub - } else if !pk.CachedPubKey.Equals(pub) { - return nil, fmt.Errorf("stored key does not match signing key") - } return sig, nil } // PubKey returns the stored PubKey -func (pk PrivKeyLedgerSecp256k1) PubKey() (PubKey, error) { - return pk.getPubKey() +func (pk PrivKeyLedgerSecp256k1) PubKey() PubKey { + return pk.CachedPubKey } -// getPubKey reads the pubkey from cache or from the ledger itself +// getPubKey reads the pubkey the ledger itself // since this involves IO, it may return an error, which is not exposed // in the PubKey interface, so this function allows better error handling func (pk PrivKeyLedgerSecp256k1) getPubKey() (key PubKey, err error) { - // if we have no pubkey, set it - if pk.CachedPubKey == nil { - pk.CachedPubKey, err = pk.forceGetPubKey() - } - return pk.CachedPubKey, err -} - -// forceGetPubKey is like getPubKey but ignores any cached key -// and ensures we get it from the ledger itself. -func (pk PrivKeyLedgerSecp256k1) forceGetPubKey() (key PubKey, err error) { dev, err := getLedger() if err != nil { return key, fmt.Errorf("cannot connect to Ledger device - error: %v", err) diff --git a/ledger_test.go b/ledger_test.go index 4a7ae46e4..83390cc36 100644 --- a/ledger_test.go +++ b/ledger_test.go @@ -19,8 +19,7 @@ func TestRealLedgerSecp256k1(t *testing.T) { priv, err := NewPrivKeyLedgerSecp256k1(path) require.Nil(t, err, "%+v", err) - pub, err := priv.PubKey() - require.Nil(t, err) + pub := priv.PubKey() sig, err := priv.Sign(msg) require.Nil(t, err) @@ -33,8 +32,7 @@ func TestRealLedgerSecp256k1(t *testing.T) { require.Nil(t, err, "%+v", err) // make sure we get the same pubkey when we load from disk - pub2, err := priv2.PubKey() - require.Nil(t, err) + pub2 := priv2.PubKey() require.Equal(t, pub, pub2) // signing with the loaded key should match the original pubkey diff --git a/priv_key.go b/priv_key.go index 2c06f3452..dbfe64c33 100644 --- a/priv_key.go +++ b/priv_key.go @@ -18,7 +18,7 @@ func PrivKeyFromBytes(privKeyBytes []byte) (privKey PrivKey, err error) { type PrivKey interface { Bytes() []byte Sign(msg []byte) (Signature, error) - PubKey() (PubKey, error) + PubKey() PubKey Equals(PrivKey) bool } @@ -39,10 +39,10 @@ func (privKey PrivKeyEd25519) Sign(msg []byte) (Signature, error) { return SignatureEd25519(*signatureBytes), nil } -func (privKey PrivKeyEd25519) PubKey() (PubKey, error) { +func (privKey PrivKeyEd25519) PubKey() PubKey { privKeyBytes := [64]byte(privKey) pubBytes := *ed25519.MakePublicKey(&privKeyBytes) - return PubKeyEd25519(pubBytes), nil + return PubKeyEd25519(pubBytes) } // Equals - you probably don't need to use this. @@ -115,11 +115,11 @@ func (privKey PrivKeySecp256k1) Sign(msg []byte) (Signature, error) { return SignatureSecp256k1(sig__.Serialize()), nil } -func (privKey PrivKeySecp256k1) PubKey() (PubKey, error) { +func (privKey PrivKeySecp256k1) PubKey() PubKey { _, pub__ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:]) var pub PubKeySecp256k1 copy(pub[:], pub__.SerializeCompressed()) - return pub, nil + return pub } // Equals - you probably don't need to use this. diff --git a/priv_key_test.go b/priv_key_test.go index 33f3eb7ee..c43a6d1b1 100644 --- a/priv_key_test.go +++ b/priv_key_test.go @@ -11,8 +11,7 @@ func TestGeneratePrivKey(t *testing.T) { testPriv := crypto.GenPrivKeyEd25519() testGenerate := testPriv.Generate(1) signBytes := []byte("something to sign") - pub, err := testGenerate.PubKey() - assert.NoError(t, err) + pub := testGenerate.PubKey() sig, err := testGenerate.Sign(signBytes) assert.NoError(t, err) assert.True(t, pub.VerifyBytes(signBytes, sig)) diff --git a/pub_key_test.go b/pub_key_test.go index 35c78a46a..7b856cf18 100644 --- a/pub_key_test.go +++ b/pub_key_test.go @@ -33,8 +33,7 @@ func TestPubKeySecp256k1Address(t *testing.T) { var priv PrivKeySecp256k1 copy(priv[:], privB) - pubKey, err := priv.PubKey() - assert.NoError(t, err) + pubKey := priv.PubKey() pubT, _ := pubKey.(PubKeySecp256k1) pub := pubT[:] addr := pubKey.Address() diff --git a/signature_test.go b/signature_test.go index 560815ccf..d6ae2b7a9 100644 --- a/signature_test.go +++ b/signature_test.go @@ -3,15 +3,14 @@ package crypto import ( "testing" - "github.com/stretchr/testify/require" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestSignAndValidateEd25519(t *testing.T) { privKey := GenPrivKeyEd25519() - pubKey, err := privKey.PubKey() - require.Nil(t, err) + pubKey := privKey.PubKey() msg := CRandBytes(128) sig, err := privKey.Sign(msg) @@ -30,8 +29,7 @@ func TestSignAndValidateEd25519(t *testing.T) { func TestSignAndValidateSecp256k1(t *testing.T) { privKey := GenPrivKeySecp256k1() - pubKey, err := privKey.PubKey() - require.Nil(t, err) + pubKey := privKey.PubKey() msg := CRandBytes(128) sig, err := privKey.Sign(msg)