Identify invalid signature within batch verification (#11582) (#11741)

* 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:
Ye Ding
2022-12-20 18:41:47 +08:00
committed by GitHub
parent 90d5f6097c
commit e43152102e
20 changed files with 486 additions and 131 deletions

View File

@@ -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)

View File

@@ -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.

View File

@@ -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)

View File

@@ -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)

View File

@@ -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