|
|
|
package bls
|
|
|
|
|
|
|
|
import (
|
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/harmony-one/bls/ffi/go/bls"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Test the basic functionality of a BLS multi-sig mask.
|
|
|
|
func TestNewMask(test *testing.T) {
|
|
|
|
pubKey1 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
pubKey2 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
pubKey3 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
|
|
|
|
pubKey1.Bytes.FromLibBLSPublicKey(pubKey1.Object)
|
|
|
|
pubKey2.Bytes.FromLibBLSPublicKey(pubKey2.Object)
|
|
|
|
pubKey3.Bytes.FromLibBLSPublicKey(pubKey3.Object)
|
|
|
|
mask, err := NewMask([]PublicKeyWrapper{pubKey1, pubKey2, pubKey3}, &pubKey1)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
test.Errorf("Failed to create a new Mask: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if mask.Len() != 1 {
|
|
|
|
test.Errorf("Mask created with wrong size: %d", mask.Len())
|
|
|
|
}
|
|
|
|
|
|
|
|
enabled, err := mask.KeyEnabled(pubKey1.Bytes)
|
|
|
|
if !enabled || err != nil {
|
|
|
|
test.Errorf("My key pubKey1 should have been enabled: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if mask.CountEnabled() != 1 {
|
|
|
|
test.Error("Only one key should have been enabled")
|
|
|
|
}
|
|
|
|
|
|
|
|
if mask.CountTotal() != 3 {
|
|
|
|
test.Error("Should have a total of 3 keys")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestNewMaskWithAbsentPublicKey(test *testing.T) {
|
|
|
|
pubKey1 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
pubKey2 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
pubKey3 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
pubKey4 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
|
|
|
|
pubKey1.Bytes.FromLibBLSPublicKey(pubKey1.Object)
|
|
|
|
pubKey2.Bytes.FromLibBLSPublicKey(pubKey2.Object)
|
|
|
|
pubKey3.Bytes.FromLibBLSPublicKey(pubKey3.Object)
|
|
|
|
pubKey4.Bytes.FromLibBLSPublicKey(pubKey4.Object)
|
|
|
|
|
|
|
|
mask, err := NewMask([]PublicKeyWrapper{pubKey1, pubKey2, pubKey3}, &pubKey4)
|
|
|
|
|
|
|
|
if err == nil {
|
|
|
|
test.Errorf("Failed to create a new Mask: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if mask != nil {
|
|
|
|
test.Errorf("Expected failure to create a new mask")
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestThreshHoldPolicy(test *testing.T) {
|
|
|
|
pubKey1 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
pubKey2 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
pubKey3 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
|
|
|
|
pubKey1.Bytes.FromLibBLSPublicKey(pubKey1.Object)
|
|
|
|
pubKey2.Bytes.FromLibBLSPublicKey(pubKey2.Object)
|
|
|
|
pubKey3.Bytes.FromLibBLSPublicKey(pubKey3.Object)
|
|
|
|
mask, err := NewMask([]PublicKeyWrapper{pubKey1, pubKey2, pubKey3}, &pubKey1)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
test.Errorf("Failed to create a new Mask: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if mask.Len() != 1 {
|
|
|
|
test.Errorf("Mask created with wrong size: %d", mask.Len())
|
|
|
|
}
|
|
|
|
|
|
|
|
threshHoldPolicy := *NewThresholdPolicy(1)
|
|
|
|
|
|
|
|
mask.SetKey(pubKey1.Bytes, true)
|
|
|
|
mask.SetKey(pubKey2.Bytes, true)
|
|
|
|
|
|
|
|
if mask.CountEnabled() != 2 {
|
|
|
|
test.Errorf("Number of enabled nodes: %d , expected count = 2 ", mask.CountEnabled())
|
|
|
|
}
|
|
|
|
|
|
|
|
if !threshHoldPolicy.Check(mask) {
|
|
|
|
test.Error("Number of enabled nodes less than threshold")
|
|
|
|
}
|
|
|
|
|
|
|
|
mask.SetKey(pubKey1.Bytes, false)
|
|
|
|
mask.SetKey(pubKey2.Bytes, false)
|
|
|
|
|
|
|
|
if threshHoldPolicy.Check(mask) {
|
|
|
|
test.Error("Number of enabled nodes more than equal to threshold")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCompletePolicy(test *testing.T) {
|
|
|
|
pubKey1 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
pubKey2 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
pubKey3 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
|
|
|
|
pubKey1.Bytes.FromLibBLSPublicKey(pubKey1.Object)
|
|
|
|
pubKey2.Bytes.FromLibBLSPublicKey(pubKey2.Object)
|
|
|
|
pubKey3.Bytes.FromLibBLSPublicKey(pubKey3.Object)
|
|
|
|
mask, err := NewMask([]PublicKeyWrapper{pubKey1, pubKey2, pubKey3}, &pubKey1)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
test.Errorf("Failed to create a new Mask: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if mask.Len() != 1 {
|
|
|
|
test.Errorf("Mask created with wrong size: %d", mask.Len())
|
|
|
|
}
|
|
|
|
|
|
|
|
completePolicy := CompletePolicy{}
|
|
|
|
|
|
|
|
mask.SetKey(pubKey1.Bytes, true)
|
|
|
|
mask.SetKey(pubKey2.Bytes, true)
|
|
|
|
mask.SetKey(pubKey3.Bytes, true)
|
|
|
|
|
|
|
|
if mask.CountEnabled() != 3 {
|
|
|
|
test.Errorf("Number of enabled nodes: %d , expected count = 3 ", mask.CountEnabled())
|
|
|
|
}
|
|
|
|
|
|
|
|
if !completePolicy.Check(mask) {
|
|
|
|
test.Error("Number of enabled nodes not equal to total count")
|
|
|
|
}
|
|
|
|
|
|
|
|
mask.SetKey(pubKey1.Bytes, false)
|
|
|
|
|
|
|
|
if completePolicy.Check(mask) {
|
|
|
|
test.Error("Number of enabled nodes equal to total count")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestAggregatedSignature(test *testing.T) {
|
|
|
|
var sec bls.SecretKey
|
|
|
|
sec.SetByCSPRNG()
|
|
|
|
|
|
|
|
signs := []*bls.Sign{sec.Sign("message1"), sec.Sign("message2")}
|
|
|
|
|
|
|
|
multiSignature := AggregateSig(signs)
|
|
|
|
|
|
|
|
str := multiSignature.SerializeToHexStr()
|
|
|
|
|
|
|
|
if strings.Compare(multiSignature.SerializeToHexStr(), "0") == 0 {
|
|
|
|
test.Error("Error creating multisignature", str)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestAggregateMasks(test *testing.T) {
|
|
|
|
message := []byte("message")
|
|
|
|
newMessage := []byte("message")
|
|
|
|
emptyMessage := []byte("")
|
|
|
|
|
|
|
|
aggMask, err := AggregateMasks(message, emptyMessage)
|
|
|
|
if aggMask != nil {
|
|
|
|
test.Error("Expected mismatching bitmap lengths")
|
|
|
|
}
|
|
|
|
if err == nil {
|
|
|
|
test.Error("Expected error thrown because of bitmap length mismatch")
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, err := AggregateMasks(message, newMessage); err != nil {
|
|
|
|
test.Error("Error thrown in aggregating masks")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestEnableKeyFunctions(test *testing.T) {
|
|
|
|
pubKey1 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
pubKey2 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
pubKey3 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
pubKey4 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
|
|
|
|
pubKey1.Bytes.FromLibBLSPublicKey(pubKey1.Object)
|
|
|
|
pubKey2.Bytes.FromLibBLSPublicKey(pubKey2.Object)
|
|
|
|
pubKey3.Bytes.FromLibBLSPublicKey(pubKey3.Object)
|
|
|
|
pubKey4.Bytes.FromLibBLSPublicKey(pubKey4.Object)
|
|
|
|
mask, err := NewMask([]PublicKeyWrapper{pubKey1, pubKey2, pubKey3}, &pubKey1)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
test.Errorf("Failed to create a new Mask: %s", err)
|
|
|
|
}
|
|
|
|
length := mask.Len()
|
|
|
|
_ = length
|
|
|
|
|
|
|
|
if mask.Len() != 1 {
|
|
|
|
test.Errorf("Mask created with wrong size: %d", mask.Len())
|
|
|
|
}
|
|
|
|
|
|
|
|
mask.SetBit(0, true)
|
|
|
|
mask.SetBit(1, false)
|
|
|
|
mask.SetBit(0, true)
|
|
|
|
|
|
|
|
if err := mask.SetBit(5, true); err == nil {
|
|
|
|
test.Error("Expected index out of range error")
|
|
|
|
}
|
|
|
|
|
|
|
|
enabledKeys := mask.GetPubKeyFromMask(true)
|
|
|
|
disabledKeys := mask.GetPubKeyFromMask(false)
|
|
|
|
|
|
|
|
if len(enabledKeys) != 1 {
|
|
|
|
test.Error("Count of enabled keys doesn't match")
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(disabledKeys) != 2 {
|
|
|
|
test.Error("Count of disabled keys don't match")
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, error := mask.KeyEnabled(pubKey4.Bytes); error == nil {
|
|
|
|
test.Error("Expected key not found error")
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, error := mask.IndexEnabled(5); error == nil {
|
|
|
|
test.Error("Expected index out of range error")
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := mask.SetKey(pubKey4.Bytes, true); err == nil {
|
|
|
|
test.Error("Expected key not found error")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetSignedPubKeysFromBitmap(test *testing.T) {
|
|
|
|
pubKey1 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
pubKey2 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
pubKey3 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
pubKey4 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
|
|
|
|
pubKey1.Bytes.FromLibBLSPublicKey(pubKey1.Object)
|
|
|
|
pubKey2.Bytes.FromLibBLSPublicKey(pubKey2.Object)
|
|
|
|
pubKey3.Bytes.FromLibBLSPublicKey(pubKey3.Object)
|
|
|
|
pubKey4.Bytes.FromLibBLSPublicKey(pubKey4.Object)
|
|
|
|
mask, err := NewMask([]PublicKeyWrapper{pubKey1, pubKey2, pubKey3}, &pubKey1)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
test.Errorf("Failed to create a new Mask: %s", err)
|
|
|
|
}
|
|
|
|
length := mask.Len()
|
|
|
|
_ = length
|
|
|
|
|
|
|
|
if mask.Len() != 1 {
|
|
|
|
test.Errorf("Mask created with wrong size: %d", mask.Len())
|
|
|
|
}
|
|
|
|
|
|
|
|
mask.SetBit(0, true)
|
|
|
|
mask.SetBit(1, false)
|
|
|
|
mask.SetBit(0, true)
|
|
|
|
mask.SetBit(2, true)
|
|
|
|
|
|
|
|
enabledKeysFromBitmap, _ := mask.GetSignedPubKeysFromBitmap(mask.Bitmap)
|
|
|
|
|
|
|
|
if len(enabledKeysFromBitmap) != 2 ||
|
|
|
|
!enabledKeysFromBitmap[0].Object.IsEqual(pubKey1.Object) || !enabledKeysFromBitmap[1].Object.IsEqual(pubKey3.Object) {
|
|
|
|
test.Error("Enabled keys from bitmap are incorrect")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSetKeyAtomic(test *testing.T) {
|
|
|
|
pubKey1 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
pubKey2 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
pubKey3 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
pubKey4 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
|
|
|
|
pubKey1.Bytes.FromLibBLSPublicKey(pubKey1.Object)
|
|
|
|
pubKey2.Bytes.FromLibBLSPublicKey(pubKey2.Object)
|
|
|
|
pubKey3.Bytes.FromLibBLSPublicKey(pubKey3.Object)
|
|
|
|
pubKey4.Bytes.FromLibBLSPublicKey(pubKey4.Object)
|
|
|
|
mask, err := NewMask([]PublicKeyWrapper{pubKey1, pubKey2, pubKey3}, &pubKey1)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
test.Errorf("Failed to create a new Mask: %s", err)
|
|
|
|
}
|
|
|
|
length := mask.Len()
|
|
|
|
_ = length
|
|
|
|
|
|
|
|
if mask.Len() != 1 {
|
|
|
|
test.Errorf("Mask created with wrong size: %d", mask.Len())
|
|
|
|
}
|
|
|
|
|
|
|
|
mask.SetKey(pubKey1.Bytes, true)
|
|
|
|
|
|
|
|
enabledKeysFromBitmap, _ := mask.GetSignedPubKeysFromBitmap(mask.Bitmap)
|
|
|
|
|
|
|
|
if len(enabledKeysFromBitmap) != 1 ||
|
|
|
|
!enabledKeysFromBitmap[0].Object.IsEqual(pubKey1.Object) {
|
|
|
|
test.Error("Enabled keys from bitmap are incorrect")
|
|
|
|
}
|
|
|
|
|
|
|
|
mask.SetKeysAtomic([]*PublicKeyWrapper{&pubKey1, &pubKey2}, true)
|
|
|
|
|
|
|
|
enabledKeysFromBitmap, _ = mask.GetSignedPubKeysFromBitmap(mask.Bitmap)
|
|
|
|
if len(enabledKeysFromBitmap) != 2 ||
|
|
|
|
!enabledKeysFromBitmap[0].Object.IsEqual(pubKey1.Object) || !enabledKeysFromBitmap[1].Object.IsEqual(pubKey2.Object) {
|
|
|
|
test.Error("Enabled keys from bitmap are incorrect")
|
|
|
|
}
|
|
|
|
|
|
|
|
err = mask.SetKeysAtomic([]*PublicKeyWrapper{&pubKey1, &pubKey4}, true)
|
|
|
|
|
|
|
|
if !strings.Contains(err.Error(), "key not found") {
|
|
|
|
test.Error(err, "expect error due to key not found")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCopyParticipatingMask(test *testing.T) {
|
|
|
|
pubKey1 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
pubKey2 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
|
|
|
|
pubKey1.Bytes.FromLibBLSPublicKey(pubKey1.Object)
|
|
|
|
pubKey2.Bytes.FromLibBLSPublicKey(pubKey2.Object)
|
|
|
|
mask, _ := NewMask([]PublicKeyWrapper{pubKey1, pubKey2}, &pubKey1)
|
|
|
|
|
|
|
|
clonedMask := mask.Mask()
|
|
|
|
|
|
|
|
if len(clonedMask) != 1 {
|
|
|
|
test.Error("Length of clonedMask doesn't match")
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSetMask(test *testing.T) {
|
|
|
|
pubKey1 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
pubKey2 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
|
|
|
|
|
|
|
|
pubKey1.Bytes.FromLibBLSPublicKey(pubKey1.Object)
|
|
|
|
pubKey2.Bytes.FromLibBLSPublicKey(pubKey2.Object)
|
|
|
|
mask, _ := NewMask([]PublicKeyWrapper{pubKey1, pubKey2}, &pubKey1)
|
|
|
|
|
|
|
|
_ = mask
|
|
|
|
maskBytes := []byte{3}
|
|
|
|
mask.SetMask(maskBytes)
|
|
|
|
|
|
|
|
if mask.CountEnabled() != 2 {
|
|
|
|
test.Error("Count of Enabled nodes doesn't match")
|
|
|
|
}
|
|
|
|
|
|
|
|
newMaskBytes := []byte{3, 2}
|
|
|
|
|
|
|
|
if err := mask.SetMask(newMaskBytes); err == nil {
|
|
|
|
test.Error("Expected mismatching Bitmap lengths")
|
|
|
|
}
|
|
|
|
}
|