mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-08 23:18:15 -05:00
* Identify invalid signature within batch verification (#11582) * Fix issues found by linter * Make deepsource happy * Add signature description enums * Make descriptions a mandatory field * More readable error message of invalid signatures * Add 'enable-verbose-sig-verification' option * Fix format * Move descriptions to package signing * Add more validation and test cases * Fix build failure Co-authored-by: Nishant Das <nishdas93@gmail.com>
This commit is contained in:
@@ -54,6 +54,11 @@ func AggregateCompressedSignatures(multiSigs [][]byte) (common.Signature, error)
|
||||
return blst.AggregateCompressedSignatures(multiSigs)
|
||||
}
|
||||
|
||||
// VerifySignature verifies a single signature. For performance reason, always use VerifyMultipleSignatures if possible.
|
||||
func VerifySignature(sig []byte, msg [32]byte, pubKey common.PublicKey) (bool, error) {
|
||||
return blst.VerifySignature(sig, msg, pubKey)
|
||||
}
|
||||
|
||||
// VerifyMultipleSignatures verifies multiple signatures for distinct messages securely.
|
||||
func VerifyMultipleSignatures(sigs [][]byte, msgs [][32]byte, pubKeys []common.PublicKey) (bool, error) {
|
||||
return blst.VerifyMultipleSignatures(sigs, msgs, pubKeys)
|
||||
|
||||
@@ -196,6 +196,15 @@ func AggregateSignatures(sigs []common.Signature) common.Signature {
|
||||
return &Signature{s: signature.ToAffine()}
|
||||
}
|
||||
|
||||
// VerifySignature verifies a single signature using public key and message.
|
||||
func VerifySignature(sig []byte, msg [32]byte, pubKey common.PublicKey) (bool, error) {
|
||||
rSig, err := SignatureFromBytes(sig)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return rSig.Verify(pubKey, msg[:]), nil
|
||||
}
|
||||
|
||||
// VerifyMultipleSignatures verifies a non-singular set of signatures and its respective pubkeys and messages.
|
||||
// This method provides a safe way to verify multiple signatures at once. We pick a number randomly from 1 to max
|
||||
// uint64 and then multiply the signature by it. We continue doing this for all signatures and its respective pubkeys.
|
||||
|
||||
@@ -36,6 +36,7 @@ func TestAggregateVerify(t *testing.T) {
|
||||
msgs = append(msgs, msg)
|
||||
}
|
||||
aggSig := AggregateSignatures(sigs)
|
||||
// skipcq: GO-W1009
|
||||
assert.Equal(t, true, aggSig.AggregateVerify(pubkeys, msgs), "Signature did not verify")
|
||||
}
|
||||
|
||||
@@ -56,6 +57,7 @@ func TestAggregateVerify_CompressedSignatures(t *testing.T) {
|
||||
msgs = append(msgs, msg)
|
||||
}
|
||||
aggSig := AggregateSignatures(sigs)
|
||||
// skipcq: GO-W1009
|
||||
assert.Equal(t, true, aggSig.AggregateVerify(pubkeys, msgs), "Signature did not verify")
|
||||
|
||||
aggSig2, err := AggregateCompressedSignatures(sigBytes)
|
||||
@@ -90,6 +92,29 @@ func TestVerifyCompressed(t *testing.T) {
|
||||
assert.Equal(t, true, VerifyCompressed(sig.Marshal(), pub.Marshal(), msg), "Compressed signatures and pubkeys did not verify")
|
||||
}
|
||||
|
||||
func TestVerifySingleSignature_InvalidSignature(t *testing.T) {
|
||||
priv, err := RandKey()
|
||||
require.NoError(t, err)
|
||||
pub := priv.PublicKey()
|
||||
msgA := [32]byte{'h', 'e', 'l', 'l', 'o'}
|
||||
msgB := [32]byte{'o', 'l', 'l', 'e', 'h'}
|
||||
sigA := priv.Sign(msgA[:]).Marshal()
|
||||
valid, err := VerifySignature(sigA, msgB, pub)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, false, valid, "Signature did verify")
|
||||
}
|
||||
|
||||
func TestVerifySingleSignature_ValidSignature(t *testing.T) {
|
||||
priv, err := RandKey()
|
||||
require.NoError(t, err)
|
||||
pub := priv.PublicKey()
|
||||
msg := [32]byte{'h', 'e', 'l', 'l', 'o'}
|
||||
sig := priv.Sign(msg[:]).Marshal()
|
||||
valid, err := VerifySignature(sig, msg, pub)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, true, valid, "Signature did not verify")
|
||||
}
|
||||
|
||||
func TestMultipleSignatureVerification(t *testing.T) {
|
||||
pubkeys := make([]common.PublicKey, 0, 100)
|
||||
sigs := make([][]byte, 0, 100)
|
||||
|
||||
@@ -1,22 +1,32 @@
|
||||
package bls
|
||||
|
||||
import "github.com/pkg/errors"
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// AggregatedSignature represents aggregated signature produced by AggregateBatch()
|
||||
const AggregatedSignature = "bls aggregated signature"
|
||||
|
||||
// SignatureBatch refers to the defined set of
|
||||
// signatures and its respective public keys and
|
||||
// messages required to verify it.
|
||||
type SignatureBatch struct {
|
||||
Signatures [][]byte
|
||||
PublicKeys []PublicKey
|
||||
Messages [][32]byte
|
||||
Signatures [][]byte
|
||||
PublicKeys []PublicKey
|
||||
Messages [][32]byte
|
||||
Descriptions []string
|
||||
}
|
||||
|
||||
// NewSet constructs an empty signature batch object.
|
||||
func NewSet() *SignatureBatch {
|
||||
return &SignatureBatch{
|
||||
Signatures: [][]byte{},
|
||||
PublicKeys: []PublicKey{},
|
||||
Messages: [][32]byte{},
|
||||
Signatures: [][]byte{},
|
||||
PublicKeys: []PublicKey{},
|
||||
Messages: [][32]byte{},
|
||||
Descriptions: []string{},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +35,7 @@ func (s *SignatureBatch) Join(set *SignatureBatch) *SignatureBatch {
|
||||
s.Signatures = append(s.Signatures, set.Signatures...)
|
||||
s.PublicKeys = append(s.PublicKeys, set.PublicKeys...)
|
||||
s.Messages = append(s.Messages, set.Messages...)
|
||||
s.Descriptions = append(s.Descriptions, set.Descriptions...)
|
||||
return s
|
||||
}
|
||||
|
||||
@@ -33,12 +44,49 @@ func (s *SignatureBatch) Verify() (bool, error) {
|
||||
return VerifyMultipleSignatures(s.Signatures, s.Messages, s.PublicKeys)
|
||||
}
|
||||
|
||||
// VerifyVerbosely verifies signatures as a whole at first, if fails, fallback
|
||||
// to verify each single signature to identify invalid ones.
|
||||
func (s *SignatureBatch) VerifyVerbosely() (bool, error) {
|
||||
valid, err := s.Verify()
|
||||
if err != nil || valid {
|
||||
return valid, err
|
||||
}
|
||||
|
||||
// if signature batch is invalid, we then verify signatures one by one.
|
||||
|
||||
errmsg := "some signatures are invalid. details:"
|
||||
for i := 0; i < len(s.Signatures); i++ {
|
||||
sig := s.Signatures[i]
|
||||
msg := s.Messages[i]
|
||||
pubKey := s.PublicKeys[i]
|
||||
|
||||
valid, err := VerifySignature(sig, msg, pubKey)
|
||||
if !valid {
|
||||
desc := s.Descriptions[i]
|
||||
if err != nil {
|
||||
errmsg += fmt.Sprintf("\nsignature '%s' is invalid."+
|
||||
" signature: 0x%s, public key: 0x%s, message: 0x%v, error: %v",
|
||||
desc, hex.EncodeToString(sig), hex.EncodeToString(pubKey.Marshal()),
|
||||
hex.EncodeToString(msg[:]), err)
|
||||
} else {
|
||||
errmsg += fmt.Sprintf("\nsignature '%s' is invalid."+
|
||||
" signature: 0x%s, public key: 0x%s, message: 0x%v",
|
||||
desc, hex.EncodeToString(sig), hex.EncodeToString(pubKey.Marshal()),
|
||||
hex.EncodeToString(msg[:]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false, errors.Errorf(errmsg)
|
||||
}
|
||||
|
||||
// Copy the attached signature batch and return it
|
||||
// to the caller.
|
||||
func (s *SignatureBatch) Copy() *SignatureBatch {
|
||||
signatures := make([][]byte, len(s.Signatures))
|
||||
pubkeys := make([]PublicKey, len(s.PublicKeys))
|
||||
messages := make([][32]byte, len(s.Messages))
|
||||
descriptions := make([]string, len(s.Descriptions))
|
||||
for i := range s.Signatures {
|
||||
sig := make([]byte, len(s.Signatures[i]))
|
||||
copy(sig, s.Signatures[i])
|
||||
@@ -50,10 +98,12 @@ func (s *SignatureBatch) Copy() *SignatureBatch {
|
||||
for i := range s.Messages {
|
||||
copy(messages[i][:], s.Messages[i][:])
|
||||
}
|
||||
copy(descriptions, s.Descriptions)
|
||||
return &SignatureBatch{
|
||||
Signatures: signatures,
|
||||
PublicKeys: pubkeys,
|
||||
Messages: messages,
|
||||
Signatures: signatures,
|
||||
PublicKeys: pubkeys,
|
||||
Messages: messages,
|
||||
Descriptions: descriptions,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,6 +132,7 @@ func (s *SignatureBatch) RemoveDuplicates() (int, *SignatureBatch, error) {
|
||||
sigs := s.Signatures[:0]
|
||||
pubs := s.PublicKeys[:0]
|
||||
msgs := s.Messages[:0]
|
||||
descs := s.Descriptions[:0]
|
||||
|
||||
for i := 0; i < len(s.Signatures); i++ {
|
||||
if duplicateSet[i] {
|
||||
@@ -90,11 +141,13 @@ func (s *SignatureBatch) RemoveDuplicates() (int, *SignatureBatch, error) {
|
||||
sigs = append(sigs, s.Signatures[i])
|
||||
pubs = append(pubs, s.PublicKeys[i])
|
||||
msgs = append(msgs, s.Messages[i])
|
||||
descs = append(descs, s.Descriptions[i])
|
||||
}
|
||||
|
||||
s.Signatures = sigs
|
||||
s.PublicKeys = pubs
|
||||
s.Messages = msgs
|
||||
s.Descriptions = descs
|
||||
|
||||
return len(duplicateSet), s, nil
|
||||
}
|
||||
@@ -103,12 +156,12 @@ func (s *SignatureBatch) RemoveDuplicates() (int, *SignatureBatch, error) {
|
||||
// reduce the number of pairings required when we finally verify the
|
||||
// whole batch.
|
||||
func (s *SignatureBatch) AggregateBatch() (*SignatureBatch, error) {
|
||||
if len(s.Signatures) == 0 || len(s.PublicKeys) == 0 || len(s.Messages) == 0 {
|
||||
return s, nil
|
||||
if len(s.Signatures) != len(s.PublicKeys) || len(s.Signatures) != len(s.Messages) || len(s.Signatures) != len(s.Descriptions) {
|
||||
return s, errors.Errorf("mismatch number of signatures, publickeys, messages and descriptions in signature batch. "+
|
||||
"Signatures %d, Public Keys %d , Messages %d, Descriptions %d", len(s.Signatures), len(s.PublicKeys), len(s.Messages), len(s.Descriptions))
|
||||
}
|
||||
if len(s.Signatures) != len(s.PublicKeys) || len(s.Signatures) != len(s.Messages) {
|
||||
return s, errors.Errorf("mismatch number of signatures, publickeys and messages in signature batch. "+
|
||||
"Signatures %d, Public Keys %d , Messages %d", s.Signatures, s.PublicKeys, s.Messages)
|
||||
if len(s.Signatures) == 0 {
|
||||
return s, nil
|
||||
}
|
||||
msgMap := make(map[[32]byte]*SignatureBatch)
|
||||
|
||||
@@ -119,12 +172,14 @@ func (s *SignatureBatch) AggregateBatch() (*SignatureBatch, error) {
|
||||
currBatch.Signatures = append(currBatch.Signatures, s.Signatures[i])
|
||||
currBatch.Messages = append(currBatch.Messages, s.Messages[i])
|
||||
currBatch.PublicKeys = append(currBatch.PublicKeys, s.PublicKeys[i])
|
||||
currBatch.Descriptions = append(currBatch.Descriptions, s.Descriptions[i])
|
||||
continue
|
||||
}
|
||||
currBatch = &SignatureBatch{
|
||||
Signatures: [][]byte{s.Signatures[i]},
|
||||
Messages: [][32]byte{s.Messages[i]},
|
||||
PublicKeys: []PublicKey{s.PublicKeys[i]},
|
||||
Signatures: [][]byte{s.Signatures[i]},
|
||||
Messages: [][32]byte{s.Messages[i]},
|
||||
PublicKeys: []PublicKey{s.PublicKeys[i]},
|
||||
Descriptions: []string{s.Descriptions[i]},
|
||||
}
|
||||
msgMap[currMsg] = currBatch
|
||||
}
|
||||
@@ -140,6 +195,7 @@ func (s *SignatureBatch) AggregateBatch() (*SignatureBatch, error) {
|
||||
b.PublicKeys = []PublicKey{aggPub}
|
||||
b.Signatures = [][]byte{aggSig.Marshal()}
|
||||
b.Messages = [][32]byte{copiedRt}
|
||||
b.Descriptions = []string{AggregatedSignature}
|
||||
}
|
||||
newObj := *b
|
||||
newSt = newSt.Join(&newObj)
|
||||
|
||||
@@ -2,13 +2,18 @@ package bls
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v3/crypto/bls/common"
|
||||
"github.com/prysmaticlabs/prysm/v3/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v3/testing/require"
|
||||
)
|
||||
|
||||
const TestSignature = "test signature"
|
||||
|
||||
func TestCopySignatureSet(t *testing.T) {
|
||||
t.Run("blst", func(t *testing.T) {
|
||||
key, err := RandKey()
|
||||
@@ -27,19 +32,22 @@ func TestCopySignatureSet(t *testing.T) {
|
||||
sig3 := key3.Sign(message3[:])
|
||||
|
||||
set := &SignatureBatch{
|
||||
Signatures: [][]byte{sig.Marshal()},
|
||||
PublicKeys: []PublicKey{key.PublicKey()},
|
||||
Messages: [][32]byte{message},
|
||||
Signatures: [][]byte{sig.Marshal()},
|
||||
PublicKeys: []PublicKey{key.PublicKey()},
|
||||
Messages: [][32]byte{message},
|
||||
Descriptions: createDescriptions(1),
|
||||
}
|
||||
set2 := &SignatureBatch{
|
||||
Signatures: [][]byte{sig2.Marshal()},
|
||||
PublicKeys: []PublicKey{key.PublicKey()},
|
||||
Messages: [][32]byte{message},
|
||||
Signatures: [][]byte{sig2.Marshal()},
|
||||
PublicKeys: []PublicKey{key.PublicKey()},
|
||||
Messages: [][32]byte{message},
|
||||
Descriptions: createDescriptions(1),
|
||||
}
|
||||
set3 := &SignatureBatch{
|
||||
Signatures: [][]byte{sig3.Marshal()},
|
||||
PublicKeys: []PublicKey{key.PublicKey()},
|
||||
Messages: [][32]byte{message},
|
||||
Signatures: [][]byte{sig3.Marshal()},
|
||||
PublicKeys: []PublicKey{key.PublicKey()},
|
||||
Messages: [][32]byte{message},
|
||||
Descriptions: createDescriptions(1),
|
||||
}
|
||||
aggSet := set.Join(set2).Join(set3)
|
||||
aggSet2 := aggSet.Copy()
|
||||
@@ -48,6 +56,38 @@ func TestCopySignatureSet(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestVerifyVerbosely_AllSignaturesValid(t *testing.T) {
|
||||
set := NewValidSignatureSet(t, "good", 3)
|
||||
valid, err := set.VerifyVerbosely()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, true, valid, "SignatureSet is expected to be valid")
|
||||
}
|
||||
|
||||
func TestVerifyVerbosely_SomeSignaturesInvalid(t *testing.T) {
|
||||
goodSet := NewValidSignatureSet(t, "good", 3)
|
||||
badSet := NewInvalidSignatureSet(t, "bad", 3, false)
|
||||
set := NewSet().Join(goodSet).Join(badSet)
|
||||
valid, err := set.VerifyVerbosely()
|
||||
assert.Equal(t, false, valid, "SignatureSet is expected to be invalid")
|
||||
assert.StringContains(t, "signature 'signature of bad0' is invalid", err.Error())
|
||||
assert.StringContains(t, "signature 'signature of bad1' is invalid", err.Error())
|
||||
assert.StringContains(t, "signature 'signature of bad2' is invalid", err.Error())
|
||||
assert.StringNotContains(t, "signature 'signature of good0' is invalid", err.Error())
|
||||
assert.StringNotContains(t, "signature 'signature of good1' is invalid", err.Error())
|
||||
assert.StringNotContains(t, "signature 'signature of good2' is invalid", err.Error())
|
||||
}
|
||||
|
||||
func TestVerifyVerbosely_VerificationThrowsError(t *testing.T) {
|
||||
goodSet := NewValidSignatureSet(t, "good", 1)
|
||||
badSet := NewInvalidSignatureSet(t, "bad", 1, true)
|
||||
set := NewSet().Join(goodSet).Join(badSet)
|
||||
valid, err := set.VerifyVerbosely()
|
||||
assert.Equal(t, false, valid, "SignatureSet is expected to be invalid")
|
||||
assert.StringContains(t, "signature 'signature of bad0' is invalid", err.Error())
|
||||
assert.StringContains(t, "error: could not unmarshal bytes into signature", err.Error())
|
||||
assert.StringNotContains(t, "signature 'signature of good0' is invalid", err.Error())
|
||||
}
|
||||
|
||||
func TestSignatureBatch_RemoveDuplicates(t *testing.T) {
|
||||
var keys []SecretKey
|
||||
for i := 0; i < 100; i++ {
|
||||
@@ -86,13 +126,15 @@ func TestSignatureBatch_RemoveDuplicates(t *testing.T) {
|
||||
allPubs := append(pubs, pubs...)
|
||||
allMsgs := append(messages, messages...)
|
||||
return &SignatureBatch{
|
||||
Signatures: allSigs,
|
||||
PublicKeys: allPubs,
|
||||
Messages: allMsgs,
|
||||
Signatures: allSigs,
|
||||
PublicKeys: allPubs,
|
||||
Messages: allMsgs,
|
||||
Descriptions: createDescriptions(len(allMsgs)),
|
||||
}, &SignatureBatch{
|
||||
Signatures: signatures,
|
||||
PublicKeys: pubs,
|
||||
Messages: messages,
|
||||
Signatures: signatures,
|
||||
PublicKeys: pubs,
|
||||
Messages: messages,
|
||||
Descriptions: createDescriptions(len(allMsgs)),
|
||||
}
|
||||
},
|
||||
want: 20,
|
||||
@@ -130,13 +172,15 @@ func TestSignatureBatch_RemoveDuplicates(t *testing.T) {
|
||||
allPubs := append(pubs, pubs...)
|
||||
allMsgs := append(messages, messages...)
|
||||
return &SignatureBatch{
|
||||
Signatures: allSigs,
|
||||
PublicKeys: allPubs,
|
||||
Messages: allMsgs,
|
||||
Signatures: allSigs,
|
||||
PublicKeys: allPubs,
|
||||
Messages: allMsgs,
|
||||
Descriptions: createDescriptions(len(allMsgs)),
|
||||
}, &SignatureBatch{
|
||||
Signatures: signatures,
|
||||
PublicKeys: pubs,
|
||||
Messages: messages,
|
||||
Signatures: signatures,
|
||||
PublicKeys: pubs,
|
||||
Messages: messages,
|
||||
Descriptions: createDescriptions(len(allMsgs)),
|
||||
}
|
||||
},
|
||||
want: 30,
|
||||
@@ -171,13 +215,15 @@ func TestSignatureBatch_RemoveDuplicates(t *testing.T) {
|
||||
pubs = append(pubs, k.PublicKey())
|
||||
}
|
||||
return &SignatureBatch{
|
||||
Signatures: signatures,
|
||||
PublicKeys: pubs,
|
||||
Messages: messages,
|
||||
Signatures: signatures,
|
||||
PublicKeys: pubs,
|
||||
Messages: messages,
|
||||
Descriptions: createDescriptions(len(messages)),
|
||||
}, &SignatureBatch{
|
||||
Signatures: signatures,
|
||||
PublicKeys: pubs,
|
||||
Messages: messages,
|
||||
Signatures: signatures,
|
||||
PublicKeys: pubs,
|
||||
Messages: messages,
|
||||
Descriptions: createDescriptions(len(messages)),
|
||||
}
|
||||
},
|
||||
want: 0,
|
||||
@@ -223,13 +269,15 @@ func TestSignatureBatch_RemoveDuplicates(t *testing.T) {
|
||||
// Zero out to expected result
|
||||
signatures[10] = make([]byte, 96)
|
||||
return &SignatureBatch{
|
||||
Signatures: allSigs,
|
||||
PublicKeys: allPubs,
|
||||
Messages: allMsgs,
|
||||
Signatures: allSigs,
|
||||
PublicKeys: allPubs,
|
||||
Messages: allMsgs,
|
||||
Descriptions: createDescriptions(len(allMsgs)),
|
||||
}, &SignatureBatch{
|
||||
Signatures: signatures,
|
||||
PublicKeys: pubs,
|
||||
Messages: messages,
|
||||
Signatures: signatures,
|
||||
PublicKeys: pubs,
|
||||
Messages: messages,
|
||||
Descriptions: createDescriptions(len(allMsgs)),
|
||||
}
|
||||
},
|
||||
want: 29,
|
||||
@@ -294,13 +342,15 @@ func TestSignatureBatch_RemoveDuplicates(t *testing.T) {
|
||||
messages[29] = [32]byte{'j', 'u', 'n', 'k'}
|
||||
|
||||
return &SignatureBatch{
|
||||
Signatures: allSigs,
|
||||
PublicKeys: allPubs,
|
||||
Messages: allMsgs,
|
||||
Signatures: allSigs,
|
||||
PublicKeys: allPubs,
|
||||
Messages: allMsgs,
|
||||
Descriptions: createDescriptions(len(allMsgs)),
|
||||
}, &SignatureBatch{
|
||||
Signatures: signatures,
|
||||
PublicKeys: pubs,
|
||||
Messages: messages,
|
||||
Signatures: signatures,
|
||||
PublicKeys: pubs,
|
||||
Messages: messages,
|
||||
Descriptions: createDescriptions(len(messages)),
|
||||
}
|
||||
},
|
||||
want: 27,
|
||||
@@ -342,11 +392,37 @@ func TestSignatureBatch_AggregateBatch(t *testing.T) {
|
||||
{
|
||||
name: "empty batch",
|
||||
batchCreator: func(t *testing.T) (*SignatureBatch, *SignatureBatch) {
|
||||
return &SignatureBatch{Signatures: nil, Messages: nil, PublicKeys: nil},
|
||||
&SignatureBatch{Signatures: nil, Messages: nil, PublicKeys: nil}
|
||||
return &SignatureBatch{Signatures: nil, Messages: nil, PublicKeys: nil, Descriptions: nil},
|
||||
&SignatureBatch{Signatures: nil, Messages: nil, PublicKeys: nil, Descriptions: nil}
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "mismatch number of signatures and messages in batch",
|
||||
batchCreator: func(t *testing.T) (*SignatureBatch, *SignatureBatch) {
|
||||
key1 := keys[0]
|
||||
key2 := keys[1]
|
||||
msg := [32]byte{'r', 'a', 'n', 'd', 'o', 'm'}
|
||||
sig1 := key1.Sign(msg[:])
|
||||
sig2 := key2.Sign(msg[:])
|
||||
signatures := [][]byte{sig1.Marshal(), sig2.Marshal()}
|
||||
pubs := []common.PublicKey{key1.PublicKey(), key2.PublicKey()}
|
||||
messages := [][32]byte{msg}
|
||||
descs := createDescriptions(2)
|
||||
return &SignatureBatch{
|
||||
Signatures: signatures,
|
||||
PublicKeys: pubs,
|
||||
Messages: messages,
|
||||
Descriptions: descs,
|
||||
}, &SignatureBatch{
|
||||
Signatures: signatures,
|
||||
PublicKeys: pubs,
|
||||
Messages: messages,
|
||||
Descriptions: descs,
|
||||
}
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "valid signatures in batch",
|
||||
batchCreator: func(t *testing.T) (*SignatureBatch, *SignatureBatch) {
|
||||
@@ -366,13 +442,15 @@ func TestSignatureBatch_AggregateBatch(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
aggPub := AggregateMultiplePubkeys(pubs)
|
||||
return &SignatureBatch{
|
||||
Signatures: signatures,
|
||||
PublicKeys: pubs,
|
||||
Messages: messages,
|
||||
Signatures: signatures,
|
||||
PublicKeys: pubs,
|
||||
Messages: messages,
|
||||
Descriptions: createDescriptions(len(messages)),
|
||||
}, &SignatureBatch{
|
||||
Signatures: [][]byte{aggSig.Marshal()},
|
||||
PublicKeys: []PublicKey{aggPub},
|
||||
Messages: [][32]byte{msg},
|
||||
Signatures: [][]byte{aggSig.Marshal()},
|
||||
PublicKeys: []PublicKey{aggPub},
|
||||
Messages: [][32]byte{msg},
|
||||
Descriptions: createDescriptions(1, AggregatedSignature),
|
||||
}
|
||||
},
|
||||
wantErr: false,
|
||||
@@ -394,9 +472,10 @@ func TestSignatureBatch_AggregateBatch(t *testing.T) {
|
||||
}
|
||||
signatures[10] = make([]byte, 96)
|
||||
return &SignatureBatch{
|
||||
Signatures: signatures,
|
||||
PublicKeys: pubs,
|
||||
Messages: messages,
|
||||
Signatures: signatures,
|
||||
PublicKeys: pubs,
|
||||
Messages: messages,
|
||||
Descriptions: createDescriptions(len(messages)),
|
||||
}, nil
|
||||
},
|
||||
wantErr: true,
|
||||
@@ -440,13 +519,15 @@ func TestSignatureBatch_AggregateBatch(t *testing.T) {
|
||||
aggPub2 := AggregateMultiplePubkeys(pubs[10:20])
|
||||
aggPub3 := AggregateMultiplePubkeys(pubs[20:30])
|
||||
return &SignatureBatch{
|
||||
Signatures: signatures,
|
||||
PublicKeys: pubs,
|
||||
Messages: messages,
|
||||
Signatures: signatures,
|
||||
PublicKeys: pubs,
|
||||
Messages: messages,
|
||||
Descriptions: createDescriptions(len(messages)),
|
||||
}, &SignatureBatch{
|
||||
Signatures: [][]byte{aggSig1.Marshal(), aggSig2.Marshal(), aggSig3.Marshal()},
|
||||
PublicKeys: []PublicKey{aggPub1, aggPub2, aggPub3},
|
||||
Messages: [][32]byte{msg, msg1, msg2},
|
||||
Signatures: [][]byte{aggSig1.Marshal(), aggSig2.Marshal(), aggSig3.Marshal()},
|
||||
PublicKeys: []PublicKey{aggPub1, aggPub2, aggPub3},
|
||||
Messages: [][32]byte{msg, msg1, msg2},
|
||||
Descriptions: createDescriptions(3, AggregatedSignature),
|
||||
}
|
||||
},
|
||||
wantErr: false,
|
||||
@@ -521,13 +602,15 @@ func TestSignatureBatch_AggregateBatch(t *testing.T) {
|
||||
aggPub3 := AggregateMultiplePubkeys(newPubs)
|
||||
|
||||
return &SignatureBatch{
|
||||
Signatures: signatures,
|
||||
PublicKeys: pubs,
|
||||
Messages: messages,
|
||||
Signatures: signatures,
|
||||
PublicKeys: pubs,
|
||||
Messages: messages,
|
||||
Descriptions: createDescriptions(len(messages)),
|
||||
}, &SignatureBatch{
|
||||
Signatures: [][]byte{aggSig1.Marshal(), signatures[5], aggSig2.Marshal(), signatures[15], aggSig3.Marshal(), signatures[25]},
|
||||
PublicKeys: []PublicKey{aggPub1, pubs[5], aggPub2, pubs[15], aggPub3, pubs[25]},
|
||||
Messages: [][32]byte{msg, messages[5], msg1, messages[15], msg2, messages[25]},
|
||||
Signatures: [][]byte{aggSig1.Marshal(), signatures[5], aggSig2.Marshal(), signatures[15], aggSig3.Marshal(), signatures[25]},
|
||||
PublicKeys: []PublicKey{aggPub1, pubs[5], aggPub2, pubs[15], aggPub3, pubs[25]},
|
||||
Messages: [][32]byte{msg, messages[5], msg1, messages[15], msg2, messages[25]},
|
||||
Descriptions: []string{AggregatedSignature, TestSignature, AggregatedSignature, TestSignature, AggregatedSignature, TestSignature},
|
||||
}
|
||||
},
|
||||
wantErr: false,
|
||||
@@ -556,10 +639,87 @@ func TestSignatureBatch_AggregateBatch(t *testing.T) {
|
||||
if !reflect.DeepEqual(got.Messages, output.Messages) {
|
||||
t.Errorf("AggregateBatch() Messages got = %v, want %v", got.Messages, output.Messages)
|
||||
}
|
||||
if !reflect.DeepEqual(got.Descriptions, output.Descriptions) {
|
||||
t.Errorf("AggregateBatch() Descriptions got = %v, want %v", got.Descriptions, output.Descriptions)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func NewValidSignatureSet(t *testing.T, msgBody string, num int) *SignatureBatch {
|
||||
set := &SignatureBatch{
|
||||
Signatures: make([][]byte, num),
|
||||
PublicKeys: make([]common.PublicKey, num),
|
||||
Messages: make([][32]byte, num),
|
||||
Descriptions: make([]string, num),
|
||||
}
|
||||
|
||||
for i := 0; i < num; i++ {
|
||||
priv, err := RandKey()
|
||||
require.NoError(t, err)
|
||||
pubkey := priv.PublicKey()
|
||||
msg := messageBytes(fmt.Sprintf("%s%d", msgBody, i))
|
||||
sig := priv.Sign(msg[:]).Marshal()
|
||||
desc := fmt.Sprintf("signature of %s%d", msgBody, i)
|
||||
|
||||
set.Signatures[i] = sig
|
||||
set.PublicKeys[i] = pubkey
|
||||
set.Messages[i] = msg
|
||||
set.Descriptions[i] = desc
|
||||
}
|
||||
|
||||
return set
|
||||
}
|
||||
|
||||
func NewInvalidSignatureSet(t *testing.T, msgBody string, num int, throwErr bool) *SignatureBatch {
|
||||
set := &SignatureBatch{
|
||||
Signatures: make([][]byte, num),
|
||||
PublicKeys: make([]common.PublicKey, num),
|
||||
Messages: make([][32]byte, num),
|
||||
Descriptions: make([]string, num),
|
||||
}
|
||||
|
||||
for i := 0; i < num; i++ {
|
||||
priv, err := RandKey()
|
||||
require.NoError(t, err)
|
||||
pubkey := priv.PublicKey()
|
||||
msg := messageBytes(fmt.Sprintf("%s%d", msgBody, i))
|
||||
var sig []byte
|
||||
if throwErr {
|
||||
sig = make([]byte, 96)
|
||||
} else {
|
||||
badMsg := messageBytes("badmsg")
|
||||
sig = priv.Sign(badMsg[:]).Marshal()
|
||||
}
|
||||
desc := fmt.Sprintf("signature of %s%d", msgBody, i)
|
||||
|
||||
set.Signatures[i] = sig
|
||||
set.PublicKeys[i] = pubkey
|
||||
set.Messages[i] = msg
|
||||
set.Descriptions[i] = desc
|
||||
}
|
||||
|
||||
return set
|
||||
}
|
||||
|
||||
func messageBytes(message string) [32]byte {
|
||||
bytes := [32]byte{}
|
||||
copy(bytes[:], []byte(message))
|
||||
return bytes
|
||||
}
|
||||
|
||||
func createDescriptions(length int, text ...string) []string {
|
||||
desc := make([]string, length)
|
||||
for i := range desc {
|
||||
if len(text) > 0 {
|
||||
desc[i] = text[0]
|
||||
} else {
|
||||
desc[i] = TestSignature
|
||||
}
|
||||
}
|
||||
return desc
|
||||
}
|
||||
|
||||
func sortSet(s *SignatureBatch) *SignatureBatch {
|
||||
sort.Sort(sorter{set: s})
|
||||
return s
|
||||
|
||||
Reference in New Issue
Block a user