diff --git a/crypto/multisig/threshold_multisig.go b/crypto/multisig/threshold_multisig.go index 4ea69050..adc5fd12 100644 --- a/crypto/multisig/threshold_multisig.go +++ b/crypto/multisig/threshold_multisig.go @@ -34,7 +34,7 @@ func (pk *ThresholdMultiSignaturePubKey) VerifyBytes(msg []byte, marshalledSig [ return false } size := sig.BitArray.Size() - if len(sig.Sigs) < int(pk.K) || len(pk.Pubkeys) != size { + if len(sig.Sigs) < int(pk.K) || len(pk.Pubkeys) != size || sig.BitArray.NumOfTrueBitsBefore(size) < int(pk.K) { return false } // index in the list of signatures which we are concerned with. diff --git a/crypto/multisig/threshold_multisig_test.go b/crypto/multisig/threshold_multisig_test.go index c3c4263f..cbd447a2 100644 --- a/crypto/multisig/threshold_multisig_test.go +++ b/crypto/multisig/threshold_multisig_test.go @@ -19,9 +19,9 @@ func TestThresholdMultisig(t *testing.T) { require.False(t, multisigKey.VerifyBytes(msg, multisignature.Marshal())) multisignature.AddSignatureFromPubkey(sigs[0], pubkeys[0], pubkeys) require.False(t, multisigKey.VerifyBytes(msg, multisignature.Marshal())) - // Make sure adding the same signature twice doesn't make the signature pass + // Make sure adding the same signature twice doesn't increase number of signatures multisignature.AddSignatureFromPubkey(sigs[0], pubkeys[0], pubkeys) - require.False(t, multisigKey.VerifyBytes(msg, multisignature.Marshal())) + require.Equal(t, 1, len(multisignature.Sigs)) // Adding two signatures should make it pass, as k = 2 multisignature.AddSignatureFromPubkey(sigs[3], pubkeys[3], pubkeys) @@ -39,6 +39,18 @@ func TestThresholdMultisig(t *testing.T) { require.False(t, multisigKey.VerifyBytes(msg, multisignature.Marshal())) } +func TestThresholdMultisigDuplicateSignatures(t *testing.T) { + msg := []byte{1, 2, 3, 4, 5} + pubkeys, sigs := generatePubKeysAndSignatures(5, msg) + multisigKey := NewThresholdMultiSignaturePubKey(2, pubkeys) + multisignature := NewMultisig(5) + require.False(t, multisigKey.VerifyBytes(msg, multisignature.Marshal())) + multisignature.AddSignatureFromPubkey(sigs[0], pubkeys[0], pubkeys) + // Add second signature manually + multisignature.Sigs = append(multisignature.Sigs, sigs[0]) + require.False(t, multisigKey.VerifyBytes(msg, multisignature.Marshal())) +} + func TestMultiSigPubkeyEquality(t *testing.T) { msg := []byte{1, 2, 3, 4} pubkeys, _ := generatePubKeysAndSignatures(5, msg)