mirror of
https://github.com/fluencelabs/tendermint
synced 2025-05-15 08:01:19 +00:00
(squash this) begin addressing PR comments
This commit is contained in:
parent
aab26c3ff7
commit
00db469fc0
@ -31,6 +31,7 @@ func getIndex(pk crypto.PubKey, keys []crypto.PubKey) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AddSignature adds a signature to the multisig, at the corresponding index.
|
// AddSignature adds a signature to the multisig, at the corresponding index.
|
||||||
|
// If the signature already exists, replace it.
|
||||||
func (mSig *Multisignature) AddSignature(sig []byte, index int) {
|
func (mSig *Multisignature) AddSignature(sig []byte, index int) {
|
||||||
newSigIndex := mSig.BitArray.NumOfTrueBitsBefore(index)
|
newSigIndex := mSig.BitArray.NumOfTrueBitsBefore(index)
|
||||||
// Signature already exists, just replace the value there
|
// Signature already exists, just replace the value there
|
||||||
@ -64,5 +65,5 @@ func (mSig *Multisignature) AddSignatureFromPubkey(sig []byte, pubkey crypto.Pub
|
|||||||
|
|
||||||
// Marshal the multisignature with amino
|
// Marshal the multisignature with amino
|
||||||
func (mSig *Multisignature) Marshal() []byte {
|
func (mSig *Multisignature) Marshal() []byte {
|
||||||
return cdc.MustMarshalBinary(mSig)
|
return cdc.MustMarshalBinaryBare(mSig)
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,11 @@ type ThresholdMultiSignaturePubKey struct {
|
|||||||
var _ crypto.PubKey = &ThresholdMultiSignaturePubKey{}
|
var _ crypto.PubKey = &ThresholdMultiSignaturePubKey{}
|
||||||
|
|
||||||
// NewThresholdMultiSignaturePubKey returns a new ThresholdMultiSignaturePubKey.
|
// NewThresholdMultiSignaturePubKey returns a new ThresholdMultiSignaturePubKey.
|
||||||
|
// Panics if len(pubkeys) < k or 0 >= k.
|
||||||
func NewThresholdMultiSignaturePubKey(k int, pubkeys []crypto.PubKey) crypto.PubKey {
|
func NewThresholdMultiSignaturePubKey(k int, pubkeys []crypto.PubKey) crypto.PubKey {
|
||||||
|
if k <= 0 {
|
||||||
|
panic("threshold k of n multisignature: k <= 0")
|
||||||
|
}
|
||||||
if len(pubkeys) < k {
|
if len(pubkeys) < k {
|
||||||
panic("threshold k of n multisignature: len(pubkeys) < k")
|
panic("threshold k of n multisignature: len(pubkeys) < k")
|
||||||
}
|
}
|
||||||
@ -29,12 +33,21 @@ func NewThresholdMultiSignaturePubKey(k int, pubkeys []crypto.PubKey) crypto.Pub
|
|||||||
// a concern.
|
// a concern.
|
||||||
func (pk *ThresholdMultiSignaturePubKey) VerifyBytes(msg []byte, marshalledSig []byte) bool {
|
func (pk *ThresholdMultiSignaturePubKey) VerifyBytes(msg []byte, marshalledSig []byte) bool {
|
||||||
var sig *Multisignature
|
var sig *Multisignature
|
||||||
err := cdc.UnmarshalBinary(marshalledSig, &sig)
|
err := cdc.UnmarshalBinaryBare(marshalledSig, &sig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
size := sig.BitArray.Size()
|
size := sig.BitArray.Size()
|
||||||
if len(sig.Sigs) < int(pk.K) || len(pk.Pubkeys) != size || sig.BitArray.NumOfTrueBitsBefore(size) < int(pk.K) {
|
// ensure bit array is the correct size
|
||||||
|
if len(pk.Pubkeys) != size {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// ensure size of signature list
|
||||||
|
if len(sig.Sigs) < int(pk.K) || len(sig.Sigs) > size {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// ensure at least k signatures are set
|
||||||
|
if sig.BitArray.NumOfTrueBitsBefore(size) < int(pk.K) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// index in the list of signatures which we are concerned with.
|
// index in the list of signatures which we are concerned with.
|
||||||
@ -63,7 +76,10 @@ func (pk *ThresholdMultiSignaturePubKey) Address() crypto.Address {
|
|||||||
// Equals returns true iff pk and other both have the same number of keys, and
|
// Equals returns true iff pk and other both have the same number of keys, and
|
||||||
// all constituent keys are the same, and in the same order.
|
// all constituent keys are the same, and in the same order.
|
||||||
func (pk *ThresholdMultiSignaturePubKey) Equals(other crypto.PubKey) bool {
|
func (pk *ThresholdMultiSignaturePubKey) Equals(other crypto.PubKey) bool {
|
||||||
if otherKey, ok := other.(*ThresholdMultiSignaturePubKey); ok {
|
otherKey, sameType := other.(*ThresholdMultiSignaturePubKey)
|
||||||
|
if !sameType {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if pk.K != otherKey.K || len(pk.Pubkeys) != len(otherKey.Pubkeys) {
|
if pk.K != otherKey.K || len(pk.Pubkeys) != len(otherKey.Pubkeys) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -74,5 +90,3 @@ func (pk *ThresholdMultiSignaturePubKey) Equals(other crypto.PubKey) bool {
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
@ -11,34 +11,60 @@ import (
|
|||||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestThresholdMultisig(t *testing.T) {
|
// This tests multisig functionality, but it expects the first k signatures to be valid
|
||||||
msg := []byte{1, 2, 3, 4}
|
// TODO: Adapt it to give more flexibility about first k signatures being valid
|
||||||
pubkeys, sigs := generatePubKeysAndSignatures(5, msg)
|
func TestThresholdMultisigValidCases(t *testing.T) {
|
||||||
multisigKey := NewThresholdMultiSignaturePubKey(2, pubkeys)
|
pkSet1, sigSet1 := generatePubKeysAndSignatures(5, []byte{1, 2, 3, 4})
|
||||||
multisignature := NewMultisig(5)
|
cases := []struct {
|
||||||
require.False(t, multisigKey.VerifyBytes(msg, multisignature.Marshal()))
|
msg []byte
|
||||||
multisignature.AddSignatureFromPubkey(sigs[0], pubkeys[0], pubkeys)
|
k int
|
||||||
require.False(t, multisigKey.VerifyBytes(msg, multisignature.Marshal()))
|
pubkeys []crypto.PubKey
|
||||||
// Make sure adding the same signature twice doesn't increase number of signatures
|
signingIndices []int
|
||||||
multisignature.AddSignatureFromPubkey(sigs[0], pubkeys[0], pubkeys)
|
// signatures should be the same size as signingIndices.
|
||||||
require.Equal(t, 1, len(multisignature.Sigs))
|
signatures [][]byte
|
||||||
|
passAfterKSignatures []bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
msg: []byte{1, 2, 3, 4},
|
||||||
|
k: 2,
|
||||||
|
pubkeys: pkSet1,
|
||||||
|
signingIndices: []int{0, 3, 1},
|
||||||
|
signatures: sigSet1,
|
||||||
|
passAfterKSignatures: []bool{false},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for tcIndex, tc := range cases {
|
||||||
|
multisigKey := NewThresholdMultiSignaturePubKey(tc.k, tc.pubkeys)
|
||||||
|
multisignature := NewMultisig(len(tc.pubkeys))
|
||||||
|
for i := 0; i < tc.k-1; i++ {
|
||||||
|
signingIndex := tc.signingIndices[i]
|
||||||
|
multisignature.AddSignatureFromPubkey(tc.signatures[signingIndex], tc.pubkeys[signingIndex], tc.pubkeys)
|
||||||
|
require.False(t, multisigKey.VerifyBytes(tc.msg, multisignature.Marshal()),
|
||||||
|
"multisig passed when i < k, tc %d, i %d", tcIndex, i)
|
||||||
|
multisignature.AddSignatureFromPubkey(tc.signatures[signingIndex], tc.pubkeys[signingIndex], tc.pubkeys)
|
||||||
|
require.Equal(t, i+1, len(multisignature.Sigs),
|
||||||
|
"adding a signature for the same pubkey twice increased signature count by 2, tc %d", tcIndex)
|
||||||
|
}
|
||||||
|
require.False(t, multisigKey.VerifyBytes(tc.msg, multisignature.Marshal()),
|
||||||
|
"multisig passed with k - 1 sigs, tc %d", tcIndex)
|
||||||
|
multisignature.AddSignatureFromPubkey(tc.signatures[tc.signingIndices[tc.k]], tc.pubkeys[tc.signingIndices[tc.k]], tc.pubkeys)
|
||||||
|
require.True(t, multisigKey.VerifyBytes(tc.msg, multisignature.Marshal()),
|
||||||
|
"multisig failed after k good signatures, tc %d", tcIndex)
|
||||||
|
for i := tc.k + 1; i < len(tc.signingIndices); i++ {
|
||||||
|
signingIndex := tc.signingIndices[i]
|
||||||
|
multisignature.AddSignatureFromPubkey(tc.signatures[signingIndex], tc.pubkeys[signingIndex], tc.pubkeys)
|
||||||
|
require.Equal(t, tc.passAfterKSignatures[i-tc.k-1],
|
||||||
|
multisigKey.VerifyBytes(tc.msg, multisignature.Marshal()),
|
||||||
|
"multisig didn't verify as expected after k sigs, tc %d, i %d", tcIndex, i)
|
||||||
|
|
||||||
// Adding two signatures should make it pass, as k = 2
|
multisignature.AddSignatureFromPubkey(tc.signatures[signingIndex], tc.pubkeys[signingIndex], tc.pubkeys)
|
||||||
multisignature.AddSignatureFromPubkey(sigs[3], pubkeys[3], pubkeys)
|
require.Equal(t, i+1, len(multisignature.Sigs),
|
||||||
require.True(t, multisigKey.VerifyBytes(msg, multisignature.Marshal()))
|
"adding a signature for the same pubkey twice increased signature count by 2, tc %d", tcIndex)
|
||||||
|
}
|
||||||
// Adding a third invalid signature should make verification fail.
|
}
|
||||||
multisignature.AddSignatureFromPubkey(sigs[0], pubkeys[4], pubkeys)
|
|
||||||
require.False(t, multisigKey.VerifyBytes(msg, multisignature.Marshal()))
|
|
||||||
|
|
||||||
// try adding the invalid signature one signature before
|
|
||||||
// first reset the multisig
|
|
||||||
multisignature.BitArray.SetIndex(4, false)
|
|
||||||
multisignature.Sigs = multisignature.Sigs[:2]
|
|
||||||
multisignature.AddSignatureFromPubkey(sigs[0], pubkeys[2], pubkeys)
|
|
||||||
require.False(t, multisigKey.VerifyBytes(msg, multisignature.Marshal()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Fully replace this test with table driven tests
|
||||||
func TestThresholdMultisigDuplicateSignatures(t *testing.T) {
|
func TestThresholdMultisigDuplicateSignatures(t *testing.T) {
|
||||||
msg := []byte{1, 2, 3, 4, 5}
|
msg := []byte{1, 2, 3, 4, 5}
|
||||||
pubkeys, sigs := generatePubKeysAndSignatures(5, msg)
|
pubkeys, sigs := generatePubKeysAndSignatures(5, msg)
|
||||||
@ -51,6 +77,7 @@ func TestThresholdMultisigDuplicateSignatures(t *testing.T) {
|
|||||||
require.False(t, multisigKey.VerifyBytes(msg, multisignature.Marshal()))
|
require.False(t, multisigKey.VerifyBytes(msg, multisignature.Marshal()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Fully replace this test with table driven tests
|
||||||
func TestMultiSigPubkeyEquality(t *testing.T) {
|
func TestMultiSigPubkeyEquality(t *testing.T) {
|
||||||
msg := []byte{1, 2, 3, 4}
|
msg := []byte{1, 2, 3, 4}
|
||||||
pubkeys, _ := generatePubKeysAndSignatures(5, msg)
|
pubkeys, _ := generatePubKeysAndSignatures(5, msg)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user