crypto: API modifications (#5236)

## Description

This PR aims to make the crypto.PubKey interface more intuitive. 

Changes: 

- `VerfiyBytes` -> `VerifySignature`

Before `Bytes()` was amino encoded, now since it is the byte representation should we get rid of it entirely?

EDIT: decided to keep `Bytes()` as it is useful if you are using the interface instead of the concrete key

Closes: #XXX
This commit is contained in:
Marko
2020-08-13 14:29:16 +02:00
committed by GitHub
parent e1a1395cf4
commit 9e98c74e3c
21 changed files with 44 additions and 41 deletions

View File

@@ -15,6 +15,7 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi
- [crypto] [\#5214] Change `GenPrivKeySecp256k1` to `GenPrivKeyFromSecret` to be consistent with other keys
- [state] [\#5191](https://github.com/tendermint/tendermint/pull/5191) Add `State.InitialHeight` field to record initial block height, must be `1` (not `0`) to start from 1 (@erikgrinaker)
- [state] `LoadStateFromDBOrGenesisFile()` and `LoadStateFromDBOrGenesisDoc()` no longer saves the state in the database if not found, the genesis state is simply returned (@erikgrinaker)
- [crypto] \#5236 `VerifyBytes` is now `VerifySignature` on the `crypto.PubKey` interface.
### FEATURES:

View File

@@ -1708,7 +1708,9 @@ func (cs *State) defaultSetProposal(proposal *types.Proposal) error {
p := proposal.ToProto()
// Verify signature
if !cs.Validators.GetProposer().PubKey.VerifyBytes(types.ProposalSignBytes(cs.state.ChainID, p), proposal.Signature) {
if !cs.Validators.GetProposer().PubKey.VerifySignature(
types.ProposalSignBytes(cs.state.ChainID, p), proposal.Signature,
) {
return ErrInvalidProposalSignature
}

View File

@@ -22,7 +22,7 @@ func AddressHash(bz []byte) Address {
type PubKey interface {
Address() Address
Bytes() []byte
VerifyBytes(msg []byte, sig []byte) bool
VerifySignature(msg []byte, sig []byte) bool
Equals(PubKey) bool
Type() string
}

View File

@@ -145,7 +145,7 @@ func (pubKey PubKey) Bytes() []byte {
return []byte(pubKey)
}
func (pubKey PubKey) VerifyBytes(msg []byte, sig []byte) bool {
func (pubKey PubKey) VerifySignature(msg []byte, sig []byte) bool {
// make sure we use the same algorithm to sign
if len(sig) != SignatureSize {
return false

View File

@@ -20,11 +20,11 @@ func TestSignAndValidateEd25519(t *testing.T) {
require.Nil(t, err)
// Test the signature
assert.True(t, pubKey.VerifyBytes(msg, sig))
assert.True(t, pubKey.VerifySignature(msg, sig))
// Mutate the signature, just one bit.
// TODO: Replace this with a much better fuzzer, tendermint/ed25519/issues/10
sig[7] ^= byte(0x01)
assert.False(t, pubKey.VerifyBytes(msg, sig))
assert.False(t, pubKey.VerifySignature(msg, sig))
}

View File

@@ -57,7 +57,7 @@ func BenchmarkVerification(b *testing.B, priv crypto.PrivKey) {
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
pub.VerifyBytes(message, signature)
pub.VerifySignature(message, signature)
}
}

View File

@@ -18,6 +18,6 @@ func (privKey PrivKey) Sign(msg []byte) ([]byte, error) {
return rs, nil
}
func (pubKey PubKey) VerifyBytes(msg []byte, sig []byte) bool {
func (pubKey PubKey) VerifySignature(msg []byte, sig []byte) bool {
return secp256k1.VerifySignature(pubKey[:], crypto.Sha256(msg), sig)
}

View File

@@ -30,7 +30,7 @@ func (privKey PrivKey) Sign(msg []byte) ([]byte, error) {
// VerifyBytes verifies a signature of the form R || S.
// It rejects signatures which are not in lower-S form.
func (pubKey PubKey) VerifyBytes(msg []byte, sigStr []byte) bool {
func (pubKey PubKey) VerifySignature(msg []byte, sigStr []byte) bool {
if len(sigStr) != 64 {
return false
}

View File

@@ -22,14 +22,14 @@ func TestSignatureVerificationAndRejectUpperS(t *testing.T) {
require.False(t, sig.S.Cmp(secp256k1halfN) > 0)
pub := priv.PubKey()
require.True(t, pub.VerifyBytes(msg, sigStr))
require.True(t, pub.VerifySignature(msg, sigStr))
// malleate:
sig.S.Sub(secp256k1.S256().CurveParams.N, sig.S)
require.True(t, sig.S.Cmp(secp256k1halfN) > 0)
malSigStr := serializeSig(sig)
require.False(t, pub.VerifyBytes(msg, malSigStr),
require.False(t, pub.VerifySignature(msg, malSigStr),
"VerifyBytes incorrect with malleated & invalid S. sig=%v, key=%v",
sig,
priv,

View File

@@ -55,12 +55,12 @@ func TestSignAndValidateSecp256k1(t *testing.T) {
sig, err := privKey.Sign(msg)
require.Nil(t, err)
assert.True(t, pubKey.VerifyBytes(msg, sig))
assert.True(t, pubKey.VerifySignature(msg, sig))
// Mutate the signature, just one bit.
sig[3] ^= byte(0x01)
assert.False(t, pubKey.VerifyBytes(msg, sig))
assert.False(t, pubKey.VerifySignature(msg, sig))
}
// This test is intended to justify the removal of calls to the underlying library

View File

@@ -31,7 +31,7 @@ func (pubKey PubKey) Bytes() []byte {
return []byte(pubKey)
}
func (pubKey PubKey) VerifyBytes(msg []byte, sig []byte) bool {
func (pubKey PubKey) VerifySignature(msg []byte, sig []byte) bool {
// make sure we use the same algorithm to sign
if len(sig) != SignatureSize {
return false

View File

@@ -20,12 +20,12 @@ func TestSignAndValidateSr25519(t *testing.T) {
require.Nil(t, err)
// Test the signature
assert.True(t, pubKey.VerifyBytes(msg, sig))
assert.True(t, pubKey.VerifyBytes(msg, sig))
assert.True(t, pubKey.VerifySignature(msg, sig))
assert.True(t, pubKey.VerifySignature(msg, sig))
// Mutate the signature, just one bit.
// TODO: Replace this with a much better fuzzer, tendermint/ed25519/issues/10
sig[7] ^= byte(0x01)
assert.False(t, pubKey.VerifyBytes(msg, sig))
assert.False(t, pubKey.VerifySignature(msg, sig))
}

View File

@@ -170,7 +170,7 @@ func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey crypto.PrivKey) (*
if _, ok := remPubKey.(ed25519.PubKey); !ok {
return nil, fmt.Errorf("expected ed25519 pubkey, got %T", remPubKey)
}
if !remPubKey.VerifyBytes(challenge[:], remSignature) {
if !remPubKey.VerifySignature(challenge[:], remSignature) {
return nil, errors.New("challenge verification failed")
}

View File

@@ -145,7 +145,7 @@ func TestBroadcastEvidence_DuplicateVoteEvidence(t *testing.T) {
pk, err := cryptoenc.PubKeyFromProto(v.PubKey)
require.NoError(t, err)
require.EqualValues(t, rawpub, pk.Bytes(), "Stored PubKey not equal with expected, value %v", string(qres.Value))
require.EqualValues(t, rawpub, pk, "Stored PubKey not equal with expected, value %v", string(qres.Value))
require.Equal(t, int64(9), v.Power, "Stored Power not equal with expected, value %v", string(qres.Value))
for _, fake := range fakes {

View File

@@ -247,7 +247,7 @@ func (th *TestHarness) TestSignProposal() error {
return err
}
// now validate the signature on the proposal
if sck.VerifyBytes(propBytes, prop.Signature) {
if sck.VerifySignature(propBytes, prop.Signature) {
th.logger.Info("Successfully validated proposal signature")
} else {
th.logger.Error("FAILED: Proposal signature validation failed")
@@ -298,7 +298,7 @@ func (th *TestHarness) TestSignVote() error {
}
// now validate the signature on the proposal
if sck.VerifyBytes(voteBytes, vote.Signature) {
if sck.VerifySignature(voteBytes, vote.Signature) {
th.logger.Info("Successfully validated vote signature", "type", voteType)
} else {
th.logger.Error("FAILED: Vote signature validation failed", "type", voteType)

View File

@@ -290,10 +290,10 @@ func (dve *DuplicateVoteEvidence) Verify(chainID string, pubKey crypto.PubKey) e
va := dve.VoteA.ToProto()
vb := dve.VoteB.ToProto()
// Signatures must be valid
if !pubKey.VerifyBytes(VoteSignBytes(chainID, va), dve.VoteA.Signature) {
if !pubKey.VerifySignature(VoteSignBytes(chainID, va), dve.VoteA.Signature) {
return fmt.Errorf("verifying VoteA: %w", ErrVoteInvalidSignature)
}
if !pubKey.VerifyBytes(VoteSignBytes(chainID, vb), dve.VoteB.Signature) {
if !pubKey.VerifySignature(VoteSignBytes(chainID, vb), dve.VoteB.Signature) {
return fmt.Errorf("verifying VoteB: %w", ErrVoteInvalidSignature)
}
@@ -724,7 +724,7 @@ func (e *LunaticValidatorEvidence) Verify(chainID string, pubKey crypto.PubKey)
}
v := e.Vote.ToProto()
if !pubKey.VerifyBytes(VoteSignBytes(chainID, v), e.Vote.Signature) {
if !pubKey.VerifySignature(VoteSignBytes(chainID, v), e.Vote.Signature) {
return errors.New("invalid signature")
}
@@ -948,10 +948,10 @@ func (e *PotentialAmnesiaEvidence) Verify(chainID string, pubKey crypto.PubKey)
vb := e.VoteB.ToProto()
// Signatures must be valid
if !pubKey.VerifyBytes(VoteSignBytes(chainID, va), e.VoteA.Signature) {
if !pubKey.VerifySignature(VoteSignBytes(chainID, va), e.VoteA.Signature) {
return fmt.Errorf("verifying VoteA: %w", ErrVoteInvalidSignature)
}
if !pubKey.VerifyBytes(VoteSignBytes(chainID, vb), e.VoteB.Signature) {
if !pubKey.VerifySignature(VoteSignBytes(chainID, vb), e.VoteB.Signature) {
return fmt.Errorf("verifying VoteB: %w", ErrVoteInvalidSignature)
}
@@ -1145,7 +1145,7 @@ func (e *ProofOfLockChange) ValidateVotes(valSet *ValidatorSet, chainID string)
if bytes.Equal(validator.Address, vote.ValidatorAddress) {
exists = true
v := vote.ToProto()
if !validator.PubKey.VerifyBytes(VoteSignBytes(chainID, v), vote.Signature) {
if !validator.PubKey.VerifySignature(VoteSignBytes(chainID, v), vote.Signature) {
return fmt.Errorf("cannot verify vote (from validator: %d) against signature: %v",
vote.ValidatorIndex, vote.Signature)
}

View File

@@ -71,7 +71,7 @@ func TestProposalVerifySignature(t *testing.T) {
prop.Signature = p.Signature
// verify the same proposal
valid := pubKey.VerifyBytes(signBytes, prop.Signature)
valid := pubKey.VerifySignature(signBytes, prop.Signature)
require.True(t, valid)
// serialize, deserialize and verify again....
@@ -90,7 +90,7 @@ func TestProposalVerifySignature(t *testing.T) {
// verify the transmitted proposal
newSignBytes := ProposalSignBytes("test_chain_id", pb)
require.Equal(t, string(signBytes), string(newSignBytes))
valid = pubKey.VerifyBytes(newSignBytes, np.Signature)
valid = pubKey.VerifySignature(newSignBytes, np.Signature)
require.True(t, valid)
}
@@ -118,7 +118,7 @@ func BenchmarkProposalVerifySignature(b *testing.B) {
require.NoError(b, err)
for i := 0; i < b.N; i++ {
pubKey.VerifyBytes(ProposalSignBytes("test_chain_id", pbp), testProposal.Signature)
pubKey.VerifySignature(ProposalSignBytes("test_chain_id", pbp), testProposal.Signature)
}
}

View File

@@ -84,12 +84,12 @@ func TestABCIEvidence(t *testing.T) {
type pubKeyEddie struct{}
func (pubKeyEddie) Address() Address { return []byte{} }
func (pubKeyEddie) Bytes() []byte { return []byte{} }
func (pubKeyEddie) VerifyBytes(msg []byte, sig []byte) bool { return false }
func (pubKeyEddie) Equals(crypto.PubKey) bool { return false }
func (pubKeyEddie) String() string { return "" }
func (pubKeyEddie) Type() string { return "pubKeyEddie" }
func (pubKeyEddie) Address() Address { return []byte{} }
func (pubKeyEddie) Bytes() []byte { return []byte{} }
func (pubKeyEddie) VerifySignature(msg []byte, sig []byte) bool { return false }
func (pubKeyEddie) Equals(crypto.PubKey) bool { return false }
func (pubKeyEddie) String() string { return "" }
func (pubKeyEddie) Type() string { return "pubKeyEddie" }
func TestABCIValidatorFromPubKeyAndPower(t *testing.T) {
pubkey := ed25519.GenPrivKey().PubKey()

View File

@@ -688,7 +688,7 @@ func (vals *ValidatorSet) VerifyCommit(chainID string, blockID BlockID,
// Validate signature.
voteSignBytes := commit.VoteSignBytes(chainID, int32(idx))
if !val.PubKey.VerifyBytes(voteSignBytes, commitSig.Signature) {
if !val.PubKey.VerifySignature(voteSignBytes, commitSig.Signature) {
return fmt.Errorf("wrong signature (#%d): %X", idx, commitSig.Signature)
}
// Good!
@@ -746,7 +746,7 @@ func (vals *ValidatorSet) VerifyCommitLight(chainID string, blockID BlockID,
// Validate signature.
voteSignBytes := commit.VoteSignBytes(chainID, int32(idx))
if !val.PubKey.VerifyBytes(voteSignBytes, commitSig.Signature) {
if !val.PubKey.VerifySignature(voteSignBytes, commitSig.Signature) {
return fmt.Errorf("wrong signature (#%d): %X", idx, commitSig.Signature)
}
@@ -807,7 +807,7 @@ func (vals *ValidatorSet) VerifyCommitLightTrusting(chainID string, commit *Comm
// Validate signature.
voteSignBytes := commit.VoteSignBytes(chainID, int32(idx))
if !val.PubKey.VerifyBytes(voteSignBytes, commitSig.Signature) {
if !val.PubKey.VerifySignature(voteSignBytes, commitSig.Signature) {
return fmt.Errorf("wrong signature (#%d): %X", idx, commitSig.Signature)
}

View File

@@ -149,7 +149,7 @@ func (vote *Vote) Verify(chainID string, pubKey crypto.PubKey) error {
return ErrVoteInvalidValidatorAddress
}
v := vote.ToProto()
if !pubKey.VerifyBytes(VoteSignBytes(chainID, v), vote.Signature) {
if !pubKey.VerifySignature(VoteSignBytes(chainID, v), vote.Signature) {
return ErrVoteInvalidSignature
}
return nil

View File

@@ -161,7 +161,7 @@ func TestVoteVerifySignature(t *testing.T) {
require.NoError(t, err)
// verify the same vote
valid := pubkey.VerifyBytes(VoteSignBytes("test_chain_id", v), v.Signature)
valid := pubkey.VerifySignature(VoteSignBytes("test_chain_id", v), v.Signature)
require.True(t, valid)
// serialize, deserialize and verify again....
@@ -174,7 +174,7 @@ func TestVoteVerifySignature(t *testing.T) {
// verify the transmitted vote
newSignBytes := VoteSignBytes("test_chain_id", precommit)
require.Equal(t, string(signBytes), string(newSignBytes))
valid = pubkey.VerifyBytes(newSignBytes, precommit.Signature)
valid = pubkey.VerifySignature(newSignBytes, precommit.Signature)
require.True(t, valid)
}