From db85f052c2bd581e93689f61239803ecbc358a5e Mon Sep 17 00:00:00 2001 From: 1garo Date: Fri, 19 Nov 2021 22:40:23 -0300 Subject: [PATCH 01/40] chore: delete sig verifier from runtime pkg --- lib/runtime/sig_verifier.go | 184 ------------------------------------ 1 file changed, 184 deletions(-) delete mode 100644 lib/runtime/sig_verifier.go diff --git a/lib/runtime/sig_verifier.go b/lib/runtime/sig_verifier.go deleted file mode 100644 index 5e1e8c59ad..0000000000 --- a/lib/runtime/sig_verifier.go +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright 2021 ChainSafe Systems (ON) -// SPDX-License-Identifier: LGPL-3.0-only - -package runtime - -import ( - "fmt" - "sync" - "time" - - "github.com/ChainSafe/gossamer/internal/log" - "github.com/ChainSafe/gossamer/lib/crypto" - "github.com/ChainSafe/gossamer/lib/crypto/ed25519" - "github.com/ChainSafe/gossamer/lib/crypto/sr25519" - "github.com/ethereum/go-ethereum/crypto/secp256k1" -) - -// Signature ... -type Signature struct { - PubKey []byte - Sign []byte - Msg []byte - KeyTypeID crypto.KeyType -} - -// SignatureVerifier ... -type SignatureVerifier struct { - batch []*Signature - init bool // Indicates whether the batch processing is started. - invalid bool // Set to true if any signature verification fails. - logger log.LeveledLogger - closeCh chan struct{} - sync.RWMutex - sync.Once - sync.WaitGroup -} - -// NewSignatureVerifier initialises SignatureVerifier which does background verification of signatures. -// Start() is called to start the verification process. -// Finish() is called to stop the verification process. -// Signatures can be added to the batch using Add(). -func NewSignatureVerifier(logger log.LeveledLogger) *SignatureVerifier { - return &SignatureVerifier{ - batch: make([]*Signature, 0), - init: false, - invalid: false, - logger: logger, - RWMutex: sync.RWMutex{}, - closeCh: make(chan struct{}), - } -} - -// Start signature verification in batch. -func (sv *SignatureVerifier) Start() { - // Update the init state. - sv.Lock() - sv.init = true - sv.Unlock() - - sv.WaitGroup.Add(1) - - go func() { - defer sv.Done() - for { - select { - case <-sv.closeCh: - return - default: - sign := sv.Remove() - if sign == nil { - continue - } - err := sign.verify() - if err != nil { - sv.logger.Errorf("[ext_crypto_start_batch_verify_version_1]: %s", err) - sv.Invalid() - return - } - } - } - }() -} - -// IsStarted ... -func (sv *SignatureVerifier) IsStarted() bool { - sv.RLock() - defer sv.RUnlock() - return sv.init -} - -// IsInvalid ... -func (sv *SignatureVerifier) IsInvalid() bool { - sv.RLock() - defer sv.RUnlock() - return sv.invalid -} - -// Invalid ... -func (sv *SignatureVerifier) Invalid() { - sv.RLock() - defer sv.RUnlock() - sv.invalid = true -} - -// Add ... -func (sv *SignatureVerifier) Add(s *Signature) { - if sv.IsInvalid() { - return - } - - sv.Lock() - defer sv.Unlock() - sv.batch = append(sv.batch, s) -} - -// Remove returns the first signature from the batch. Returns nil if batch is empty. -func (sv *SignatureVerifier) Remove() *Signature { - sv.Lock() - defer sv.Unlock() - if len(sv.batch) == 0 { - return nil - } - sign := sv.batch[0] - sv.batch = sv.batch[1:len(sv.batch)] - return sign -} - -// Reset reset the signature verifier for reuse. -func (sv *SignatureVerifier) Reset() { - sv.Lock() - defer sv.Unlock() - sv.init = false - sv.batch = make([]*Signature, 0) - sv.invalid = false - sv.closeCh = make(chan struct{}) -} - -// Finish waits till batch is finished. Returns true if all the signatures are valid, Otherwise returns false. -func (sv *SignatureVerifier) Finish() bool { - for { - time.Sleep(100 * time.Millisecond) - sv.Lock() - if sv.invalid || len(sv.batch) == 0 { - close(sv.closeCh) - sv.Unlock() - break - } - sv.RUnlock() - } - // Wait till start function to finish and then reset it. - sv.Wait() - isInvalid := sv.IsInvalid() - sv.Reset() - return !isInvalid -} - -func (sig *Signature) verify() error { - switch sig.KeyTypeID { - case crypto.Ed25519Type: - pubKey, err := ed25519.NewPublicKey(sig.PubKey) - if err != nil { - return fmt.Errorf("failed to fetch ed25519 public key: %s", err) - } - ok, err := pubKey.Verify(sig.Msg, sig.Sign) - if err != nil || !ok { - return fmt.Errorf("failed to verify ed25519 signature: %s", err) - } - case crypto.Sr25519Type: - pubKey, err := sr25519.NewPublicKey(sig.PubKey) - if err != nil { - return fmt.Errorf("failed to fetch sr25519 public key: %s", err) - } - ok, err := pubKey.Verify(sig.Msg, sig.Sign) - if err != nil || !ok { - return fmt.Errorf("failed to verify sr25519 signature: %s", err) - } - case crypto.Secp256k1Type: - ok := secp256k1.VerifySignature(sig.PubKey, sig.Msg, sig.Sign) - if !ok { - return fmt.Errorf("failed to verify secp256k1 signature") - } - } - return nil -} From eda4236f8a40605011010377d35e1a8e68c77276 Mon Sep 17 00:00:00 2001 From: 1garo Date: Fri, 19 Nov 2021 22:41:36 -0300 Subject: [PATCH 02/40] feat: implement SignVerify for sr25519 --- lib/crypto/sr25519/sr25519.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/crypto/sr25519/sr25519.go b/lib/crypto/sr25519/sr25519.go index 351cf79c09..aa59c4e988 100644 --- a/lib/crypto/sr25519/sr25519.go +++ b/lib/crypto/sr25519/sr25519.go @@ -6,6 +6,7 @@ package sr25519 import ( "encoding/hex" "errors" + "fmt" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/crypto" @@ -43,6 +44,20 @@ type PrivateKey struct { key *sr25519.SecretKey } +// SignVerify verify signature given pubkey and msg +func SignVerify(pubkey, sig, msg []byte) (bool, error) { + pubKey, err := NewPublicKey(pubkey) + if err != nil { + return false, fmt.Errorf("failed to fetch sr25519 public key: %s", err) + } + ok, err := pubKey.Verify(msg, sig) + if err != nil || !ok { + return false, fmt.Errorf("failed to verify sr25519 signature: %s", err) + } + + return true, nil +} + // NewKeypair returns a sr25519 Keypair given a schnorrkel secret key func NewKeypair(priv *sr25519.SecretKey) (*Keypair, error) { pub, err := priv.Public() From ed89c506e87da5a1f61c80ee88ba60bf58f5ad85 Mon Sep 17 00:00:00 2001 From: 1garo Date: Fri, 19 Nov 2021 22:41:51 -0300 Subject: [PATCH 03/40] feat: implement SignVerify for ed25519 --- lib/crypto/ed25519/ed25519.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/crypto/ed25519/ed25519.go b/lib/crypto/ed25519/ed25519.go index b91e5e9af8..9c8ae11377 100644 --- a/lib/crypto/ed25519/ed25519.go +++ b/lib/crypto/ed25519/ed25519.go @@ -44,6 +44,20 @@ type PublicKey ed25519.PublicKey // PublicKeyBytes is an encoded ed25519 public key type PublicKeyBytes [PublicKeyLength]byte +// SignVerify verify signature given pubkey and msg +func SignVerify(pubkey, sig, msg []byte) (bool, error) { + pubKey, err := NewPublicKey(pubkey) + if err != nil { + return false, fmt.Errorf("failed to fetch ed25519 public key: %s", err) + } + ok, err := pubKey.Verify(msg, sig) + if err != nil || !ok { + return false, fmt.Errorf("failed to verify ed25519 signature: %s", err) + } + + return true, nil +} + // String returns the PublicKeyBytes formatted as a hex string func (b PublicKeyBytes) String() string { pk := [PublicKeyLength]byte(b) From 6f41dfcb1f4306d4291813bceb1ae4d27ba5fdbb Mon Sep 17 00:00:00 2001 From: 1garo Date: Fri, 19 Nov 2021 22:42:23 -0300 Subject: [PATCH 04/40] feat: implement SignVerify for srcp256k1 --- lib/crypto/secp256k1/secp256k1.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/crypto/secp256k1/secp256k1.go b/lib/crypto/secp256k1/secp256k1.go index 29dccfeb2c..f64ffe63ce 100644 --- a/lib/crypto/secp256k1/secp256k1.go +++ b/lib/crypto/secp256k1/secp256k1.go @@ -7,6 +7,7 @@ import ( "crypto/ecdsa" "encoding/hex" "errors" + "fmt" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/crypto" @@ -36,6 +37,16 @@ type PublicKey struct { key ecdsa.PublicKey } +// SignVerify verify signature given pubkey and msg +func SignVerify(pubkey, sig, msg []byte) (bool, error) { + ok := secp256k1.VerifySignature(pubkey, msg, sig) + if !ok { + return false, fmt.Errorf("failed to verify secp256k1 signature") + } + + return true, nil +} + // RecoverPublicKey returns the 64-byte uncompressed public key that created the given signature. func RecoverPublicKey(msg, sig []byte) ([]byte, error) { // update recovery bit From 73e8d87cec25452505c15e97bce4d6eafa9b7a77 Mon Sep 17 00:00:00 2001 From: 1garo Date: Fri, 19 Nov 2021 22:42:53 -0300 Subject: [PATCH 05/40] fix: move sig_verifier to crypto pkg --- lib/crypto/sig_verifier.go | 152 +++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 lib/crypto/sig_verifier.go diff --git a/lib/crypto/sig_verifier.go b/lib/crypto/sig_verifier.go new file mode 100644 index 0000000000..e4a32a3fda --- /dev/null +++ b/lib/crypto/sig_verifier.go @@ -0,0 +1,152 @@ +// Copyright 2021 ChainSafe Systems (ON) +// SPDX-License-Identifier: LGPL-3.0-only + +package crypto + +import ( + "sync" + "time" + + "github.com/ChainSafe/gossamer/internal/log" +) + +type SigVerifyFunc func(pubkey, sig, msg []byte) (bool, error) + +// Signature ... +type Signature struct { + PubKey []byte + Sign []byte + Msg []byte + VerifyFunc SigVerifyFunc +} + +// SignatureVerifier ... +type SignatureVerifier struct { + batch []*Signature + init bool // Indicates whether the batch processing is started. + invalid bool // Set to true if any signature verification fails. + logger log.LeveledLogger + closeCh chan struct{} + sync.RWMutex + sync.Once + sync.WaitGroup +} + +// NewSignatureVerifier initialises SignatureVerifier which does background verification of signatures. +// Start() is called to start the verification process. +// Finish() is called to stop the verification process. +// Signatures can be added to the batch using Add(). +func NewSignatureVerifier(logger log.LeveledLogger) *SignatureVerifier { + return &SignatureVerifier{ + batch: make([]*Signature, 0), + init: false, + invalid: false, + logger: logger, + RWMutex: sync.RWMutex{}, + closeCh: make(chan struct{}), + } +} + +// Start signature verification in batch. +func (sv *SignatureVerifier) Start() { + // Update the init state. + sv.Lock() + sv.init = true + sv.Unlock() + + sv.WaitGroup.Add(1) + + go func() { + defer sv.Done() + for { + select { + case <-sv.closeCh: + return + default: + sig := sv.Remove() + if sig == nil { + continue + } + ok, err := sig.VerifyFunc(sig.PubKey, sig.Sign, sig.Msg) + if err != nil || !ok { + sv.logger.Errorf("[ext_crypto_start_batch_verify_version_1]: %s", err) + sv.Invalid() + return + } + } + } + }() +} + +// IsStarted ... +func (sv *SignatureVerifier) IsStarted() bool { + sv.RLock() + defer sv.RUnlock() + return sv.init +} + +// IsInvalid ... +func (sv *SignatureVerifier) IsInvalid() bool { + sv.RLock() + defer sv.RUnlock() + return sv.invalid +} + +// Invalid ... +func (sv *SignatureVerifier) Invalid() { + sv.RLock() + defer sv.RUnlock() + sv.invalid = true +} + +// Add ... +func (sv *SignatureVerifier) Add(s *Signature) { + if sv.IsInvalid() { + return + } + + sv.Lock() + defer sv.Unlock() + sv.batch = append(sv.batch, s) +} + +// Remove returns the first signature from the batch. Returns nil if batch is empty. +func (sv *SignatureVerifier) Remove() *Signature { + sv.Lock() + defer sv.Unlock() + if len(sv.batch) == 0 { + return nil + } + sign := sv.batch[0] + sv.batch = sv.batch[1:len(sv.batch)] + return sign +} + +// Reset reset the signature verifier for reuse. +func (sv *SignatureVerifier) Reset() { + sv.Lock() + defer sv.Unlock() + sv.init = false + sv.batch = make([]*Signature, 0) + sv.invalid = false + sv.closeCh = make(chan struct{}) +} + +// Finish waits till batch is finished. Returns true if all the signatures are valid, Otherwise returns false. +func (sv *SignatureVerifier) Finish() bool { + for { + time.Sleep(100 * time.Millisecond) + sv.Lock() + if sv.invalid || len(sv.batch) == 0 { + close(sv.closeCh) + sv.Unlock() + break + } + sv.RUnlock() + } + // Wait till start function to finish and then reset it. + sv.Wait() + isInvalid := sv.IsInvalid() + sv.Reset() + return !isInvalid +} From 11b60168386841cb1d1c20ed2e0e80842a94621d Mon Sep 17 00:00:00 2001 From: 1garo Date: Fri, 19 Nov 2021 22:44:09 -0300 Subject: [PATCH 06/40] chore: update usages for crypto pkg --- lib/runtime/life/instance.go | 3 ++- lib/runtime/life/resolver.go | 20 ++++++++--------- lib/runtime/test_helpers.go | 17 ++++++++------- lib/runtime/types.go | 3 ++- lib/runtime/types_test.go | 40 +++++++++++++++++----------------- lib/runtime/wasmer/imports.go | 22 +++++++++---------- lib/runtime/wasmer/instance.go | 4 +++- 7 files changed, 57 insertions(+), 52 deletions(-) diff --git a/lib/runtime/life/instance.go b/lib/runtime/life/instance.go index ec22bf7eb3..d0d65a3b29 100644 --- a/lib/runtime/life/instance.go +++ b/lib/runtime/life/instance.go @@ -14,6 +14,7 @@ import ( "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/keystore" "github.com/ChainSafe/gossamer/lib/runtime" + "github.com/ChainSafe/gossamer/lib/crypto" "github.com/perlin-network/life/exec" wasm_validation "github.com/perlin-network/life/wasm-validation" @@ -112,7 +113,7 @@ func NewInstance(code []byte, cfg *Config) (*Instance, error) { NodeStorage: cfg.NodeStorage, Network: cfg.Network, Transaction: cfg.Transaction, - SigVerifier: runtime.NewSignatureVerifier(logger), + SigVerifier: crypto.NewSignatureVerifier(logger), } logger.Debugf("creating new runtime instance with context: %v", runtimeCtx) diff --git a/lib/runtime/life/resolver.go b/lib/runtime/life/resolver.go index f85a08d2dc..f1b60b26af 100644 --- a/lib/runtime/life/resolver.go +++ b/lib/runtime/life/resolver.go @@ -933,11 +933,11 @@ func ext_crypto_ed25519_verify_version_1(vm *exec.VirtualMachine) int64 { } if sigVerifier.IsStarted() { - signature := runtime.Signature{ - PubKey: pubKey.Encode(), - Sign: signature, - Msg: message, - KeyTypeID: crypto.Ed25519Type, + signature := crypto.Signature{ + PubKey: pubKey.Encode(), + Sign: signature, + Msg: message, + VerifyFunc: ed25519.SignVerify, } sigVerifier.Add(&signature) return 1 @@ -1120,11 +1120,11 @@ func ext_crypto_sr25519_verify_version_1(vm *exec.VirtualMachine) int64 { pub.Hex(), message, signature) if sigVerifier.IsStarted() { - signature := runtime.Signature{ - PubKey: pub.Encode(), - Sign: signature, - Msg: message, - KeyTypeID: crypto.Sr25519Type, + signature := crypto.Signature{ + PubKey: pub.Encode(), + Sign: signature, + Msg: message, + VerifyFunc: sr25519.SignVerify, } sigVerifier.Add(&signature) return 1 diff --git a/lib/runtime/test_helpers.go b/lib/runtime/test_helpers.go index 4da3c3b963..812eb41ae9 100644 --- a/lib/runtime/test_helpers.go +++ b/lib/runtime/test_helpers.go @@ -12,9 +12,10 @@ import ( "testing" "time" + "github.com/ChainSafe/gossamer/lib/crypto" + "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/lib/common" - "github.com/ChainSafe/gossamer/lib/crypto" "github.com/ChainSafe/gossamer/lib/crypto/ed25519" "github.com/ChainSafe/gossamer/lib/utils" ma "github.com/multiformats/go-multiaddr" @@ -115,9 +116,9 @@ func (*TestRuntimeNetwork) NetworkState() common.NetworkState { } } -func generateEd25519Signatures(t *testing.T, n int) []*Signature { +func generateEd25519Signatures(t *testing.T, n int) []*crypto.Signature { t.Helper() - signs := make([]*Signature, n) + signs := make([]*crypto.Signature, n) for i := 0; i < n; i++ { msg := []byte("Hello") key, err := ed25519.GenerateKeypair() @@ -126,11 +127,11 @@ func generateEd25519Signatures(t *testing.T, n int) []*Signature { sign, err := key.Private().Sign(msg) require.NoError(t, err) - signs[i] = &Signature{ - PubKey: key.Public().Encode(), - Sign: sign, - Msg: msg, - KeyTypeID: crypto.Ed25519Type, + signs[i] = &crypto.Signature{ + PubKey: key.Public().Encode(), + Sign: sign, + Msg: msg, + VerifyFunc: ed25519.SignVerify, } } return signs diff --git a/lib/runtime/types.go b/lib/runtime/types.go index b246920ddb..312be14058 100644 --- a/lib/runtime/types.go +++ b/lib/runtime/types.go @@ -6,6 +6,7 @@ package runtime import ( "github.com/ChainSafe/gossamer/internal/log" "github.com/ChainSafe/gossamer/lib/common" + "github.com/ChainSafe/gossamer/lib/crypto" "github.com/ChainSafe/gossamer/lib/keystore" "github.com/ChainSafe/gossamer/lib/runtime/offchain" ) @@ -67,7 +68,7 @@ type Context struct { NodeStorage NodeStorage Network BasicNetwork Transaction TransactionState - SigVerifier *SignatureVerifier + SigVerifier *crypto.SignatureVerifier OffchainHTTPSet *offchain.HTTPSet } diff --git a/lib/runtime/types_test.go b/lib/runtime/types_test.go index b8295542e2..5dacc6aa60 100644 --- a/lib/runtime/types_test.go +++ b/lib/runtime/types_test.go @@ -19,7 +19,7 @@ import ( func TestBackgroundSignVerification(t *testing.T) { signs := generateEd25519Signatures(t, 2) - signVerify := NewSignatureVerifier(log.New(log.SetWriter(io.Discard))) + signVerify := crypto.NewSignatureVerifier(log.New(log.SetWriter(io.Discard))) signVerify.Start() @@ -34,7 +34,7 @@ func TestBackgroundSignVerification(t *testing.T) { func TestBackgroundSignVerificationMultipleStart(t *testing.T) { signs := generateEd25519Signatures(t, 2) - signVerify := NewSignatureVerifier(log.New(log.SetWriter(io.Discard))) + signVerify := crypto.NewSignatureVerifier(log.New(log.SetWriter(io.Discard))) for ii := 0; ii < 5; ii++ { require.False(t, signVerify.IsStarted()) @@ -60,16 +60,16 @@ func TestInvalidSignatureBatch(t *testing.T) { sigData, err := common.HexToBytes("0x90f27b8b488db00b00606796d2987f6a5f59ae62ea05effe84fef5b8b0e549984a691139ad57a3f0b906637673aa2f63d1f55cb1a69199d4009eea23ceaddc9301") require.Nil(t, err) - signature := &Signature{ - PubKey: key.Public().Encode(), - Sign: sigData, - Msg: msg, - KeyTypeID: crypto.Ed25519Type, + signature := &crypto.Signature{ + PubKey: key.Public().Encode(), + Sign: sigData, + Msg: msg, + VerifyFunc: ed25519.SignVerify, } signs = append(signs, signature) - signVerify := NewSignatureVerifier(log.New(log.SetWriter(io.Discard))) + signVerify := crypto.NewSignatureVerifier(log.New(log.SetWriter(io.Discard))) signVerify.Start() for _, sig := range signs { @@ -80,7 +80,7 @@ func TestInvalidSignatureBatch(t *testing.T) { func TestValidSignatureBatch(t *testing.T) { signs := generateEd25519Signatures(t, 2) - signVerify := NewSignatureVerifier(log.New(log.SetWriter(io.Discard))) + signVerify := crypto.NewSignatureVerifier(log.New(log.SetWriter(io.Discard))) signVerify.Start() @@ -101,11 +101,11 @@ func TestAllCryptoTypeSignature(t *testing.T) { srSig, err := srKey.Private().Sign(srMsg) require.NoError(t, err) - srSignature := &Signature{ - PubKey: srKey.Public().Encode(), - Sign: srSig, - Msg: srMsg, - KeyTypeID: crypto.Sr25519Type, + srSignature := &crypto.Signature{ + PubKey: srKey.Public().Encode(), + Sign: srSig, + Msg: srMsg, + VerifyFunc: sr25519.SignVerify, } blakeHash, err := common.Blake2bHash([]byte("secp256k1")) @@ -118,14 +118,14 @@ func TestAllCryptoTypeSignature(t *testing.T) { require.NoError(t, err) secpSigData = secpSigData[:len(secpSigData)-1] // remove recovery id - secpSignature := &Signature{ - PubKey: kp.Public().Encode(), - Sign: secpSigData, - Msg: blakeHash.ToBytes(), - KeyTypeID: crypto.Secp256k1Type, + secpSignature := &crypto.Signature{ + PubKey: kp.Public().Encode(), + Sign: secpSigData, + Msg: blakeHash.ToBytes(), + VerifyFunc: secp256k1.SignVerify, } - signVerify := NewSignatureVerifier(log.New(log.SetWriter(io.Discard))) + signVerify := crypto.NewSignatureVerifier(log.New(log.SetWriter(io.Discard))) signVerify.Start() diff --git a/lib/runtime/wasmer/imports.go b/lib/runtime/wasmer/imports.go index b3f292d652..3c1a62bd35 100644 --- a/lib/runtime/wasmer/imports.go +++ b/lib/runtime/wasmer/imports.go @@ -383,11 +383,11 @@ func ext_crypto_ed25519_verify_version_1(context unsafe.Pointer, sig C.int32_t, } if sigVerifier.IsStarted() { - signature := runtime.Signature{ - PubKey: pubKey.Encode(), - Sign: signature, - Msg: message, - KeyTypeID: crypto.Ed25519Type, + signature := crypto.Signature{ + PubKey: pubKey.Encode(), + Sign: signature, + Msg: message, + VerifyFunc: ed25519.SignVerify, } sigVerifier.Add(&signature) return 1 @@ -474,11 +474,11 @@ func ext_crypto_ecdsa_verify_version_2(context unsafe.Pointer, sig C.int32_t, ms } if sigVerifier.IsStarted() { - signature := runtime.Signature{ + signature := crypto.Signature{ PubKey: pub.Encode(), Sign: signature, Msg: hash[:], - KeyTypeID: crypto.Secp256k1Type, + VerifyFunc: secp256k1.SignVerify, } sigVerifier.Add(&signature) return C.int32_t(1) @@ -700,11 +700,11 @@ func ext_crypto_sr25519_verify_version_1(context unsafe.Pointer, sig C.int32_t, pub.Hex(), message, signature) if sigVerifier.IsStarted() { - signature := runtime.Signature{ + signature := crypto.Signature{ PubKey: pub.Encode(), Sign: signature, Msg: message, - KeyTypeID: crypto.Sr25519Type, + VerifyFunc: sr25519.SignVerify, } sigVerifier.Add(&signature) return 1 @@ -742,11 +742,11 @@ func ext_crypto_sr25519_verify_version_2(context unsafe.Pointer, sig C.int32_t, pub.Hex(), message, signature) if sigVerifier.IsStarted() { - signature := runtime.Signature{ + signature := crypto.Signature{ PubKey: pub.Encode(), Sign: signature, Msg: message, - KeyTypeID: crypto.Sr25519Type, + VerifyFunc: sr25519.SignVerify, } sigVerifier.Add(&signature) return 1 diff --git a/lib/runtime/wasmer/instance.go b/lib/runtime/wasmer/instance.go index 303fc93901..7c87ceb287 100644 --- a/lib/runtime/wasmer/instance.go +++ b/lib/runtime/wasmer/instance.go @@ -15,6 +15,8 @@ import ( "github.com/ChainSafe/gossamer/lib/runtime/offchain" "github.com/ChainSafe/gossamer/lib/trie" + "github.com/ChainSafe/gossamer/lib/crypto" + wasm "github.com/wasmerio/go-ext-wasm/wasmer" ) @@ -137,7 +139,7 @@ func NewInstance(code []byte, cfg *Config) (*Instance, error) { NodeStorage: cfg.NodeStorage, Network: cfg.Network, Transaction: cfg.Transaction, - SigVerifier: runtime.NewSignatureVerifier(logger), + SigVerifier: crypto.NewSignatureVerifier(logger), OffchainHTTPSet: offchain.NewHTTPSet(), } From 63a34425dc9d3b26ef2ec35142ba144e78d96349 Mon Sep 17 00:00:00 2001 From: 1garo Date: Fri, 19 Nov 2021 22:57:41 -0300 Subject: [PATCH 07/40] fix: resolve lint problem --- lib/runtime/life/instance.go | 2 +- lib/runtime/wasmer/imports.go | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/runtime/life/instance.go b/lib/runtime/life/instance.go index d0d65a3b29..f5d50f2732 100644 --- a/lib/runtime/life/instance.go +++ b/lib/runtime/life/instance.go @@ -12,9 +12,9 @@ import ( "github.com/ChainSafe/gossamer/internal/log" "github.com/ChainSafe/gossamer/lib/common" + "github.com/ChainSafe/gossamer/lib/crypto" "github.com/ChainSafe/gossamer/lib/keystore" "github.com/ChainSafe/gossamer/lib/runtime" - "github.com/ChainSafe/gossamer/lib/crypto" "github.com/perlin-network/life/exec" wasm_validation "github.com/perlin-network/life/wasm-validation" diff --git a/lib/runtime/wasmer/imports.go b/lib/runtime/wasmer/imports.go index 3c1a62bd35..df90a15dd9 100644 --- a/lib/runtime/wasmer/imports.go +++ b/lib/runtime/wasmer/imports.go @@ -475,9 +475,9 @@ func ext_crypto_ecdsa_verify_version_2(context unsafe.Pointer, sig C.int32_t, ms if sigVerifier.IsStarted() { signature := crypto.Signature{ - PubKey: pub.Encode(), - Sign: signature, - Msg: hash[:], + PubKey: pub.Encode(), + Sign: signature, + Msg: hash[:], VerifyFunc: secp256k1.SignVerify, } sigVerifier.Add(&signature) @@ -701,9 +701,9 @@ func ext_crypto_sr25519_verify_version_1(context unsafe.Pointer, sig C.int32_t, if sigVerifier.IsStarted() { signature := crypto.Signature{ - PubKey: pub.Encode(), - Sign: signature, - Msg: message, + PubKey: pub.Encode(), + Sign: signature, + Msg: message, VerifyFunc: sr25519.SignVerify, } sigVerifier.Add(&signature) @@ -743,9 +743,9 @@ func ext_crypto_sr25519_verify_version_2(context unsafe.Pointer, sig C.int32_t, if sigVerifier.IsStarted() { signature := crypto.Signature{ - PubKey: pub.Encode(), - Sign: signature, - Msg: message, + PubKey: pub.Encode(), + Sign: signature, + Msg: message, VerifyFunc: sr25519.SignVerify, } sigVerifier.Add(&signature) From 969efc235423c055a952b89d08ac8c8ffb7bfa1a Mon Sep 17 00:00:00 2001 From: 1garo Date: Sat, 20 Nov 2021 11:51:04 -0300 Subject: [PATCH 08/40] chore: add comment on exported type --- lib/crypto/sig_verifier.go | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/crypto/sig_verifier.go b/lib/crypto/sig_verifier.go index e4a32a3fda..31187bcc01 100644 --- a/lib/crypto/sig_verifier.go +++ b/lib/crypto/sig_verifier.go @@ -10,6 +10,7 @@ import ( "github.com/ChainSafe/gossamer/internal/log" ) +// SigVerifyFunc verify an signature given a pubkey and msg type SigVerifyFunc func(pubkey, sig, msg []byte) (bool, error) // Signature ... From 9146c3700f8948cc4a69494c9c22cfc079d07526 Mon Sep 17 00:00:00 2001 From: 1garo Date: Tue, 23 Nov 2021 20:34:48 -0300 Subject: [PATCH 09/40] remove spaces between imports --- lib/runtime/test_helpers.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/runtime/test_helpers.go b/lib/runtime/test_helpers.go index 812eb41ae9..a7efb27e17 100644 --- a/lib/runtime/test_helpers.go +++ b/lib/runtime/test_helpers.go @@ -12,10 +12,9 @@ import ( "testing" "time" - "github.com/ChainSafe/gossamer/lib/crypto" - "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/lib/common" + "github.com/ChainSafe/gossamer/lib/crypto" "github.com/ChainSafe/gossamer/lib/crypto/ed25519" "github.com/ChainSafe/gossamer/lib/utils" ma "github.com/multiformats/go-multiaddr" @@ -131,7 +130,7 @@ func generateEd25519Signatures(t *testing.T, n int) []*crypto.Signature { PubKey: key.Public().Encode(), Sign: sign, Msg: msg, - VerifyFunc: ed25519.SignVerify, + VerifyFunc: ed25519.VerifySignature, } } return signs From a83901890bb70314a0e4523e1ed76eec76d4ccb1 Mon Sep 17 00:00:00 2001 From: 1garo Date: Tue, 23 Nov 2021 20:35:37 -0300 Subject: [PATCH 10/40] rename function to improve readability --- lib/runtime/life/resolver.go | 4 ++-- lib/runtime/types_test.go | 6 +++--- lib/runtime/wasmer/imports.go | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/runtime/life/resolver.go b/lib/runtime/life/resolver.go index f1b60b26af..ce8c32b813 100644 --- a/lib/runtime/life/resolver.go +++ b/lib/runtime/life/resolver.go @@ -937,7 +937,7 @@ func ext_crypto_ed25519_verify_version_1(vm *exec.VirtualMachine) int64 { PubKey: pubKey.Encode(), Sign: signature, Msg: message, - VerifyFunc: ed25519.SignVerify, + VerifyFunc: ed25519.VerifySignature, } sigVerifier.Add(&signature) return 1 @@ -1124,7 +1124,7 @@ func ext_crypto_sr25519_verify_version_1(vm *exec.VirtualMachine) int64 { PubKey: pub.Encode(), Sign: signature, Msg: message, - VerifyFunc: sr25519.SignVerify, + VerifyFunc: sr25519.VerifySignature, } sigVerifier.Add(&signature) return 1 diff --git a/lib/runtime/types_test.go b/lib/runtime/types_test.go index 5dacc6aa60..543fec505a 100644 --- a/lib/runtime/types_test.go +++ b/lib/runtime/types_test.go @@ -64,7 +64,7 @@ func TestInvalidSignatureBatch(t *testing.T) { PubKey: key.Public().Encode(), Sign: sigData, Msg: msg, - VerifyFunc: ed25519.SignVerify, + VerifyFunc: ed25519.VerifySignature, } signs = append(signs, signature) @@ -105,7 +105,7 @@ func TestAllCryptoTypeSignature(t *testing.T) { PubKey: srKey.Public().Encode(), Sign: srSig, Msg: srMsg, - VerifyFunc: sr25519.SignVerify, + VerifyFunc: sr25519.VerifySignature, } blakeHash, err := common.Blake2bHash([]byte("secp256k1")) @@ -122,7 +122,7 @@ func TestAllCryptoTypeSignature(t *testing.T) { PubKey: kp.Public().Encode(), Sign: secpSigData, Msg: blakeHash.ToBytes(), - VerifyFunc: secp256k1.SignVerify, + VerifyFunc: secp256k1.VerifySignature, } signVerify := crypto.NewSignatureVerifier(log.New(log.SetWriter(io.Discard))) diff --git a/lib/runtime/wasmer/imports.go b/lib/runtime/wasmer/imports.go index df90a15dd9..3f9a89fb8d 100644 --- a/lib/runtime/wasmer/imports.go +++ b/lib/runtime/wasmer/imports.go @@ -387,7 +387,7 @@ func ext_crypto_ed25519_verify_version_1(context unsafe.Pointer, sig C.int32_t, PubKey: pubKey.Encode(), Sign: signature, Msg: message, - VerifyFunc: ed25519.SignVerify, + VerifyFunc: ed25519.VerifySignature, } sigVerifier.Add(&signature) return 1 @@ -478,7 +478,7 @@ func ext_crypto_ecdsa_verify_version_2(context unsafe.Pointer, sig C.int32_t, ms PubKey: pub.Encode(), Sign: signature, Msg: hash[:], - VerifyFunc: secp256k1.SignVerify, + VerifyFunc: secp256k1.VerifySignature, } sigVerifier.Add(&signature) return C.int32_t(1) @@ -704,7 +704,7 @@ func ext_crypto_sr25519_verify_version_1(context unsafe.Pointer, sig C.int32_t, PubKey: pub.Encode(), Sign: signature, Msg: message, - VerifyFunc: sr25519.SignVerify, + VerifyFunc: sr25519.VerifySignature, } sigVerifier.Add(&signature) return 1 @@ -746,7 +746,7 @@ func ext_crypto_sr25519_verify_version_2(context unsafe.Pointer, sig C.int32_t, PubKey: pub.Encode(), Sign: signature, Msg: message, - VerifyFunc: sr25519.SignVerify, + VerifyFunc: sr25519.VerifySignature, } sigVerifier.Add(&signature) return 1 From 43ad637cd3562e6f19ddb635a14cf8cab36a739f Mon Sep 17 00:00:00 2001 From: 1garo Date: Tue, 23 Nov 2021 20:37:55 -0300 Subject: [PATCH 11/40] add err signature err msg and add return for docs purpose --- lib/crypto/sig_verifier.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/crypto/sig_verifier.go b/lib/crypto/sig_verifier.go index 31187bcc01..e2cdcb2610 100644 --- a/lib/crypto/sig_verifier.go +++ b/lib/crypto/sig_verifier.go @@ -4,14 +4,18 @@ package crypto import ( + "errors" "sync" "time" "github.com/ChainSafe/gossamer/internal/log" ) +// ErrSignatureVerificationFailed usaged when signature verification fails +var ErrSignatureVerificationFailed = errors.New("failed to verify signature") + // SigVerifyFunc verify an signature given a pubkey and msg -type SigVerifyFunc func(pubkey, sig, msg []byte) (bool, error) +type SigVerifyFunc func(pubkey, sig, msg []byte) (ok bool, err error) // Signature ... type Signature struct { @@ -64,11 +68,11 @@ func (sv *SignatureVerifier) Start() { case <-sv.closeCh: return default: - sig := sv.Remove() - if sig == nil { + signature := sv.Remove() + if signature == nil { continue } - ok, err := sig.VerifyFunc(sig.PubKey, sig.Sign, sig.Msg) + ok, err := signature.VerifyFunc(signature.PubKey, signature.Sign, signature.Msg) if err != nil || !ok { sv.logger.Errorf("[ext_crypto_start_batch_verify_version_1]: %s", err) sv.Invalid() From 9531a549996ac364af3c5a52e474cf3165aebfcd Mon Sep 17 00:00:00 2001 From: 1garo Date: Tue, 23 Nov 2021 20:38:58 -0300 Subject: [PATCH 12/40] improve naming and error handling --- lib/crypto/ed25519/ed25519.go | 19 ++++++++++++------- lib/crypto/secp256k1/secp256k1.go | 9 +++++---- lib/crypto/sr25519/sr25519.go | 19 ++++++++++++------- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/lib/crypto/ed25519/ed25519.go b/lib/crypto/ed25519/ed25519.go index 9c8ae11377..3745aac778 100644 --- a/lib/crypto/ed25519/ed25519.go +++ b/lib/crypto/ed25519/ed25519.go @@ -44,15 +44,20 @@ type PublicKey ed25519.PublicKey // PublicKeyBytes is an encoded ed25519 public key type PublicKeyBytes [PublicKeyLength]byte -// SignVerify verify signature given pubkey and msg -func SignVerify(pubkey, sig, msg []byte) (bool, error) { - pubKey, err := NewPublicKey(pubkey) +// VerifySignature verifies a signature given a public key and a message +func VerifySignature(publicKey, signature, message []byte) (bool, error) { + pubKey, err := NewPublicKey(publicKey) if err != nil { - return false, fmt.Errorf("failed to fetch ed25519 public key: %s", err) + return false, fmt.Errorf("failed to fetch ed25519 public key: %w", err) } - ok, err := pubKey.Verify(msg, sig) - if err != nil || !ok { - return false, fmt.Errorf("failed to verify ed25519 signature: %s", err) + ok, err := pubKey.Verify(message, signature) + if err != nil { + return false, fmt.Errorf("ed25519: %w: for message 0x%x, signature 0x%x and public key 0x%x", + crypto.ErrSignatureVerificationFailed, message, signature, publicKey) + } + + if !ok { + return false, nil } return true, nil diff --git a/lib/crypto/secp256k1/secp256k1.go b/lib/crypto/secp256k1/secp256k1.go index f64ffe63ce..a368483710 100644 --- a/lib/crypto/secp256k1/secp256k1.go +++ b/lib/crypto/secp256k1/secp256k1.go @@ -37,11 +37,12 @@ type PublicKey struct { key ecdsa.PublicKey } -// SignVerify verify signature given pubkey and msg -func SignVerify(pubkey, sig, msg []byte) (bool, error) { - ok := secp256k1.VerifySignature(pubkey, msg, sig) +// VerifySignature verifies a signature given a public key and a message +func VerifySignature(publicKey, signature, message []byte) (bool, error) { + ok := secp256k1.VerifySignature(publicKey, message, signature) if !ok { - return false, fmt.Errorf("failed to verify secp256k1 signature") + return false, fmt.Errorf("secp256k1: %w: for message 0x%x, signature 0x%x and public key 0x%x", + crypto.ErrSignatureVerificationFailed, message, signature, publicKey) } return true, nil diff --git a/lib/crypto/sr25519/sr25519.go b/lib/crypto/sr25519/sr25519.go index aa59c4e988..d18a93bf42 100644 --- a/lib/crypto/sr25519/sr25519.go +++ b/lib/crypto/sr25519/sr25519.go @@ -44,15 +44,20 @@ type PrivateKey struct { key *sr25519.SecretKey } -// SignVerify verify signature given pubkey and msg -func SignVerify(pubkey, sig, msg []byte) (bool, error) { - pubKey, err := NewPublicKey(pubkey) +// VerifySignature verifies a signature given a public key and a message +func VerifySignature(publicKey, signature, message []byte) (bool, error) { + pubKey, err := NewPublicKey(publicKey) if err != nil { - return false, fmt.Errorf("failed to fetch sr25519 public key: %s", err) + return false, fmt.Errorf("failed to fetch sr25519 public key: %w", err) } - ok, err := pubKey.Verify(msg, sig) - if err != nil || !ok { - return false, fmt.Errorf("failed to verify sr25519 signature: %s", err) + ok, err := pubKey.Verify(message, signature) + if err != nil { + return false, fmt.Errorf("sr25519: %w: for message 0x%x, signature 0x%x and public key 0x%x", + crypto.ErrSignatureVerificationFailed, message, signature, publicKey) + } + + if !ok { + return false, nil } return true, nil From 7a9560ecdbf562d92bc3f20df69dc88421ffdd76 Mon Sep 17 00:00:00 2001 From: 1garo Date: Tue, 23 Nov 2021 20:39:13 -0300 Subject: [PATCH 13/40] implement tests for new function --- lib/crypto/ed25519/ed25519_test.go | 16 ++++++++++++++++ lib/crypto/secp256k1/secp256k1_test.go | 16 ++++++++++++++++ lib/crypto/sr25519/sr25519_test.go | 16 ++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/lib/crypto/ed25519/ed25519_test.go b/lib/crypto/ed25519/ed25519_test.go index f83a3a8554..1384b55164 100644 --- a/lib/crypto/ed25519/ed25519_test.go +++ b/lib/crypto/ed25519/ed25519_test.go @@ -99,3 +99,19 @@ func TestNewKeypairFromMnenomic_Again(t *testing.T) { expectedPubkey := common.MustHexToBytes("0xf56d9231e7b7badd3f1e10ad15ef8aa08b70839723d0a2d10d7329f0ea2b8c61") require.Equal(t, expectedPubkey, kp.Public().Encode()) } + +func TestVerifySignature(t *testing.T) { + keypair, err := GenerateKeypair() + require.NoError(t, err) + + content := "Hello world!" + + message := []byte(content) + signature, err := keypair.Sign(message) + require.NoError(t, err) + + ok, err := VerifySignature(keypair.public.Encode(), signature, message) + require.NoError(t, err) + + require.Equal(t, ok, true) +} diff --git a/lib/crypto/secp256k1/secp256k1_test.go b/lib/crypto/secp256k1/secp256k1_test.go index 7ae002066d..7b8ca3fbfc 100644 --- a/lib/crypto/secp256k1/secp256k1_test.go +++ b/lib/crypto/secp256k1/secp256k1_test.go @@ -154,3 +154,19 @@ func TestRecoverPublicKeyCompressed(t *testing.T) { require.NoError(t, err) require.Equal(t, kp.Public(), r) } + +func TestVerifySignature(t *testing.T) { + keypair, err := GenerateKeypair() + require.NoError(t, err) + + content := "a225e8c75da7da319af6335e7642d473" + + message := []byte(content) + signature, err := keypair.Sign(message) + require.NoError(t, err) + + ok, err := VerifySignature(keypair.Public().Encode(), signature[:64], message) + require.NoError(t, err) + + require.Equal(t, ok, true) +} diff --git a/lib/crypto/sr25519/sr25519_test.go b/lib/crypto/sr25519/sr25519_test.go index a6440c738e..9ec2ded615 100644 --- a/lib/crypto/sr25519/sr25519_test.go +++ b/lib/crypto/sr25519/sr25519_test.go @@ -119,3 +119,19 @@ func TestNewKeypairFromMnenomic(t *testing.T) { _, err = NewKeypairFromMnenomic(mnemonic, "") require.NoError(t, err) } + +func TestVerifySignature(t *testing.T) { + keypair, err := GenerateKeypair() + require.NoError(t, err) + + content := "Hello world!" + + message := []byte(content) + signature, err := keypair.Sign(message) + require.NoError(t, err) + + ok, err := VerifySignature(keypair.public.Encode(), signature, message) + require.NoError(t, err) + + require.Equal(t, ok, true) +} From 9c31504ebf30fa9828d2fdfa11bfccd4541e4c64 Mon Sep 17 00:00:00 2001 From: 1garo Date: Tue, 23 Nov 2021 20:40:02 -0300 Subject: [PATCH 14/40] gen by mockery --- dot/network/mock_transaction_handler.go | 16 ++++++++-------- dot/rpc/modules/mocks/network_api.go | 11 ----------- dot/sync/mocks/Network.go | 12 +++++++----- 3 files changed, 15 insertions(+), 24 deletions(-) diff --git a/dot/network/mock_transaction_handler.go b/dot/network/mock_transaction_handler.go index 3c67662777..5a290bf6a4 100644 --- a/dot/network/mock_transaction_handler.go +++ b/dot/network/mock_transaction_handler.go @@ -3,7 +3,7 @@ package network import ( - "github.com/libp2p/go-libp2p-core/peer" + peer "github.com/libp2p/go-libp2p-core/peer" mock "github.com/stretchr/testify/mock" ) @@ -12,20 +12,20 @@ type MockTransactionHandler struct { mock.Mock } -// HandleTransactionMessage provides a mock function with given fields: _a0 -func (_m *MockTransactionHandler) HandleTransactionMessage(_ peer.ID, _a0 *TransactionMessage) (bool, error) { - ret := _m.Called(_a0) +// HandleTransactionMessage provides a mock function with given fields: _a0, _a1 +func (_m *MockTransactionHandler) HandleTransactionMessage(_a0 peer.ID, _a1 *TransactionMessage) (bool, error) { + ret := _m.Called(_a0, _a1) var r0 bool - if rf, ok := ret.Get(0).(func(*TransactionMessage) bool); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(peer.ID, *TransactionMessage) bool); ok { + r0 = rf(_a0, _a1) } else { r0 = ret.Get(0).(bool) } var r1 error - if rf, ok := ret.Get(1).(func(*TransactionMessage) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(peer.ID, *TransactionMessage) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } diff --git a/dot/rpc/modules/mocks/network_api.go b/dot/rpc/modules/mocks/network_api.go index 753703cb7a..d9dd66275a 100644 --- a/dot/rpc/modules/mocks/network_api.go +++ b/dot/rpc/modules/mocks/network_api.go @@ -3,10 +3,7 @@ package mocks import ( - "github.com/ChainSafe/gossamer/dot/network" - "github.com/ChainSafe/gossamer/dot/peerset" common "github.com/ChainSafe/gossamer/lib/common" - "github.com/libp2p/go-libp2p-core/peer" mock "github.com/stretchr/testify/mock" ) @@ -15,14 +12,6 @@ type NetworkAPI struct { mock.Mock } -func (_m *NetworkAPI) GossipMessage(message network.NotificationsMessage) { - _m.Called(message) -} - -func (_m *NetworkAPI) ReportPeer(change peerset.ReputationChange, p peer.ID) { - _m.Called(change, p) -} - // AddReservedPeers provides a mock function with given fields: addrs func (_m *NetworkAPI) AddReservedPeers(addrs ...string) error { _va := make([]interface{}, len(addrs)) diff --git a/dot/sync/mocks/Network.go b/dot/sync/mocks/Network.go index e4b4abd567..6f506ec05c 100644 --- a/dot/sync/mocks/Network.go +++ b/dot/sync/mocks/Network.go @@ -3,13 +3,14 @@ package mocks import ( - "github.com/ChainSafe/gossamer/dot/peerset" common "github.com/ChainSafe/gossamer/lib/common" mock "github.com/stretchr/testify/mock" network "github.com/ChainSafe/gossamer/dot/network" peer "github.com/libp2p/go-libp2p-core/peer" + + peerset "github.com/ChainSafe/gossamer/dot/peerset" ) // Network is an autogenerated mock type for the Network type @@ -17,10 +18,6 @@ type Network struct { mock.Mock } -func (_m *Network) ReportPeer(change peerset.ReputationChange, peer peer.ID) { - _m.Called(change, peer) -} - // DoBlockRequest provides a mock function with given fields: to, req func (_m *Network) DoBlockRequest(to peer.ID, req *network.BlockRequestMessage) (*network.BlockResponseMessage, error) { ret := _m.Called(to, req) @@ -59,3 +56,8 @@ func (_m *Network) Peers() []common.PeerInfo { return r0 } + +// ReportPeer provides a mock function with given fields: change, p +func (_m *Network) ReportPeer(change peerset.ReputationChange, p peer.ID) { + _m.Called(change, p) +} From fd188fcf88a65849fed2455da11a29e6a15e3e86 Mon Sep 17 00:00:00 2001 From: 1garo Date: Wed, 24 Nov 2021 19:16:40 -0300 Subject: [PATCH 15/40] create tests for sig verifier --- lib/crypto/sig_verifier_test.go | 205 ++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 lib/crypto/sig_verifier_test.go diff --git a/lib/crypto/sig_verifier_test.go b/lib/crypto/sig_verifier_test.go new file mode 100644 index 0000000000..c5619aea7b --- /dev/null +++ b/lib/crypto/sig_verifier_test.go @@ -0,0 +1,205 @@ +// Copyright 2021 ChainSafe Systems (ON) +// SPDX-License-Identifier: LGPL-3.0-only + +package crypto_test + +import ( + // "io" + + "testing" + + "github.com/ChainSafe/gossamer/internal/log" + "github.com/ChainSafe/gossamer/lib/crypto" + "github.com/ChainSafe/gossamer/lib/crypto/ed25519" + "github.com/ChainSafe/gossamer/lib/crypto/secp256k1" + "github.com/ChainSafe/gossamer/lib/crypto/sr25519" + + "github.com/stretchr/testify/require" +) + +func TestSigVerifierEd25519(t *testing.T) { + t.Helper() + signs := make([]*crypto.Signature, 2) + + for i := 0; i < 2; i++ { + msg := []byte("Hello") + key, err := ed25519.GenerateKeypair() + require.NoError(t, err) + + sign, err := key.Sign(msg) + require.NoError(t, err) + + signs[i] = &crypto.Signature{ + PubKey: key.Public().Encode(), + Sign: sign, + Msg: msg, + VerifyFunc: ed25519.VerifySignature, + } + } + signVerify := crypto.NewSignatureVerifier(log.New()) + + for _, sig := range signs { + signVerify.Add(sig) + } + + signVerify.Start() + ok := signVerify.Finish() + require.True(t, ok) +} + +func TestSigVerifierEd25519Fails(t *testing.T) { + t.Helper() + signs := make([]*crypto.Signature, 2) + + for i := 0; i < 2; i++ { + msg := []byte("Hello") + key, err := ed25519.GenerateKeypair() + require.NoError(t, err) + + sign, err := key.Sign(msg) + require.NoError(t, err) + if i == 1 { + signs[i] = &crypto.Signature{ + PubKey: []byte(""), + Sign: sign, + Msg: msg, + VerifyFunc: ed25519.VerifySignature, + } + continue + } + signs[i] = &crypto.Signature{ + PubKey: key.Public().Encode(), + Sign: []byte(""), + Msg: msg, + VerifyFunc: ed25519.VerifySignature, + } + } + signVerify := crypto.NewSignatureVerifier(log.New()) + + for _, sig := range signs { + signVerify.Add(sig) + } + + signVerify.Start() + ok := signVerify.Finish() + require.False(t, ok) +} + +func TestSigVerifierSr25519(t *testing.T) { + t.Helper() + signs := make([]*crypto.Signature, 2) + + for i := 0; i < 2; i++ { + msg := []byte("Hello") + key, err := sr25519.GenerateKeypair() + require.NoError(t, err) + + sign, err := key.Sign(msg) + require.NoError(t, err) + + signs[i] = &crypto.Signature{ + PubKey: key.Public().Encode(), + Sign: sign, + Msg: msg, + VerifyFunc: sr25519.VerifySignature, + } + } + signVerify := crypto.NewSignatureVerifier(log.New()) + + for _, sig := range signs { + signVerify.Add(sig) + } + + signVerify.Start() + ok := signVerify.Finish() + require.True(t, ok) +} + +func TestSigVerifierSr25519Fails(t *testing.T) { + t.Helper() + signs := make([]*crypto.Signature, 2) + + for i := 0; i < 2; i++ { + msg := []byte("Hello") + key, err := sr25519.GenerateKeypair() + require.NoError(t, err) + + sign, err := key.Sign(msg) + require.NoError(t, err) + + signs[i] = &crypto.Signature{ + PubKey: []byte(""), + Sign: sign, + Msg: msg, + VerifyFunc: sr25519.VerifySignature, + } + } + signVerify := crypto.NewSignatureVerifier(log.New()) + + for _, sig := range signs { + signVerify.Add(sig) + } + + signVerify.Start() + ok := signVerify.Finish() + require.False(t, ok) +} + +func TestSigVerifierSecp256k1(t *testing.T) { + t.Helper() + signs := make([]*crypto.Signature, 2) + + for i := 0; i < 2; i++ { + msg := []byte("a225e8c75da7da319af6335e7642d473") + key, err := secp256k1.GenerateKeypair() + require.NoError(t, err) + + sign, err := key.Sign(msg) + require.NoError(t, err) + + signs[i] = &crypto.Signature{ + PubKey: key.Public().Encode(), + Sign: sign[:64], + Msg: msg, + VerifyFunc: secp256k1.VerifySignature, + } + } + signVerify := crypto.NewSignatureVerifier(log.New()) + + for _, sig := range signs { + signVerify.Add(sig) + } + + signVerify.Start() + ok := signVerify.Finish() + require.True(t, ok) +} +func TestSigVerifierSecp256k1Fails(t *testing.T) { + t.Helper() + signs := make([]*crypto.Signature, 2) + + for i := 0; i < 2; i++ { + msg := []byte("a225e8c75da7da319af6335e7642d473") + key, err := secp256k1.GenerateKeypair() + require.NoError(t, err) + + sign, err := key.Sign(msg) + require.NoError(t, err) + + signs[i] = &crypto.Signature{ + PubKey: []byte(""), + Sign: sign[:64], + Msg: msg, + VerifyFunc: secp256k1.VerifySignature, + } + } + signVerify := crypto.NewSignatureVerifier(log.New()) + + for _, sig := range signs { + signVerify.Add(sig) + } + + signVerify.Start() + ok := signVerify.Finish() + require.False(t, ok) +} From 610e4cd304a5e74b3acf401ee2726fcab4baf721 Mon Sep 17 00:00:00 2001 From: 1garo Date: Wed, 24 Nov 2021 19:56:15 -0300 Subject: [PATCH 16/40] rename type and refactor VerifyFunc call --- lib/crypto/sig_verifier.go | 23 +++++++++++------------ lib/runtime/life/resolver.go | 4 ++-- lib/runtime/test_helpers.go | 6 +++--- lib/runtime/types_test.go | 6 +++--- lib/runtime/wasmer/imports.go | 8 ++++---- 5 files changed, 23 insertions(+), 24 deletions(-) diff --git a/lib/crypto/sig_verifier.go b/lib/crypto/sig_verifier.go index e2cdcb2610..d1dc42dd55 100644 --- a/lib/crypto/sig_verifier.go +++ b/lib/crypto/sig_verifier.go @@ -11,14 +11,13 @@ import ( "github.com/ChainSafe/gossamer/internal/log" ) -// ErrSignatureVerificationFailed usaged when signature verification fails var ErrSignatureVerificationFailed = errors.New("failed to verify signature") -// SigVerifyFunc verify an signature given a pubkey and msg -type SigVerifyFunc func(pubkey, sig, msg []byte) (ok bool, err error) +// SigVerifyFunc verifies a signature given a public key and a message +type SigVerifyFunc func(pubkey, sig, msg []byte) (err error) -// Signature ... -type Signature struct { +// Signing ... +type Signing struct { PubKey []byte Sign []byte Msg []byte @@ -27,7 +26,7 @@ type Signature struct { // SignatureVerifier ... type SignatureVerifier struct { - batch []*Signature + batch []*Signing init bool // Indicates whether the batch processing is started. invalid bool // Set to true if any signature verification fails. logger log.LeveledLogger @@ -43,7 +42,7 @@ type SignatureVerifier struct { // Signatures can be added to the batch using Add(). func NewSignatureVerifier(logger log.LeveledLogger) *SignatureVerifier { return &SignatureVerifier{ - batch: make([]*Signature, 0), + batch: make([]*Signing, 0), init: false, invalid: false, logger: logger, @@ -72,8 +71,8 @@ func (sv *SignatureVerifier) Start() { if signature == nil { continue } - ok, err := signature.VerifyFunc(signature.PubKey, signature.Sign, signature.Msg) - if err != nil || !ok { + err := signature.VerifyFunc(signature.PubKey, signature.Sign, signature.Msg) + if err != nil { sv.logger.Errorf("[ext_crypto_start_batch_verify_version_1]: %s", err) sv.Invalid() return @@ -105,7 +104,7 @@ func (sv *SignatureVerifier) Invalid() { } // Add ... -func (sv *SignatureVerifier) Add(s *Signature) { +func (sv *SignatureVerifier) Add(s *Signing) { if sv.IsInvalid() { return } @@ -116,7 +115,7 @@ func (sv *SignatureVerifier) Add(s *Signature) { } // Remove returns the first signature from the batch. Returns nil if batch is empty. -func (sv *SignatureVerifier) Remove() *Signature { +func (sv *SignatureVerifier) Remove() *Signing { sv.Lock() defer sv.Unlock() if len(sv.batch) == 0 { @@ -132,7 +131,7 @@ func (sv *SignatureVerifier) Reset() { sv.Lock() defer sv.Unlock() sv.init = false - sv.batch = make([]*Signature, 0) + sv.batch = make([]*Signing, 0) sv.invalid = false sv.closeCh = make(chan struct{}) } diff --git a/lib/runtime/life/resolver.go b/lib/runtime/life/resolver.go index 6cda3dd001..9b3bbc2bd7 100644 --- a/lib/runtime/life/resolver.go +++ b/lib/runtime/life/resolver.go @@ -933,7 +933,7 @@ func ext_crypto_ed25519_verify_version_1(vm *exec.VirtualMachine) int64 { } if sigVerifier.IsStarted() { - signature := crypto.Signature{ + signature := crypto.Signing{ PubKey: pubKey.Encode(), Sign: signature, Msg: message, @@ -1120,7 +1120,7 @@ func ext_crypto_sr25519_verify_version_1(vm *exec.VirtualMachine) int64 { pub.Hex(), message, signature) if sigVerifier.IsStarted() { - signature := crypto.Signature{ + signature := crypto.Signing{ PubKey: pub.Encode(), Sign: signature, Msg: message, diff --git a/lib/runtime/test_helpers.go b/lib/runtime/test_helpers.go index a7efb27e17..7c5ad7c90d 100644 --- a/lib/runtime/test_helpers.go +++ b/lib/runtime/test_helpers.go @@ -115,9 +115,9 @@ func (*TestRuntimeNetwork) NetworkState() common.NetworkState { } } -func generateEd25519Signatures(t *testing.T, n int) []*crypto.Signature { +func generateEd25519Signatures(t *testing.T, n int) []*crypto.Signing { t.Helper() - signs := make([]*crypto.Signature, n) + signs := make([]*crypto.Signing, n) for i := 0; i < n; i++ { msg := []byte("Hello") key, err := ed25519.GenerateKeypair() @@ -126,7 +126,7 @@ func generateEd25519Signatures(t *testing.T, n int) []*crypto.Signature { sign, err := key.Private().Sign(msg) require.NoError(t, err) - signs[i] = &crypto.Signature{ + signs[i] = &crypto.Signing{ PubKey: key.Public().Encode(), Sign: sign, Msg: msg, diff --git a/lib/runtime/types_test.go b/lib/runtime/types_test.go index 543fec505a..d585537f9b 100644 --- a/lib/runtime/types_test.go +++ b/lib/runtime/types_test.go @@ -60,7 +60,7 @@ func TestInvalidSignatureBatch(t *testing.T) { sigData, err := common.HexToBytes("0x90f27b8b488db00b00606796d2987f6a5f59ae62ea05effe84fef5b8b0e549984a691139ad57a3f0b906637673aa2f63d1f55cb1a69199d4009eea23ceaddc9301") require.Nil(t, err) - signature := &crypto.Signature{ + signature := &crypto.Signing{ PubKey: key.Public().Encode(), Sign: sigData, Msg: msg, @@ -101,7 +101,7 @@ func TestAllCryptoTypeSignature(t *testing.T) { srSig, err := srKey.Private().Sign(srMsg) require.NoError(t, err) - srSignature := &crypto.Signature{ + srSignature := &crypto.Signing{ PubKey: srKey.Public().Encode(), Sign: srSig, Msg: srMsg, @@ -118,7 +118,7 @@ func TestAllCryptoTypeSignature(t *testing.T) { require.NoError(t, err) secpSigData = secpSigData[:len(secpSigData)-1] // remove recovery id - secpSignature := &crypto.Signature{ + secpSignature := &crypto.Signing{ PubKey: kp.Public().Encode(), Sign: secpSigData, Msg: blakeHash.ToBytes(), diff --git a/lib/runtime/wasmer/imports.go b/lib/runtime/wasmer/imports.go index f7a4c82712..4ec694b063 100644 --- a/lib/runtime/wasmer/imports.go +++ b/lib/runtime/wasmer/imports.go @@ -384,7 +384,7 @@ func ext_crypto_ed25519_verify_version_1(context unsafe.Pointer, sig C.int32_t, } if sigVerifier.IsStarted() { - signature := crypto.Signature{ + signature := crypto.Signing{ PubKey: pubKey.Encode(), Sign: signature, Msg: message, @@ -475,7 +475,7 @@ func ext_crypto_ecdsa_verify_version_2(context unsafe.Pointer, sig C.int32_t, ms } if sigVerifier.IsStarted() { - signature := crypto.Signature{ + signature := crypto.Signing{ PubKey: pub.Encode(), Sign: signature, Msg: hash[:], @@ -701,7 +701,7 @@ func ext_crypto_sr25519_verify_version_1(context unsafe.Pointer, sig C.int32_t, pub.Hex(), message, signature) if sigVerifier.IsStarted() { - signature := crypto.Signature{ + signature := crypto.Signing{ PubKey: pub.Encode(), Sign: signature, Msg: message, @@ -743,7 +743,7 @@ func ext_crypto_sr25519_verify_version_2(context unsafe.Pointer, sig C.int32_t, pub.Hex(), message, signature) if sigVerifier.IsStarted() { - signature := crypto.Signature{ + signature := crypto.Signing{ PubKey: pub.Encode(), Sign: signature, Msg: message, From 5c45a1f1b008889f4dfde96d7a08079ef435359a Mon Sep 17 00:00:00 2001 From: 1garo Date: Wed, 24 Nov 2021 19:57:15 -0300 Subject: [PATCH 17/40] remove ok bool as return value --- lib/crypto/ed25519/ed25519.go | 15 ++++++--------- lib/crypto/secp256k1/secp256k1.go | 6 +++--- lib/crypto/sr25519/sr25519.go | 15 ++++++--------- 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/lib/crypto/ed25519/ed25519.go b/lib/crypto/ed25519/ed25519.go index 3745aac778..a731d2bc72 100644 --- a/lib/crypto/ed25519/ed25519.go +++ b/lib/crypto/ed25519/ed25519.go @@ -45,22 +45,19 @@ type PublicKey ed25519.PublicKey type PublicKeyBytes [PublicKeyLength]byte // VerifySignature verifies a signature given a public key and a message -func VerifySignature(publicKey, signature, message []byte) (bool, error) { +func VerifySignature(publicKey, signature, message []byte) error { pubKey, err := NewPublicKey(publicKey) if err != nil { - return false, fmt.Errorf("failed to fetch ed25519 public key: %w", err) + return err } - ok, err := pubKey.Verify(message, signature) + + _, err = pubKey.Verify(message, signature) if err != nil { - return false, fmt.Errorf("ed25519: %w: for message 0x%x, signature 0x%x and public key 0x%x", + return fmt.Errorf("ed25519: %w: for message 0x%x, signature 0x%x and public key 0x%x", crypto.ErrSignatureVerificationFailed, message, signature, publicKey) } - if !ok { - return false, nil - } - - return true, nil + return nil } // String returns the PublicKeyBytes formatted as a hex string diff --git a/lib/crypto/secp256k1/secp256k1.go b/lib/crypto/secp256k1/secp256k1.go index a368483710..e4ac80a0a9 100644 --- a/lib/crypto/secp256k1/secp256k1.go +++ b/lib/crypto/secp256k1/secp256k1.go @@ -38,14 +38,14 @@ type PublicKey struct { } // VerifySignature verifies a signature given a public key and a message -func VerifySignature(publicKey, signature, message []byte) (bool, error) { +func VerifySignature(publicKey, signature, message []byte) error { ok := secp256k1.VerifySignature(publicKey, message, signature) if !ok { - return false, fmt.Errorf("secp256k1: %w: for message 0x%x, signature 0x%x and public key 0x%x", + return fmt.Errorf("secp256k1: %w: for message 0x%x, signature 0x%x and public key 0x%x", crypto.ErrSignatureVerificationFailed, message, signature, publicKey) } - return true, nil + return nil } // RecoverPublicKey returns the 64-byte uncompressed public key that created the given signature. diff --git a/lib/crypto/sr25519/sr25519.go b/lib/crypto/sr25519/sr25519.go index 4d76164239..7623c6b293 100644 --- a/lib/crypto/sr25519/sr25519.go +++ b/lib/crypto/sr25519/sr25519.go @@ -50,22 +50,19 @@ type PrivateKey struct { } // VerifySignature verifies a signature given a public key and a message -func VerifySignature(publicKey, signature, message []byte) (bool, error) { +func VerifySignature(publicKey, signature, message []byte) error { pubKey, err := NewPublicKey(publicKey) if err != nil { - return false, fmt.Errorf("failed to fetch sr25519 public key: %w", err) + return err } - ok, err := pubKey.Verify(message, signature) + + _, err = pubKey.Verify(message, signature) if err != nil { - return false, fmt.Errorf("sr25519: %w: for message 0x%x, signature 0x%x and public key 0x%x", + return fmt.Errorf("sr25519: %w: for message 0x%x, signature 0x%x and public key 0x%x", crypto.ErrSignatureVerificationFailed, message, signature, publicKey) } - if !ok { - return false, nil - } - - return true, nil + return nil } // NewKeypair returns a sr25519 Keypair given a schnorrkel secret key From 5c15e6f217db6ee8e2cb4292074da7f03fcac2a7 Mon Sep 17 00:00:00 2001 From: 1garo Date: Wed, 24 Nov 2021 19:57:34 -0300 Subject: [PATCH 18/40] update tests and add one for sig_verifier --- lib/crypto/ed25519/ed25519_test.go | 48 ++++++++++++++++++--- lib/crypto/secp256k1/secp256k1_test.go | 41 +++++++++++++++--- lib/crypto/sig_verifier_test.go | 59 +++++++++++++++++--------- lib/crypto/sr25519/sr25519_test.go | 49 ++++++++++++++++++--- 4 files changed, 161 insertions(+), 36 deletions(-) diff --git a/lib/crypto/ed25519/ed25519_test.go b/lib/crypto/ed25519/ed25519_test.go index 1384b55164..0a44e1a926 100644 --- a/lib/crypto/ed25519/ed25519_test.go +++ b/lib/crypto/ed25519/ed25519_test.go @@ -5,10 +5,13 @@ package ed25519 import ( ed25519 "crypto/ed25519" + "errors" + "fmt" "reflect" "testing" "github.com/ChainSafe/gossamer/lib/common" + "github.com/ChainSafe/gossamer/lib/crypto" bip39 "github.com/cosmos/go-bip39" "github.com/stretchr/testify/require" @@ -104,14 +107,49 @@ func TestVerifySignature(t *testing.T) { keypair, err := GenerateKeypair() require.NoError(t, err) - content := "Hello world!" + message := []byte("Hello world!") - message := []byte(content) signature, err := keypair.Sign(message) require.NoError(t, err) - ok, err := VerifySignature(keypair.public.Encode(), signature, message) - require.NoError(t, err) + testCase := map[string]struct { + publicKey, signature, message []byte + err error + }{ + "success": { + publicKey: keypair.public.Encode(), + signature: signature, + message: message, + err: nil, + }, + "failed to fetch publicKey": { + publicKey: []byte(""), + signature: signature, + message: message, + err: errors.New("cannot create public key: input is not 32 bytes"), + }, + "verification failed": { + publicKey: keypair.public.Encode(), + signature: []byte(""), + message: message, + err: fmt.Errorf("ed25519: %w: for message 0x%x, signature 0x and public key 0x%x", + crypto.ErrSignatureVerificationFailed, message, keypair.public.Encode()), + }, + } + + for name, value := range testCase { + testCase := value + t.Run(name, func(t *testing.T) { + t.Parallel() + + err = VerifySignature(testCase.publicKey, testCase.signature, testCase.message) + + if testCase.err != nil { + require.EqualError(t, err, testCase.err.Error()) + return + } + require.NoError(t, err) + }) + } - require.Equal(t, ok, true) } diff --git a/lib/crypto/secp256k1/secp256k1_test.go b/lib/crypto/secp256k1/secp256k1_test.go index 7b8ca3fbfc..bad3f0d455 100644 --- a/lib/crypto/secp256k1/secp256k1_test.go +++ b/lib/crypto/secp256k1/secp256k1_test.go @@ -4,10 +4,12 @@ package secp256k1 import ( + "fmt" "reflect" "testing" "github.com/ChainSafe/gossamer/lib/common" + "github.com/ChainSafe/gossamer/lib/crypto" "github.com/stretchr/testify/require" ) @@ -159,14 +161,43 @@ func TestVerifySignature(t *testing.T) { keypair, err := GenerateKeypair() require.NoError(t, err) - content := "a225e8c75da7da319af6335e7642d473" + message := []byte("a225e8c75da7da319af6335e7642d473") - message := []byte(content) signature, err := keypair.Sign(message) require.NoError(t, err) - ok, err := VerifySignature(keypair.Public().Encode(), signature[:64], message) - require.NoError(t, err) + testCase := map[string]struct { + publicKey, signature, message []byte + err error + }{ + "success": { + publicKey: keypair.public.Encode(), + signature: signature[:64], + message: message, + err: nil, + }, + "verification failed": { + publicKey: keypair.public.Encode(), + signature: []byte(""), + message: message, + err: fmt.Errorf("secp256k1: %w: for message 0x%x, signature 0x and public key 0x%x", + crypto.ErrSignatureVerificationFailed, message, keypair.public.Encode()), + }, + } + + for name, value := range testCase { + testCase := value + t.Run(name, func(t *testing.T) { + t.Parallel() + + err = VerifySignature(testCase.publicKey, testCase.signature, testCase.message) + + if testCase.err != nil { + require.EqualError(t, err, testCase.err.Error()) + return + } + require.NoError(t, err) + }) + } - require.Equal(t, ok, true) } diff --git a/lib/crypto/sig_verifier_test.go b/lib/crypto/sig_verifier_test.go index c5619aea7b..348a51b339 100644 --- a/lib/crypto/sig_verifier_test.go +++ b/lib/crypto/sig_verifier_test.go @@ -4,8 +4,6 @@ package crypto_test import ( - // "io" - "testing" "github.com/ChainSafe/gossamer/internal/log" @@ -19,7 +17,7 @@ import ( func TestSigVerifierEd25519(t *testing.T) { t.Helper() - signs := make([]*crypto.Signature, 2) + signs := make([]*crypto.Signing, 2) for i := 0; i < 2; i++ { msg := []byte("Hello") @@ -29,7 +27,7 @@ func TestSigVerifierEd25519(t *testing.T) { sign, err := key.Sign(msg) require.NoError(t, err) - signs[i] = &crypto.Signature{ + signs[i] = &crypto.Signing{ PubKey: key.Public().Encode(), Sign: sign, Msg: msg, @@ -49,7 +47,7 @@ func TestSigVerifierEd25519(t *testing.T) { func TestSigVerifierEd25519Fails(t *testing.T) { t.Helper() - signs := make([]*crypto.Signature, 2) + signs := make([]*crypto.Signing, 2) for i := 0; i < 2; i++ { msg := []byte("Hello") @@ -59,7 +57,7 @@ func TestSigVerifierEd25519Fails(t *testing.T) { sign, err := key.Sign(msg) require.NoError(t, err) if i == 1 { - signs[i] = &crypto.Signature{ + signs[i] = &crypto.Signing{ PubKey: []byte(""), Sign: sign, Msg: msg, @@ -67,7 +65,7 @@ func TestSigVerifierEd25519Fails(t *testing.T) { } continue } - signs[i] = &crypto.Signature{ + signs[i] = &crypto.Signing{ PubKey: key.Public().Encode(), Sign: []byte(""), Msg: msg, @@ -87,7 +85,7 @@ func TestSigVerifierEd25519Fails(t *testing.T) { func TestSigVerifierSr25519(t *testing.T) { t.Helper() - signs := make([]*crypto.Signature, 2) + signs := make([]*crypto.Signing, 2) for i := 0; i < 2; i++ { msg := []byte("Hello") @@ -97,7 +95,7 @@ func TestSigVerifierSr25519(t *testing.T) { sign, err := key.Sign(msg) require.NoError(t, err) - signs[i] = &crypto.Signature{ + signs[i] = &crypto.Signing{ PubKey: key.Public().Encode(), Sign: sign, Msg: msg, @@ -117,7 +115,7 @@ func TestSigVerifierSr25519(t *testing.T) { func TestSigVerifierSr25519Fails(t *testing.T) { t.Helper() - signs := make([]*crypto.Signature, 2) + signs := make([]*crypto.Signing, 2) for i := 0; i < 2; i++ { msg := []byte("Hello") @@ -127,11 +125,20 @@ func TestSigVerifierSr25519Fails(t *testing.T) { sign, err := key.Sign(msg) require.NoError(t, err) - signs[i] = &crypto.Signature{ - PubKey: []byte(""), - Sign: sign, + if i == 1 { + signs[i] = &crypto.Signing{ + PubKey: []byte(""), + Sign: sign, + Msg: msg, + VerifyFunc: ed25519.VerifySignature, + } + continue + } + signs[i] = &crypto.Signing{ + PubKey: key.Public().Encode(), + Sign: []byte(""), Msg: msg, - VerifyFunc: sr25519.VerifySignature, + VerifyFunc: ed25519.VerifySignature, } } signVerify := crypto.NewSignatureVerifier(log.New()) @@ -147,7 +154,7 @@ func TestSigVerifierSr25519Fails(t *testing.T) { func TestSigVerifierSecp256k1(t *testing.T) { t.Helper() - signs := make([]*crypto.Signature, 2) + signs := make([]*crypto.Signing, 2) for i := 0; i < 2; i++ { msg := []byte("a225e8c75da7da319af6335e7642d473") @@ -157,7 +164,7 @@ func TestSigVerifierSecp256k1(t *testing.T) { sign, err := key.Sign(msg) require.NoError(t, err) - signs[i] = &crypto.Signature{ + signs[i] = &crypto.Signing{ PubKey: key.Public().Encode(), Sign: sign[:64], Msg: msg, @@ -174,9 +181,10 @@ func TestSigVerifierSecp256k1(t *testing.T) { ok := signVerify.Finish() require.True(t, ok) } + func TestSigVerifierSecp256k1Fails(t *testing.T) { t.Helper() - signs := make([]*crypto.Signature, 2) + signs := make([]*crypto.Signing, 2) for i := 0; i < 2; i++ { msg := []byte("a225e8c75da7da319af6335e7642d473") @@ -186,11 +194,20 @@ func TestSigVerifierSecp256k1Fails(t *testing.T) { sign, err := key.Sign(msg) require.NoError(t, err) - signs[i] = &crypto.Signature{ - PubKey: []byte(""), - Sign: sign[:64], + if i == 1 { + signs[i] = &crypto.Signing{ + PubKey: []byte(""), + Sign: sign, + Msg: msg, + VerifyFunc: ed25519.VerifySignature, + } + continue + } + signs[i] = &crypto.Signing{ + PubKey: key.Public().Encode(), + Sign: []byte(""), Msg: msg, - VerifyFunc: secp256k1.VerifySignature, + VerifyFunc: ed25519.VerifySignature, } } signVerify := crypto.NewSignatureVerifier(log.New()) diff --git a/lib/crypto/sr25519/sr25519_test.go b/lib/crypto/sr25519/sr25519_test.go index 9ec2ded615..419583d3e6 100644 --- a/lib/crypto/sr25519/sr25519_test.go +++ b/lib/crypto/sr25519/sr25519_test.go @@ -5,8 +5,12 @@ package sr25519 import ( "crypto/rand" + "errors" + + "fmt" "testing" + "github.com/ChainSafe/gossamer/lib/crypto" bip39 "github.com/cosmos/go-bip39" "github.com/gtank/merlin" "github.com/stretchr/testify/require" @@ -124,14 +128,49 @@ func TestVerifySignature(t *testing.T) { keypair, err := GenerateKeypair() require.NoError(t, err) - content := "Hello world!" + message := []byte("Hello world!") - message := []byte(content) signature, err := keypair.Sign(message) require.NoError(t, err) - ok, err := VerifySignature(keypair.public.Encode(), signature, message) - require.NoError(t, err) + testCase := map[string]struct { + publicKey, signature, message []byte + err error + }{ + "success": { + publicKey: keypair.public.Encode(), + signature: signature, + message: message, + err: nil, + }, + "failed to fetch publicKey": { + publicKey: []byte(""), + signature: signature, + message: message, + err: errors.New("cannot create public key: input is not 32 bytes"), + }, + "verification failed": { + publicKey: keypair.public.Encode(), + signature: []byte(""), + message: message, + err: fmt.Errorf("sr25519: %w: for message 0x%x, signature 0x and public key 0x%x", + crypto.ErrSignatureVerificationFailed, message, keypair.public.Encode()), + }, + } + + for name, value := range testCase { + testCase := value + t.Run(name, func(t *testing.T) { + t.Parallel() + + err = VerifySignature(testCase.publicKey, testCase.signature, testCase.message) + + if testCase.err != nil { + require.EqualError(t, err, testCase.err.Error()) + return + } + require.NoError(t, err) + }) + } - require.Equal(t, ok, true) } From fbe70d87386226bc9184012377e1d16dc9c509d3 Mon Sep 17 00:00:00 2001 From: 1garo Date: Thu, 25 Nov 2021 21:41:55 -0300 Subject: [PATCH 19/40] add signature name when error occurs --- lib/crypto/ed25519/ed25519.go | 2 +- lib/crypto/sr25519/sr25519.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/crypto/ed25519/ed25519.go b/lib/crypto/ed25519/ed25519.go index a731d2bc72..dd7a38f376 100644 --- a/lib/crypto/ed25519/ed25519.go +++ b/lib/crypto/ed25519/ed25519.go @@ -48,7 +48,7 @@ type PublicKeyBytes [PublicKeyLength]byte func VerifySignature(publicKey, signature, message []byte) error { pubKey, err := NewPublicKey(publicKey) if err != nil { - return err + return fmt.Errorf("ed25519: %w", err) } _, err = pubKey.Verify(message, signature) diff --git a/lib/crypto/sr25519/sr25519.go b/lib/crypto/sr25519/sr25519.go index 7623c6b293..aaea81ace9 100644 --- a/lib/crypto/sr25519/sr25519.go +++ b/lib/crypto/sr25519/sr25519.go @@ -53,7 +53,7 @@ type PrivateKey struct { func VerifySignature(publicKey, signature, message []byte) error { pubKey, err := NewPublicKey(publicKey) if err != nil { - return err + return fmt.Errorf("sr25519: %w", err) } _, err = pubKey.Verify(message, signature) From c164f4de030a48e53c43bf3fed991a52072dc2c6 Mon Sep 17 00:00:00 2001 From: 1garo Date: Thu, 25 Nov 2021 21:43:11 -0300 Subject: [PATCH 20/40] parallel tests and rename test case --- lib/crypto/ed25519/ed25519_test.go | 8 ++++---- lib/crypto/secp256k1/secp256k1_test.go | 4 ++-- lib/crypto/sr25519/sr25519_test.go | 9 +++++---- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/lib/crypto/ed25519/ed25519_test.go b/lib/crypto/ed25519/ed25519_test.go index 0a44e1a926..980246e57c 100644 --- a/lib/crypto/ed25519/ed25519_test.go +++ b/lib/crypto/ed25519/ed25519_test.go @@ -104,6 +104,7 @@ func TestNewKeypairFromMnenomic_Again(t *testing.T) { } func TestVerifySignature(t *testing.T) { + t.Parallel() keypair, err := GenerateKeypair() require.NoError(t, err) @@ -120,17 +121,16 @@ func TestVerifySignature(t *testing.T) { publicKey: keypair.public.Encode(), signature: signature, message: message, - err: nil, }, - "failed to fetch publicKey": { - publicKey: []byte(""), + "bad public key input": { + publicKey: []byte{}, signature: signature, message: message, err: errors.New("cannot create public key: input is not 32 bytes"), }, "verification failed": { publicKey: keypair.public.Encode(), - signature: []byte(""), + signature: []byte{}, message: message, err: fmt.Errorf("ed25519: %w: for message 0x%x, signature 0x and public key 0x%x", crypto.ErrSignatureVerificationFailed, message, keypair.public.Encode()), diff --git a/lib/crypto/secp256k1/secp256k1_test.go b/lib/crypto/secp256k1/secp256k1_test.go index bad3f0d455..c87476f1ca 100644 --- a/lib/crypto/secp256k1/secp256k1_test.go +++ b/lib/crypto/secp256k1/secp256k1_test.go @@ -158,6 +158,7 @@ func TestRecoverPublicKeyCompressed(t *testing.T) { } func TestVerifySignature(t *testing.T) { + t.Parallel() keypair, err := GenerateKeypair() require.NoError(t, err) @@ -174,11 +175,10 @@ func TestVerifySignature(t *testing.T) { publicKey: keypair.public.Encode(), signature: signature[:64], message: message, - err: nil, }, "verification failed": { publicKey: keypair.public.Encode(), - signature: []byte(""), + signature: []byte{}, message: message, err: fmt.Errorf("secp256k1: %w: for message 0x%x, signature 0x and public key 0x%x", crypto.ErrSignatureVerificationFailed, message, keypair.public.Encode()), diff --git a/lib/crypto/sr25519/sr25519_test.go b/lib/crypto/sr25519/sr25519_test.go index 419583d3e6..603f32cca3 100644 --- a/lib/crypto/sr25519/sr25519_test.go +++ b/lib/crypto/sr25519/sr25519_test.go @@ -125,6 +125,8 @@ func TestNewKeypairFromMnenomic(t *testing.T) { } func TestVerifySignature(t *testing.T) { + t.Parallel() + keypair, err := GenerateKeypair() require.NoError(t, err) @@ -141,17 +143,16 @@ func TestVerifySignature(t *testing.T) { publicKey: keypair.public.Encode(), signature: signature, message: message, - err: nil, }, - "failed to fetch publicKey": { - publicKey: []byte(""), + "bad public key input": { + publicKey: []byte{}, signature: signature, message: message, err: errors.New("cannot create public key: input is not 32 bytes"), }, "verification failed": { publicKey: keypair.public.Encode(), - signature: []byte(""), + signature: []byte{}, message: message, err: fmt.Errorf("sr25519: %w: for message 0x%x, signature 0x and public key 0x%x", crypto.ErrSignatureVerificationFailed, message, keypair.public.Encode()), From e1717bc58beb1f1535c7b9490c27fe66fc378cc8 Mon Sep 17 00:00:00 2001 From: 1garo Date: Thu, 25 Nov 2021 21:43:27 -0300 Subject: [PATCH 21/40] parallel tests and add log level --- lib/crypto/sig_verifier_test.go | 43 +++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/lib/crypto/sig_verifier_test.go b/lib/crypto/sig_verifier_test.go index 348a51b339..dc54402906 100644 --- a/lib/crypto/sig_verifier_test.go +++ b/lib/crypto/sig_verifier_test.go @@ -4,6 +4,7 @@ package crypto_test import ( + "io" "testing" "github.com/ChainSafe/gossamer/internal/log" @@ -16,7 +17,8 @@ import ( ) func TestSigVerifierEd25519(t *testing.T) { - t.Helper() + t.Parallel() + signs := make([]*crypto.Signing, 2) for i := 0; i < 2; i++ { @@ -34,7 +36,7 @@ func TestSigVerifierEd25519(t *testing.T) { VerifyFunc: ed25519.VerifySignature, } } - signVerify := crypto.NewSignatureVerifier(log.New()) + signVerify := crypto.NewSignatureVerifier(log.New(log.SetWriter(io.Discard))) for _, sig := range signs { signVerify.Add(sig) @@ -46,7 +48,8 @@ func TestSigVerifierEd25519(t *testing.T) { } func TestSigVerifierEd25519Fails(t *testing.T) { - t.Helper() + t.Parallel() + signs := make([]*crypto.Signing, 2) for i := 0; i < 2; i++ { @@ -58,7 +61,7 @@ func TestSigVerifierEd25519Fails(t *testing.T) { require.NoError(t, err) if i == 1 { signs[i] = &crypto.Signing{ - PubKey: []byte(""), + PubKey: []byte{}, Sign: sign, Msg: msg, VerifyFunc: ed25519.VerifySignature, @@ -67,12 +70,12 @@ func TestSigVerifierEd25519Fails(t *testing.T) { } signs[i] = &crypto.Signing{ PubKey: key.Public().Encode(), - Sign: []byte(""), + Sign: []byte{}, Msg: msg, VerifyFunc: ed25519.VerifySignature, } } - signVerify := crypto.NewSignatureVerifier(log.New()) + signVerify := crypto.NewSignatureVerifier(log.New(log.SetWriter(io.Discard))) for _, sig := range signs { signVerify.Add(sig) @@ -84,7 +87,8 @@ func TestSigVerifierEd25519Fails(t *testing.T) { } func TestSigVerifierSr25519(t *testing.T) { - t.Helper() + t.Parallel() + signs := make([]*crypto.Signing, 2) for i := 0; i < 2; i++ { @@ -102,7 +106,7 @@ func TestSigVerifierSr25519(t *testing.T) { VerifyFunc: sr25519.VerifySignature, } } - signVerify := crypto.NewSignatureVerifier(log.New()) + signVerify := crypto.NewSignatureVerifier(log.New(log.SetWriter(io.Discard))) for _, sig := range signs { signVerify.Add(sig) @@ -114,7 +118,8 @@ func TestSigVerifierSr25519(t *testing.T) { } func TestSigVerifierSr25519Fails(t *testing.T) { - t.Helper() + t.Parallel() + signs := make([]*crypto.Signing, 2) for i := 0; i < 2; i++ { @@ -127,7 +132,7 @@ func TestSigVerifierSr25519Fails(t *testing.T) { if i == 1 { signs[i] = &crypto.Signing{ - PubKey: []byte(""), + PubKey: []byte{}, Sign: sign, Msg: msg, VerifyFunc: ed25519.VerifySignature, @@ -136,12 +141,12 @@ func TestSigVerifierSr25519Fails(t *testing.T) { } signs[i] = &crypto.Signing{ PubKey: key.Public().Encode(), - Sign: []byte(""), + Sign: []byte{}, Msg: msg, VerifyFunc: ed25519.VerifySignature, } } - signVerify := crypto.NewSignatureVerifier(log.New()) + signVerify := crypto.NewSignatureVerifier(log.New(log.SetWriter(io.Discard))) for _, sig := range signs { signVerify.Add(sig) @@ -153,7 +158,8 @@ func TestSigVerifierSr25519Fails(t *testing.T) { } func TestSigVerifierSecp256k1(t *testing.T) { - t.Helper() + t.Parallel() + signs := make([]*crypto.Signing, 2) for i := 0; i < 2; i++ { @@ -171,7 +177,7 @@ func TestSigVerifierSecp256k1(t *testing.T) { VerifyFunc: secp256k1.VerifySignature, } } - signVerify := crypto.NewSignatureVerifier(log.New()) + signVerify := crypto.NewSignatureVerifier(log.New(log.SetWriter(io.Discard))) for _, sig := range signs { signVerify.Add(sig) @@ -183,7 +189,8 @@ func TestSigVerifierSecp256k1(t *testing.T) { } func TestSigVerifierSecp256k1Fails(t *testing.T) { - t.Helper() + t.Parallel() + signs := make([]*crypto.Signing, 2) for i := 0; i < 2; i++ { @@ -196,7 +203,7 @@ func TestSigVerifierSecp256k1Fails(t *testing.T) { if i == 1 { signs[i] = &crypto.Signing{ - PubKey: []byte(""), + PubKey: []byte{}, Sign: sign, Msg: msg, VerifyFunc: ed25519.VerifySignature, @@ -205,12 +212,12 @@ func TestSigVerifierSecp256k1Fails(t *testing.T) { } signs[i] = &crypto.Signing{ PubKey: key.Public().Encode(), - Sign: []byte(""), + Sign: []byte{}, Msg: msg, VerifyFunc: ed25519.VerifySignature, } } - signVerify := crypto.NewSignatureVerifier(log.New()) + signVerify := crypto.NewSignatureVerifier(log.New(log.SetWriter(io.Discard))) for _, sig := range signs { signVerify.Add(sig) From f00953078f9202847428a6b1d73e3316220df93c Mon Sep 17 00:00:00 2001 From: 1garo Date: Thu, 25 Nov 2021 21:44:28 -0300 Subject: [PATCH 22/40] gofmt --- lib/crypto/sr25519/sr25519.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/crypto/sr25519/sr25519.go b/lib/crypto/sr25519/sr25519.go index aaea81ace9..53c66a5084 100644 --- a/lib/crypto/sr25519/sr25519.go +++ b/lib/crypto/sr25519/sr25519.go @@ -53,7 +53,7 @@ type PrivateKey struct { func VerifySignature(publicKey, signature, message []byte) error { pubKey, err := NewPublicKey(publicKey) if err != nil { - return fmt.Errorf("sr25519: %w", err) + return fmt.Errorf("sr25519: %w", err) } _, err = pubKey.Verify(message, signature) @@ -212,7 +212,7 @@ func (kp *Keypair) Private() crypto.PrivateKey { } // VrfSign creates a VRF output and proof from a message and private key -func (kp *Keypair) VrfSign(t *merlin.Transcript) ([VRFOutputLength]byte, [VRFProofLength]byte, error) { +func (kp *Keypair) VrfSign(t *merlin.Transcript) ([sr25519.VRFOutputLength]byte, [sr25519.VRFProofLength]byte, error) { return kp.private.VrfSign(t) } @@ -397,7 +397,7 @@ func (k *PublicKey) AsBytes() [PublicKeyLength]byte { } // AttachInput wraps schnorrkel *VrfOutput.AttachInput -func AttachInput(output [VRFOutputLength]byte, pub *PublicKey, t *merlin.Transcript) *sr25519.VrfInOut { +func AttachInput(output [sr25519.VRFOutputLength]byte, pub *PublicKey, t *merlin.Transcript) *sr25519.VrfInOut { out := sr25519.NewOutput(output) return out.AttachInput(pub.key, t) } From 9534e7e2358d81aabaaa72f38af82b2263587da2 Mon Sep 17 00:00:00 2001 From: 1garo Date: Thu, 25 Nov 2021 22:03:35 -0300 Subject: [PATCH 23/40] resolve make build erroring --- lib/crypto/sr25519/sr25519.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/crypto/sr25519/sr25519.go b/lib/crypto/sr25519/sr25519.go index aeb3acd988..22d4a70f05 100644 --- a/lib/crypto/sr25519/sr25519.go +++ b/lib/crypto/sr25519/sr25519.go @@ -212,7 +212,7 @@ func (kp *Keypair) Private() crypto.PrivateKey { } // VrfSign creates a VRF output and proof from a message and private key -func (kp *Keypair) VrfSign(t *merlin.Transcript) ([sr25519.VRFOutputLength]byte, [sr25519.VRFProofLength]byte, error) { +func (kp *Keypair) VrfSign(t *merlin.Transcript) ([32]byte, [64]byte, error) { return kp.private.VrfSign(t) } @@ -398,7 +398,7 @@ func (k *PublicKey) AsBytes() [PublicKeyLength]byte { } // AttachInput wraps schnorrkel *VrfOutput.AttachInput -func AttachInput(output [sr25519.VRFOutputLength]byte, pub *PublicKey, t *merlin.Transcript) *sr25519.VrfInOut { +func AttachInput(output [VRFOutputLength]byte, pub *PublicKey, t *merlin.Transcript) *sr25519.VrfInOut { out := sr25519.NewOutput(output) return out.AttachInput(pub.key, t) } From 634ea8228ff170a5a991270764b6daaf60ceb757 Mon Sep 17 00:00:00 2001 From: 1garo Date: Fri, 26 Nov 2021 17:54:26 -0300 Subject: [PATCH 24/40] rename type --- lib/runtime/life/resolver.go | 4 ++-- lib/runtime/test_helpers.go | 6 +++--- lib/runtime/types_test.go | 6 +++--- lib/runtime/wasmer/imports.go | 8 ++++---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/runtime/life/resolver.go b/lib/runtime/life/resolver.go index 995dbfd8ad..7f19ea5869 100644 --- a/lib/runtime/life/resolver.go +++ b/lib/runtime/life/resolver.go @@ -935,7 +935,7 @@ func ext_crypto_ed25519_verify_version_1(vm *exec.VirtualMachine) int64 { } if sigVerifier.IsStarted() { - signature := crypto.Signing{ + signature := crypto.SignatureInfo{ PubKey: pubKey.Encode(), Sign: signature, Msg: message, @@ -1124,7 +1124,7 @@ func ext_crypto_sr25519_verify_version_1(vm *exec.VirtualMachine) int64 { pub.Hex(), message, signature) if sigVerifier.IsStarted() { - signature := crypto.Signing{ + signature := crypto.SignatureInfo{ PubKey: pub.Encode(), Sign: signature, Msg: message, diff --git a/lib/runtime/test_helpers.go b/lib/runtime/test_helpers.go index 7c5ad7c90d..e9e7d0f5f9 100644 --- a/lib/runtime/test_helpers.go +++ b/lib/runtime/test_helpers.go @@ -115,9 +115,9 @@ func (*TestRuntimeNetwork) NetworkState() common.NetworkState { } } -func generateEd25519Signatures(t *testing.T, n int) []*crypto.Signing { +func generateEd25519Signatures(t *testing.T, n int) []*crypto.SignatureInfo { t.Helper() - signs := make([]*crypto.Signing, n) + signs := make([]*crypto.SignatureInfo, n) for i := 0; i < n; i++ { msg := []byte("Hello") key, err := ed25519.GenerateKeypair() @@ -126,7 +126,7 @@ func generateEd25519Signatures(t *testing.T, n int) []*crypto.Signing { sign, err := key.Private().Sign(msg) require.NoError(t, err) - signs[i] = &crypto.Signing{ + signs[i] = &crypto.SignatureInfo{ PubKey: key.Public().Encode(), Sign: sign, Msg: msg, diff --git a/lib/runtime/types_test.go b/lib/runtime/types_test.go index 8b4945220d..98627f241d 100644 --- a/lib/runtime/types_test.go +++ b/lib/runtime/types_test.go @@ -60,7 +60,7 @@ func TestInvalidSignatureBatch(t *testing.T) { sigData, err := common.HexToBytes("0x90f27b8b488db00b00606796d2987f6a5f59ae62ea05effe84fef5b8b0e549984a691139ad57a3f0b906637673aa2f63d1f55cb1a69199d4009eea23ceaddc9301") //nolint:lll require.Nil(t, err) - signature := &crypto.Signing{ + signature := &crypto.SignatureInfo{ PubKey: key.Public().Encode(), Sign: sigData, Msg: msg, @@ -101,7 +101,7 @@ func TestAllCryptoTypeSignature(t *testing.T) { srSig, err := srKey.Private().Sign(srMsg) require.NoError(t, err) - srSignature := &crypto.Signing{ + srSignature := &crypto.SignatureInfo{ PubKey: srKey.Public().Encode(), Sign: srSig, Msg: srMsg, @@ -118,7 +118,7 @@ func TestAllCryptoTypeSignature(t *testing.T) { require.NoError(t, err) secpSigData = secpSigData[:len(secpSigData)-1] // remove recovery id - secpSignature := &crypto.Signing{ + secpSignature := &crypto.SignatureInfo{ PubKey: kp.Public().Encode(), Sign: secpSigData, Msg: blakeHash.ToBytes(), diff --git a/lib/runtime/wasmer/imports.go b/lib/runtime/wasmer/imports.go index 4ec694b063..cfecb7e005 100644 --- a/lib/runtime/wasmer/imports.go +++ b/lib/runtime/wasmer/imports.go @@ -384,7 +384,7 @@ func ext_crypto_ed25519_verify_version_1(context unsafe.Pointer, sig C.int32_t, } if sigVerifier.IsStarted() { - signature := crypto.Signing{ + signature := crypto.SignatureInfo{ PubKey: pubKey.Encode(), Sign: signature, Msg: message, @@ -475,7 +475,7 @@ func ext_crypto_ecdsa_verify_version_2(context unsafe.Pointer, sig C.int32_t, ms } if sigVerifier.IsStarted() { - signature := crypto.Signing{ + signature := crypto.SignatureInfo{ PubKey: pub.Encode(), Sign: signature, Msg: hash[:], @@ -701,7 +701,7 @@ func ext_crypto_sr25519_verify_version_1(context unsafe.Pointer, sig C.int32_t, pub.Hex(), message, signature) if sigVerifier.IsStarted() { - signature := crypto.Signing{ + signature := crypto.SignatureInfo{ PubKey: pub.Encode(), Sign: signature, Msg: message, @@ -743,7 +743,7 @@ func ext_crypto_sr25519_verify_version_2(context unsafe.Pointer, sig C.int32_t, pub.Hex(), message, signature) if sigVerifier.IsStarted() { - signature := crypto.Signing{ + signature := crypto.SignatureInfo{ PubKey: pub.Encode(), Sign: signature, Msg: message, From 973ce6b8d786a45d991a294e893960c356678dbb Mon Sep 17 00:00:00 2001 From: 1garo Date: Fri, 26 Nov 2021 18:05:03 -0300 Subject: [PATCH 25/40] remove space between imports --- lib/crypto/sr25519/sr25519_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/crypto/sr25519/sr25519_test.go b/lib/crypto/sr25519/sr25519_test.go index 603f32cca3..6de1ff634d 100644 --- a/lib/crypto/sr25519/sr25519_test.go +++ b/lib/crypto/sr25519/sr25519_test.go @@ -6,7 +6,6 @@ package sr25519 import ( "crypto/rand" "errors" - "fmt" "testing" From ddba19f06a294a297336c3d97af5b81669737ed3 Mon Sep 17 00:00:00 2001 From: 1garo Date: Fri, 26 Nov 2021 18:06:14 -0300 Subject: [PATCH 26/40] remove useless alias --- lib/crypto/ed25519/ed25519_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/crypto/ed25519/ed25519_test.go b/lib/crypto/ed25519/ed25519_test.go index 980246e57c..402ec7736d 100644 --- a/lib/crypto/ed25519/ed25519_test.go +++ b/lib/crypto/ed25519/ed25519_test.go @@ -4,7 +4,7 @@ package ed25519 import ( - ed25519 "crypto/ed25519" + "crypto/ed25519" "errors" "fmt" "reflect" From da14c990cb5e12019c5ed9ac840a6c0b9d687da7 Mon Sep 17 00:00:00 2001 From: 1garo Date: Fri, 26 Nov 2021 18:08:02 -0300 Subject: [PATCH 27/40] check ok, if false errors --- lib/crypto/ed25519/ed25519.go | 4 ++-- lib/crypto/sr25519/sr25519.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/crypto/ed25519/ed25519.go b/lib/crypto/ed25519/ed25519.go index dd7a38f376..59d2f18225 100644 --- a/lib/crypto/ed25519/ed25519.go +++ b/lib/crypto/ed25519/ed25519.go @@ -51,8 +51,8 @@ func VerifySignature(publicKey, signature, message []byte) error { return fmt.Errorf("ed25519: %w", err) } - _, err = pubKey.Verify(message, signature) - if err != nil { + ok, err := pubKey.Verify(message, signature) + if err != nil || !ok { return fmt.Errorf("ed25519: %w: for message 0x%x, signature 0x%x and public key 0x%x", crypto.ErrSignatureVerificationFailed, message, signature, publicKey) } diff --git a/lib/crypto/sr25519/sr25519.go b/lib/crypto/sr25519/sr25519.go index 22d4a70f05..2c94e09ac7 100644 --- a/lib/crypto/sr25519/sr25519.go +++ b/lib/crypto/sr25519/sr25519.go @@ -56,8 +56,8 @@ func VerifySignature(publicKey, signature, message []byte) error { return fmt.Errorf("sr25519: %w", err) } - _, err = pubKey.Verify(message, signature) - if err != nil { + ok, err := pubKey.Verify(message, signature) + if err != nil || !ok { return fmt.Errorf("sr25519: %w: for message 0x%x, signature 0x%x and public key 0x%x", crypto.ErrSignatureVerificationFailed, message, signature, publicKey) } From 664aa50dcd1c5b01a0063697970ba34069cf9a5b Mon Sep 17 00:00:00 2001 From: 1garo Date: Fri, 26 Nov 2021 18:08:08 -0300 Subject: [PATCH 28/40] rename typ --- lib/crypto/sig_verifier.go | 14 +++++++------- lib/crypto/sig_verifier_test.go | 30 +++++++++++++++--------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/lib/crypto/sig_verifier.go b/lib/crypto/sig_verifier.go index d1dc42dd55..80b5ca8be4 100644 --- a/lib/crypto/sig_verifier.go +++ b/lib/crypto/sig_verifier.go @@ -16,8 +16,8 @@ var ErrSignatureVerificationFailed = errors.New("failed to verify signature") // SigVerifyFunc verifies a signature given a public key and a message type SigVerifyFunc func(pubkey, sig, msg []byte) (err error) -// Signing ... -type Signing struct { +// SignatureInfo ... +type SignatureInfo struct { PubKey []byte Sign []byte Msg []byte @@ -26,7 +26,7 @@ type Signing struct { // SignatureVerifier ... type SignatureVerifier struct { - batch []*Signing + batch []*SignatureInfo init bool // Indicates whether the batch processing is started. invalid bool // Set to true if any signature verification fails. logger log.LeveledLogger @@ -42,7 +42,7 @@ type SignatureVerifier struct { // Signatures can be added to the batch using Add(). func NewSignatureVerifier(logger log.LeveledLogger) *SignatureVerifier { return &SignatureVerifier{ - batch: make([]*Signing, 0), + batch: make([]*SignatureInfo, 0), init: false, invalid: false, logger: logger, @@ -104,7 +104,7 @@ func (sv *SignatureVerifier) Invalid() { } // Add ... -func (sv *SignatureVerifier) Add(s *Signing) { +func (sv *SignatureVerifier) Add(s *SignatureInfo) { if sv.IsInvalid() { return } @@ -115,7 +115,7 @@ func (sv *SignatureVerifier) Add(s *Signing) { } // Remove returns the first signature from the batch. Returns nil if batch is empty. -func (sv *SignatureVerifier) Remove() *Signing { +func (sv *SignatureVerifier) Remove() *SignatureInfo { sv.Lock() defer sv.Unlock() if len(sv.batch) == 0 { @@ -131,7 +131,7 @@ func (sv *SignatureVerifier) Reset() { sv.Lock() defer sv.Unlock() sv.init = false - sv.batch = make([]*Signing, 0) + sv.batch = make([]*SignatureInfo, 0) sv.invalid = false sv.closeCh = make(chan struct{}) } diff --git a/lib/crypto/sig_verifier_test.go b/lib/crypto/sig_verifier_test.go index dc54402906..1928534174 100644 --- a/lib/crypto/sig_verifier_test.go +++ b/lib/crypto/sig_verifier_test.go @@ -19,7 +19,7 @@ import ( func TestSigVerifierEd25519(t *testing.T) { t.Parallel() - signs := make([]*crypto.Signing, 2) + signs := make([]*crypto.SignatureInfo, 2) for i := 0; i < 2; i++ { msg := []byte("Hello") @@ -29,7 +29,7 @@ func TestSigVerifierEd25519(t *testing.T) { sign, err := key.Sign(msg) require.NoError(t, err) - signs[i] = &crypto.Signing{ + signs[i] = &crypto.SignatureInfo{ PubKey: key.Public().Encode(), Sign: sign, Msg: msg, @@ -50,7 +50,7 @@ func TestSigVerifierEd25519(t *testing.T) { func TestSigVerifierEd25519Fails(t *testing.T) { t.Parallel() - signs := make([]*crypto.Signing, 2) + signs := make([]*crypto.SignatureInfo, 2) for i := 0; i < 2; i++ { msg := []byte("Hello") @@ -60,7 +60,7 @@ func TestSigVerifierEd25519Fails(t *testing.T) { sign, err := key.Sign(msg) require.NoError(t, err) if i == 1 { - signs[i] = &crypto.Signing{ + signs[i] = &crypto.SignatureInfo{ PubKey: []byte{}, Sign: sign, Msg: msg, @@ -68,7 +68,7 @@ func TestSigVerifierEd25519Fails(t *testing.T) { } continue } - signs[i] = &crypto.Signing{ + signs[i] = &crypto.SignatureInfo{ PubKey: key.Public().Encode(), Sign: []byte{}, Msg: msg, @@ -89,7 +89,7 @@ func TestSigVerifierEd25519Fails(t *testing.T) { func TestSigVerifierSr25519(t *testing.T) { t.Parallel() - signs := make([]*crypto.Signing, 2) + signs := make([]*crypto.SignatureInfo, 2) for i := 0; i < 2; i++ { msg := []byte("Hello") @@ -99,7 +99,7 @@ func TestSigVerifierSr25519(t *testing.T) { sign, err := key.Sign(msg) require.NoError(t, err) - signs[i] = &crypto.Signing{ + signs[i] = &crypto.SignatureInfo{ PubKey: key.Public().Encode(), Sign: sign, Msg: msg, @@ -120,7 +120,7 @@ func TestSigVerifierSr25519(t *testing.T) { func TestSigVerifierSr25519Fails(t *testing.T) { t.Parallel() - signs := make([]*crypto.Signing, 2) + signs := make([]*crypto.SignatureInfo, 2) for i := 0; i < 2; i++ { msg := []byte("Hello") @@ -131,7 +131,7 @@ func TestSigVerifierSr25519Fails(t *testing.T) { require.NoError(t, err) if i == 1 { - signs[i] = &crypto.Signing{ + signs[i] = &crypto.SignatureInfo{ PubKey: []byte{}, Sign: sign, Msg: msg, @@ -139,7 +139,7 @@ func TestSigVerifierSr25519Fails(t *testing.T) { } continue } - signs[i] = &crypto.Signing{ + signs[i] = &crypto.SignatureInfo{ PubKey: key.Public().Encode(), Sign: []byte{}, Msg: msg, @@ -160,7 +160,7 @@ func TestSigVerifierSr25519Fails(t *testing.T) { func TestSigVerifierSecp256k1(t *testing.T) { t.Parallel() - signs := make([]*crypto.Signing, 2) + signs := make([]*crypto.SignatureInfo, 2) for i := 0; i < 2; i++ { msg := []byte("a225e8c75da7da319af6335e7642d473") @@ -170,7 +170,7 @@ func TestSigVerifierSecp256k1(t *testing.T) { sign, err := key.Sign(msg) require.NoError(t, err) - signs[i] = &crypto.Signing{ + signs[i] = &crypto.SignatureInfo{ PubKey: key.Public().Encode(), Sign: sign[:64], Msg: msg, @@ -191,7 +191,7 @@ func TestSigVerifierSecp256k1(t *testing.T) { func TestSigVerifierSecp256k1Fails(t *testing.T) { t.Parallel() - signs := make([]*crypto.Signing, 2) + signs := make([]*crypto.SignatureInfo, 2) for i := 0; i < 2; i++ { msg := []byte("a225e8c75da7da319af6335e7642d473") @@ -202,7 +202,7 @@ func TestSigVerifierSecp256k1Fails(t *testing.T) { require.NoError(t, err) if i == 1 { - signs[i] = &crypto.Signing{ + signs[i] = &crypto.SignatureInfo{ PubKey: []byte{}, Sign: sign, Msg: msg, @@ -210,7 +210,7 @@ func TestSigVerifierSecp256k1Fails(t *testing.T) { } continue } - signs[i] = &crypto.Signing{ + signs[i] = &crypto.SignatureInfo{ PubKey: key.Public().Encode(), Sign: []byte{}, Msg: msg, From 625ca02e237736209e8eca072acbb64c5a9e0cbc Mon Sep 17 00:00:00 2001 From: 1garo Date: Fri, 26 Nov 2021 18:45:25 -0300 Subject: [PATCH 29/40] solve tests failing --- lib/crypto/ed25519/ed25519_test.go | 2 +- lib/crypto/sr25519/sr25519_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/crypto/ed25519/ed25519_test.go b/lib/crypto/ed25519/ed25519_test.go index 402ec7736d..31640d9daa 100644 --- a/lib/crypto/ed25519/ed25519_test.go +++ b/lib/crypto/ed25519/ed25519_test.go @@ -126,7 +126,7 @@ func TestVerifySignature(t *testing.T) { publicKey: []byte{}, signature: signature, message: message, - err: errors.New("cannot create public key: input is not 32 bytes"), + err: errors.New("ed25519: cannot create public key: input is not 32 bytes"), }, "verification failed": { publicKey: keypair.public.Encode(), diff --git a/lib/crypto/sr25519/sr25519_test.go b/lib/crypto/sr25519/sr25519_test.go index 6de1ff634d..bb68b03b3e 100644 --- a/lib/crypto/sr25519/sr25519_test.go +++ b/lib/crypto/sr25519/sr25519_test.go @@ -147,7 +147,7 @@ func TestVerifySignature(t *testing.T) { publicKey: []byte{}, signature: signature, message: message, - err: errors.New("cannot create public key: input is not 32 bytes"), + err: errors.New("sr25519: cannot create public key: input is not 32 bytes"), }, "verification failed": { publicKey: keypair.public.Encode(), From 975b40627639296e1533123e56165c6f70232b5e Mon Sep 17 00:00:00 2001 From: 1garo Date: Fri, 26 Nov 2021 20:23:03 -0300 Subject: [PATCH 30/40] use test cases to remove useless code --- lib/crypto/sig_verifier_test.go | 297 +++++++++++--------------------- 1 file changed, 100 insertions(+), 197 deletions(-) diff --git a/lib/crypto/sig_verifier_test.go b/lib/crypto/sig_verifier_test.go index 1928534174..3e1cad5ef7 100644 --- a/lib/crypto/sig_verifier_test.go +++ b/lib/crypto/sig_verifier_test.go @@ -4,6 +4,7 @@ package crypto_test import ( + "errors" "io" "testing" @@ -16,214 +17,116 @@ import ( "github.com/stretchr/testify/require" ) -func TestSigVerifierEd25519(t *testing.T) { +func TestVerifySignature(t *testing.T) { t.Parallel() - signs := make([]*crypto.SignatureInfo, 2) - - for i := 0; i < 2; i++ { - msg := []byte("Hello") - key, err := ed25519.GenerateKeypair() - require.NoError(t, err) - - sign, err := key.Sign(msg) - require.NoError(t, err) - - signs[i] = &crypto.SignatureInfo{ - PubKey: key.Public().Encode(), - Sign: sign, - Msg: msg, - VerifyFunc: ed25519.VerifySignature, - } + errorMessage := errors.New("errors test case") + message := []byte("a225e8c75da7da319af6335e7642d473") + + edKeypair, err := ed25519.GenerateKeypair() + require.NoError(t, err) + edSign, err := edKeypair.Sign(message) + require.NoError(t, err) + + secpKeypair, err := secp256k1.GenerateKeypair() + require.NoError(t, err) + secpSign, err := secpKeypair.Sign(message) + require.NoError(t, err) + + srKeypair, err := sr25519.GenerateKeypair() + require.NoError(t, err) + srSign, err := srKeypair.Sign(message) + require.NoError(t, err) + + testCase := map[string]struct { + expect error + signaturesToVerify []*crypto.SignatureInfo + }{ + "success": { + signaturesToVerify: []*crypto.SignatureInfo{ + 0: { + PubKey: edKeypair.Public().Encode(), + Sign: edSign, + Msg: message, + VerifyFunc: ed25519.VerifySignature, + }, + 1: { + PubKey: secpKeypair.Public().Encode(), + Sign: secpSign[:64], + Msg: message, + VerifyFunc: secp256k1.VerifySignature, + }, + 2: { + PubKey: srKeypair.Public().Encode(), + Sign: srSign, + Msg: message, + VerifyFunc: sr25519.VerifySignature, + }, + }, + }, + "bad public key input": { + expect: errorMessage, + signaturesToVerify: []*crypto.SignatureInfo{ + 0: { + PubKey: []byte{}, + Sign: edSign, + Msg: message, + VerifyFunc: ed25519.VerifySignature, + }, + 1: { + PubKey: []byte{}, + Sign: srSign, + Msg: message, + VerifyFunc: sr25519.VerifySignature, + }, + }, + }, + "verification failed": { + expect: errorMessage, + signaturesToVerify: []*crypto.SignatureInfo{ + 0: { + PubKey: edKeypair.Public().Encode(), + Sign: []byte{}, + Msg: message, + VerifyFunc: ed25519.VerifySignature, + }, + 1: { + PubKey: srKeypair.Public().Encode(), + Sign: []byte{}, + Msg: message, + VerifyFunc: sr25519.VerifySignature, + }, + 2: { + PubKey: secpKeypair.Public().Encode(), + Sign: secpSign, + Msg: message, + VerifyFunc: secp256k1.VerifySignature, + }, + }, + }, } - signVerify := crypto.NewSignatureVerifier(log.New(log.SetWriter(io.Discard))) - for _, sig := range signs { - signVerify.Add(sig) - } + for name, value := range testCase { + testCase := value + t.Run(name, func(t *testing.T) { + t.Parallel() - signVerify.Start() - ok := signVerify.Finish() - require.True(t, ok) -} - -func TestSigVerifierEd25519Fails(t *testing.T) { - t.Parallel() + signVerify := crypto.NewSignatureVerifier(log.New(log.SetWriter(io.Discard))) - signs := make([]*crypto.SignatureInfo, 2) - - for i := 0; i < 2; i++ { - msg := []byte("Hello") - key, err := ed25519.GenerateKeypair() - require.NoError(t, err) - - sign, err := key.Sign(msg) - require.NoError(t, err) - if i == 1 { - signs[i] = &crypto.SignatureInfo{ - PubKey: []byte{}, - Sign: sign, - Msg: msg, - VerifyFunc: ed25519.VerifySignature, + for _, sig := range testCase.signaturesToVerify { + signVerify.Add(sig) } - continue - } - signs[i] = &crypto.SignatureInfo{ - PubKey: key.Public().Encode(), - Sign: []byte{}, - Msg: msg, - VerifyFunc: ed25519.VerifySignature, - } - } - signVerify := crypto.NewSignatureVerifier(log.New(log.SetWriter(io.Discard))) - - for _, sig := range signs { - signVerify.Add(sig) - } - - signVerify.Start() - ok := signVerify.Finish() - require.False(t, ok) -} - -func TestSigVerifierSr25519(t *testing.T) { - t.Parallel() - - signs := make([]*crypto.SignatureInfo, 2) - - for i := 0; i < 2; i++ { - msg := []byte("Hello") - key, err := sr25519.GenerateKeypair() - require.NoError(t, err) - - sign, err := key.Sign(msg) - require.NoError(t, err) - - signs[i] = &crypto.SignatureInfo{ - PubKey: key.Public().Encode(), - Sign: sign, - Msg: msg, - VerifyFunc: sr25519.VerifySignature, - } - } - signVerify := crypto.NewSignatureVerifier(log.New(log.SetWriter(io.Discard))) - - for _, sig := range signs { - signVerify.Add(sig) - } - - signVerify.Start() - ok := signVerify.Finish() - require.True(t, ok) -} - -func TestSigVerifierSr25519Fails(t *testing.T) { - t.Parallel() - - signs := make([]*crypto.SignatureInfo, 2) - for i := 0; i < 2; i++ { - msg := []byte("Hello") - key, err := sr25519.GenerateKeypair() - require.NoError(t, err) + signVerify.Start() - sign, err := key.Sign(msg) - require.NoError(t, err) - - if i == 1 { - signs[i] = &crypto.SignatureInfo{ - PubKey: []byte{}, - Sign: sign, - Msg: msg, - VerifyFunc: ed25519.VerifySignature, + ok := signVerify.Finish() + if testCase.expect != nil { + require.False(t, ok) + return } - continue - } - signs[i] = &crypto.SignatureInfo{ - PubKey: key.Public().Encode(), - Sign: []byte{}, - Msg: msg, - VerifyFunc: ed25519.VerifySignature, - } - } - signVerify := crypto.NewSignatureVerifier(log.New(log.SetWriter(io.Discard))) - - for _, sig := range signs { - signVerify.Add(sig) - } - - signVerify.Start() - ok := signVerify.Finish() - require.False(t, ok) -} - -func TestSigVerifierSecp256k1(t *testing.T) { - t.Parallel() - - signs := make([]*crypto.SignatureInfo, 2) - - for i := 0; i < 2; i++ { - msg := []byte("a225e8c75da7da319af6335e7642d473") - key, err := secp256k1.GenerateKeypair() - require.NoError(t, err) - - sign, err := key.Sign(msg) - require.NoError(t, err) - - signs[i] = &crypto.SignatureInfo{ - PubKey: key.Public().Encode(), - Sign: sign[:64], - Msg: msg, - VerifyFunc: secp256k1.VerifySignature, - } - } - signVerify := crypto.NewSignatureVerifier(log.New(log.SetWriter(io.Discard))) - - for _, sig := range signs { - signVerify.Add(sig) - } - - signVerify.Start() - ok := signVerify.Finish() - require.True(t, ok) -} - -func TestSigVerifierSecp256k1Fails(t *testing.T) { - t.Parallel() - - signs := make([]*crypto.SignatureInfo, 2) - - for i := 0; i < 2; i++ { - msg := []byte("a225e8c75da7da319af6335e7642d473") - key, err := secp256k1.GenerateKeypair() - require.NoError(t, err) - - sign, err := key.Sign(msg) - require.NoError(t, err) - - if i == 1 { - signs[i] = &crypto.SignatureInfo{ - PubKey: []byte{}, - Sign: sign, - Msg: msg, - VerifyFunc: ed25519.VerifySignature, - } - continue - } - signs[i] = &crypto.SignatureInfo{ - PubKey: key.Public().Encode(), - Sign: []byte{}, - Msg: msg, - VerifyFunc: ed25519.VerifySignature, - } - } - signVerify := crypto.NewSignatureVerifier(log.New(log.SetWriter(io.Discard))) - for _, sig := range signs { - signVerify.Add(sig) + require.True(t, ok) + }) } - signVerify.Start() - ok := signVerify.Finish() - require.False(t, ok) } From 75f6080bfffbb84df908bd606e1e402cc77029c5 Mon Sep 17 00:00:00 2001 From: 1garo Date: Fri, 26 Nov 2021 20:24:32 -0300 Subject: [PATCH 31/40] send empty bytes on error test case --- lib/crypto/sig_verifier_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/crypto/sig_verifier_test.go b/lib/crypto/sig_verifier_test.go index 3e1cad5ef7..566105a950 100644 --- a/lib/crypto/sig_verifier_test.go +++ b/lib/crypto/sig_verifier_test.go @@ -98,7 +98,7 @@ func TestVerifySignature(t *testing.T) { }, 2: { PubKey: secpKeypair.Public().Encode(), - Sign: secpSign, + Sign: []byte{}, Msg: message, VerifyFunc: secp256k1.VerifySignature, }, From 7a62d06f3f633e14dff77d926715bb6db4ee7c95 Mon Sep 17 00:00:00 2001 From: 1garo Date: Sat, 27 Nov 2021 01:18:26 -0300 Subject: [PATCH 32/40] improve tests cases --- lib/crypto/sig_verifier_test.go | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/lib/crypto/sig_verifier_test.go b/lib/crypto/sig_verifier_test.go index 566105a950..fcaec07b88 100644 --- a/lib/crypto/sig_verifier_test.go +++ b/lib/crypto/sig_verifier_test.go @@ -4,7 +4,6 @@ package crypto_test import ( - "errors" "io" "testing" @@ -20,7 +19,6 @@ import ( func TestVerifySignature(t *testing.T) { t.Parallel() - errorMessage := errors.New("errors test case") message := []byte("a225e8c75da7da319af6335e7642d473") edKeypair, err := ed25519.GenerateKeypair() @@ -39,10 +37,11 @@ func TestVerifySignature(t *testing.T) { require.NoError(t, err) testCase := map[string]struct { - expect error + expect bool signaturesToVerify []*crypto.SignatureInfo }{ "success": { + expect: true, signaturesToVerify: []*crypto.SignatureInfo{ 0: { PubKey: edKeypair.Public().Encode(), @@ -65,7 +64,7 @@ func TestVerifySignature(t *testing.T) { }, }, "bad public key input": { - expect: errorMessage, + expect: false, signaturesToVerify: []*crypto.SignatureInfo{ 0: { PubKey: []byte{}, @@ -82,7 +81,7 @@ func TestVerifySignature(t *testing.T) { }, }, "verification failed": { - expect: errorMessage, + expect: false, signaturesToVerify: []*crypto.SignatureInfo{ 0: { PubKey: edKeypair.Public().Encode(), @@ -120,12 +119,7 @@ func TestVerifySignature(t *testing.T) { signVerify.Start() ok := signVerify.Finish() - if testCase.expect != nil { - require.False(t, ok) - return - } - - require.True(t, ok) + require.Equal(t, testCase.expect, ok) }) } From 7da55ab8144362d861e23745e7c6de2155788fd5 Mon Sep 17 00:00:00 2001 From: 1garo Date: Tue, 30 Nov 2021 00:23:00 -0300 Subject: [PATCH 33/40] use constants instead of just []byte --- lib/crypto/sr25519/sr25519.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/crypto/sr25519/sr25519.go b/lib/crypto/sr25519/sr25519.go index 2c94e09ac7..f23ddfe621 100644 --- a/lib/crypto/sr25519/sr25519.go +++ b/lib/crypto/sr25519/sr25519.go @@ -212,7 +212,7 @@ func (kp *Keypair) Private() crypto.PrivateKey { } // VrfSign creates a VRF output and proof from a message and private key -func (kp *Keypair) VrfSign(t *merlin.Transcript) ([32]byte, [64]byte, error) { +func (kp *Keypair) VrfSign(t *merlin.Transcript) ([VRFOutputLength]byte, [VRFProofLength]byte, error) { return kp.private.VrfSign(t) } From 2fdabf8fe157783607cb047401073d892755cb4d Mon Sep 17 00:00:00 2001 From: 1garo Date: Tue, 30 Nov 2021 19:48:50 -0300 Subject: [PATCH 34/40] switch validation order --- lib/crypto/secp256k1/secp256k1.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/crypto/secp256k1/secp256k1.go b/lib/crypto/secp256k1/secp256k1.go index e4ac80a0a9..dc4790ae8c 100644 --- a/lib/crypto/secp256k1/secp256k1.go +++ b/lib/crypto/secp256k1/secp256k1.go @@ -40,12 +40,12 @@ type PublicKey struct { // VerifySignature verifies a signature given a public key and a message func VerifySignature(publicKey, signature, message []byte) error { ok := secp256k1.VerifySignature(publicKey, message, signature) - if !ok { - return fmt.Errorf("secp256k1: %w: for message 0x%x, signature 0x%x and public key 0x%x", - crypto.ErrSignatureVerificationFailed, message, signature, publicKey) + if ok { + return nil } - return nil + return fmt.Errorf("secp256k1: %w: for message 0x%x, signature 0x%x and public key 0x%x", + crypto.ErrSignatureVerificationFailed, message, signature, publicKey) } // RecoverPublicKey returns the 64-byte uncompressed public key that created the given signature. From ae147858e5e473194c9ccd634657497aba43b096 Mon Sep 17 00:00:00 2001 From: 1garo Date: Tue, 30 Nov 2021 19:49:33 -0300 Subject: [PATCH 35/40] use new err approach validation and add tests --- lib/crypto/ed25519/ed25519.go | 6 +++++- lib/crypto/ed25519/ed25519_test.go | 15 ++++++++++----- lib/crypto/sr25519/sr25519.go | 6 +++++- lib/crypto/sr25519/sr25519_test.go | 12 +++++++++--- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/lib/crypto/ed25519/ed25519.go b/lib/crypto/ed25519/ed25519.go index 59d2f18225..0ae2fdc5d2 100644 --- a/lib/crypto/ed25519/ed25519.go +++ b/lib/crypto/ed25519/ed25519.go @@ -52,7 +52,11 @@ func VerifySignature(publicKey, signature, message []byte) error { } ok, err := pubKey.Verify(message, signature) - if err != nil || !ok { + if err != nil { + return fmt.Errorf("ed25519: %w: %s", crypto.ErrSignatureVerificationFailed, err) + } + + if !ok { return fmt.Errorf("ed25519: %w: for message 0x%x, signature 0x%x and public key 0x%x", crypto.ErrSignatureVerificationFailed, message, signature, publicKey) } diff --git a/lib/crypto/ed25519/ed25519_test.go b/lib/crypto/ed25519/ed25519_test.go index 31640d9daa..bc29284719 100644 --- a/lib/crypto/ed25519/ed25519_test.go +++ b/lib/crypto/ed25519/ed25519_test.go @@ -5,7 +5,6 @@ package ed25519 import ( "crypto/ed25519" - "errors" "fmt" "reflect" "testing" @@ -126,14 +125,20 @@ func TestVerifySignature(t *testing.T) { publicKey: []byte{}, signature: signature, message: message, - err: errors.New("ed25519: cannot create public key: input is not 32 bytes"), + err: fmt.Errorf("ed25519: cannot create public key: input is not 32 bytes"), }, - "verification failed": { + "invalid signature length": { publicKey: keypair.public.Encode(), signature: []byte{}, message: message, - err: fmt.Errorf("ed25519: %w: for message 0x%x, signature 0x and public key 0x%x", - crypto.ErrSignatureVerificationFailed, message, keypair.public.Encode()), + err: fmt.Errorf("ed25519: %w: invalid signature length", crypto.ErrSignatureVerificationFailed), + }, + "verification failed": { + publicKey: keypair.public.Encode(), + signature: signature, + message: []byte("a225e8c75da7da319af6335e7642d473"), + err: fmt.Errorf("ed25519: %w: for message 0x%x, signature 0x%x and public key 0x%x", + crypto.ErrSignatureVerificationFailed, []byte("a225e8c75da7da319af6335e7642d473"), signature, keypair.public.Encode()), }, } diff --git a/lib/crypto/sr25519/sr25519.go b/lib/crypto/sr25519/sr25519.go index f23ddfe621..4959aafe6b 100644 --- a/lib/crypto/sr25519/sr25519.go +++ b/lib/crypto/sr25519/sr25519.go @@ -57,7 +57,11 @@ func VerifySignature(publicKey, signature, message []byte) error { } ok, err := pubKey.Verify(message, signature) - if err != nil || !ok { + if err != nil { + return fmt.Errorf("sr25519: %w: %s", crypto.ErrSignatureVerificationFailed, err) + } + + if !ok { return fmt.Errorf("sr25519: %w: for message 0x%x, signature 0x%x and public key 0x%x", crypto.ErrSignatureVerificationFailed, message, signature, publicKey) } diff --git a/lib/crypto/sr25519/sr25519_test.go b/lib/crypto/sr25519/sr25519_test.go index bb68b03b3e..3cd30b30b0 100644 --- a/lib/crypto/sr25519/sr25519_test.go +++ b/lib/crypto/sr25519/sr25519_test.go @@ -149,12 +149,18 @@ func TestVerifySignature(t *testing.T) { message: message, err: errors.New("sr25519: cannot create public key: input is not 32 bytes"), }, - "verification failed": { + "invalid signature length": { publicKey: keypair.public.Encode(), signature: []byte{}, message: message, - err: fmt.Errorf("sr25519: %w: for message 0x%x, signature 0x and public key 0x%x", - crypto.ErrSignatureVerificationFailed, message, keypair.public.Encode()), + err: errors.New("sr25519: failed to verify signature: invalid signature length"), + }, + "verification failed": { + publicKey: keypair.public.Encode(), + signature: signature, + message: []byte("a225e8c75da7da319af6335e7642d473"), + err: fmt.Errorf("sr25519: %w: for message 0x%x, signature 0x%x and public key 0x%x", + crypto.ErrSignatureVerificationFailed, []byte("a225e8c75da7da319af6335e7642d473"), signature, keypair.public.Encode()), }, } From f223d65cc4506ee3cbc9557b49001e3810bc3300 Mon Sep 17 00:00:00 2001 From: 1garo Date: Tue, 30 Nov 2021 19:52:26 -0300 Subject: [PATCH 36/40] make use of constants --- lib/crypto/sr25519/sr25519_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/crypto/sr25519/sr25519_test.go b/lib/crypto/sr25519/sr25519_test.go index 3cd30b30b0..89788584c5 100644 --- a/lib/crypto/sr25519/sr25519_test.go +++ b/lib/crypto/sr25519/sr25519_test.go @@ -153,7 +153,7 @@ func TestVerifySignature(t *testing.T) { publicKey: keypair.public.Encode(), signature: []byte{}, message: message, - err: errors.New("sr25519: failed to verify signature: invalid signature length"), + err: fmt.Errorf("sr25519: %w: invalid signature length", crypto.ErrSignatureVerificationFailed), }, "verification failed": { publicKey: keypair.public.Encode(), From 1ee5e82ef016cbc4212d467fb0c1fc8f871629bc Mon Sep 17 00:00:00 2001 From: 1garo Date: Wed, 1 Dec 2021 10:32:41 -0300 Subject: [PATCH 37/40] fix error validation on ed25519 --- lib/crypto/ed25519/ed25519.go | 6 ++---- lib/crypto/ed25519/ed25519_test.go | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/crypto/ed25519/ed25519.go b/lib/crypto/ed25519/ed25519.go index 0ae2fdc5d2..28ab6c34d2 100644 --- a/lib/crypto/ed25519/ed25519.go +++ b/lib/crypto/ed25519/ed25519.go @@ -53,10 +53,8 @@ func VerifySignature(publicKey, signature, message []byte) error { ok, err := pubKey.Verify(message, signature) if err != nil { - return fmt.Errorf("ed25519: %w: %s", crypto.ErrSignatureVerificationFailed, err) - } - - if !ok { + return fmt.Errorf("ed25519: %w", err) + } else if !ok { return fmt.Errorf("ed25519: %w: for message 0x%x, signature 0x%x and public key 0x%x", crypto.ErrSignatureVerificationFailed, message, signature, publicKey) } diff --git a/lib/crypto/ed25519/ed25519_test.go b/lib/crypto/ed25519/ed25519_test.go index bc29284719..481929216a 100644 --- a/lib/crypto/ed25519/ed25519_test.go +++ b/lib/crypto/ed25519/ed25519_test.go @@ -131,7 +131,7 @@ func TestVerifySignature(t *testing.T) { publicKey: keypair.public.Encode(), signature: []byte{}, message: message, - err: fmt.Errorf("ed25519: %w: invalid signature length", crypto.ErrSignatureVerificationFailed), + err: fmt.Errorf("ed25519: invalid signature length"), }, "verification failed": { publicKey: keypair.public.Encode(), From 4012a6674e80383611e265a1d9d0eb061b4927c4 Mon Sep 17 00:00:00 2001 From: 1garo Date: Wed, 1 Dec 2021 10:32:51 -0300 Subject: [PATCH 38/40] fix error validation on sr25519 --- lib/crypto/sr25519/sr25519.go | 6 ++---- lib/crypto/sr25519/sr25519_test.go | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/crypto/sr25519/sr25519.go b/lib/crypto/sr25519/sr25519.go index 4959aafe6b..799f720d54 100644 --- a/lib/crypto/sr25519/sr25519.go +++ b/lib/crypto/sr25519/sr25519.go @@ -58,10 +58,8 @@ func VerifySignature(publicKey, signature, message []byte) error { ok, err := pubKey.Verify(message, signature) if err != nil { - return fmt.Errorf("sr25519: %w: %s", crypto.ErrSignatureVerificationFailed, err) - } - - if !ok { + return fmt.Errorf("sr25519: %w", err) + } else if !ok { return fmt.Errorf("sr25519: %w: for message 0x%x, signature 0x%x and public key 0x%x", crypto.ErrSignatureVerificationFailed, message, signature, publicKey) } diff --git a/lib/crypto/sr25519/sr25519_test.go b/lib/crypto/sr25519/sr25519_test.go index 89788584c5..4f35cf7de7 100644 --- a/lib/crypto/sr25519/sr25519_test.go +++ b/lib/crypto/sr25519/sr25519_test.go @@ -153,7 +153,7 @@ func TestVerifySignature(t *testing.T) { publicKey: keypair.public.Encode(), signature: []byte{}, message: message, - err: fmt.Errorf("sr25519: %w: invalid signature length", crypto.ErrSignatureVerificationFailed), + err: fmt.Errorf("sr25519: invalid signature length"), }, "verification failed": { publicKey: keypair.public.Encode(), From f7b81b1894590026cbf5d073d4384c46369ef996 Mon Sep 17 00:00:00 2001 From: 1garo Date: Wed, 1 Dec 2021 10:39:26 -0300 Subject: [PATCH 39/40] put publicKey in var to avoid golangci-lint error --- lib/crypto/ed25519/ed25519_test.go | 10 ++++++---- lib/crypto/sr25519/sr25519_test.go | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/crypto/ed25519/ed25519_test.go b/lib/crypto/ed25519/ed25519_test.go index 481929216a..e1833fecd9 100644 --- a/lib/crypto/ed25519/ed25519_test.go +++ b/lib/crypto/ed25519/ed25519_test.go @@ -107,6 +107,8 @@ func TestVerifySignature(t *testing.T) { keypair, err := GenerateKeypair() require.NoError(t, err) + publicKey := keypair.public.Encode() + message := []byte("Hello world!") signature, err := keypair.Sign(message) @@ -117,7 +119,7 @@ func TestVerifySignature(t *testing.T) { err error }{ "success": { - publicKey: keypair.public.Encode(), + publicKey: publicKey, signature: signature, message: message, }, @@ -128,17 +130,17 @@ func TestVerifySignature(t *testing.T) { err: fmt.Errorf("ed25519: cannot create public key: input is not 32 bytes"), }, "invalid signature length": { - publicKey: keypair.public.Encode(), + publicKey: publicKey, signature: []byte{}, message: message, err: fmt.Errorf("ed25519: invalid signature length"), }, "verification failed": { - publicKey: keypair.public.Encode(), + publicKey: publicKey, signature: signature, message: []byte("a225e8c75da7da319af6335e7642d473"), err: fmt.Errorf("ed25519: %w: for message 0x%x, signature 0x%x and public key 0x%x", - crypto.ErrSignatureVerificationFailed, []byte("a225e8c75da7da319af6335e7642d473"), signature, keypair.public.Encode()), + crypto.ErrSignatureVerificationFailed, []byte("a225e8c75da7da319af6335e7642d473"), signature, publicKey), }, } diff --git a/lib/crypto/sr25519/sr25519_test.go b/lib/crypto/sr25519/sr25519_test.go index 4f35cf7de7..1e7bbed42b 100644 --- a/lib/crypto/sr25519/sr25519_test.go +++ b/lib/crypto/sr25519/sr25519_test.go @@ -129,6 +129,8 @@ func TestVerifySignature(t *testing.T) { keypair, err := GenerateKeypair() require.NoError(t, err) + publicKey := keypair.public.Encode() + message := []byte("Hello world!") signature, err := keypair.Sign(message) @@ -139,7 +141,7 @@ func TestVerifySignature(t *testing.T) { err error }{ "success": { - publicKey: keypair.public.Encode(), + publicKey: publicKey, signature: signature, message: message, }, @@ -150,17 +152,17 @@ func TestVerifySignature(t *testing.T) { err: errors.New("sr25519: cannot create public key: input is not 32 bytes"), }, "invalid signature length": { - publicKey: keypair.public.Encode(), + publicKey: publicKey, signature: []byte{}, message: message, err: fmt.Errorf("sr25519: invalid signature length"), }, "verification failed": { - publicKey: keypair.public.Encode(), + publicKey: publicKey, signature: signature, message: []byte("a225e8c75da7da319af6335e7642d473"), err: fmt.Errorf("sr25519: %w: for message 0x%x, signature 0x%x and public key 0x%x", - crypto.ErrSignatureVerificationFailed, []byte("a225e8c75da7da319af6335e7642d473"), signature, keypair.public.Encode()), + crypto.ErrSignatureVerificationFailed, []byte("a225e8c75da7da319af6335e7642d473"), signature, publicKey), }, } From 52bc4c3ec32f019dc5e80bfb884c59b31029946b Mon Sep 17 00:00:00 2001 From: Kishan Sagathiya Date: Mon, 6 Dec 2021 21:28:56 +0530 Subject: [PATCH 40/40] use a new err variable for each parallel test run --- lib/crypto/ed25519/ed25519_test.go | 2 +- lib/crypto/secp256k1/secp256k1_test.go | 2 +- lib/crypto/sr25519/sr25519_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/crypto/ed25519/ed25519_test.go b/lib/crypto/ed25519/ed25519_test.go index e1833fecd9..765c493741 100644 --- a/lib/crypto/ed25519/ed25519_test.go +++ b/lib/crypto/ed25519/ed25519_test.go @@ -149,7 +149,7 @@ func TestVerifySignature(t *testing.T) { t.Run(name, func(t *testing.T) { t.Parallel() - err = VerifySignature(testCase.publicKey, testCase.signature, testCase.message) + err := VerifySignature(testCase.publicKey, testCase.signature, testCase.message) if testCase.err != nil { require.EqualError(t, err, testCase.err.Error()) diff --git a/lib/crypto/secp256k1/secp256k1_test.go b/lib/crypto/secp256k1/secp256k1_test.go index c87476f1ca..a0aaecacc5 100644 --- a/lib/crypto/secp256k1/secp256k1_test.go +++ b/lib/crypto/secp256k1/secp256k1_test.go @@ -190,7 +190,7 @@ func TestVerifySignature(t *testing.T) { t.Run(name, func(t *testing.T) { t.Parallel() - err = VerifySignature(testCase.publicKey, testCase.signature, testCase.message) + err := VerifySignature(testCase.publicKey, testCase.signature, testCase.message) if testCase.err != nil { require.EqualError(t, err, testCase.err.Error()) diff --git a/lib/crypto/sr25519/sr25519_test.go b/lib/crypto/sr25519/sr25519_test.go index 1e7bbed42b..53fbfe7e52 100644 --- a/lib/crypto/sr25519/sr25519_test.go +++ b/lib/crypto/sr25519/sr25519_test.go @@ -171,7 +171,7 @@ func TestVerifySignature(t *testing.T) { t.Run(name, func(t *testing.T) { t.Parallel() - err = VerifySignature(testCase.publicKey, testCase.signature, testCase.message) + err := VerifySignature(testCase.publicKey, testCase.signature, testCase.message) if testCase.err != nil { require.EqualError(t, err, testCase.err.Error())