mirror of
				https://source.quilibrium.com/quilibrium/ceremonyclient.git
				synced 2025-11-04 13:27:27 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			286 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			286 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
//
 | 
						|
// Copyright Coinbase, Inc. All Rights Reserved.
 | 
						|
//
 | 
						|
// SPDX-License-Identifier: Apache-2.0
 | 
						|
//
 | 
						|
 | 
						|
package bls_sig
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"crypto/rand"
 | 
						|
	"encoding"
 | 
						|
	"math/big"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	"source.quilibrium.com/quilibrium/monorepo/nekryptology/internal"
 | 
						|
	"source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/core/curves/native/bls12381"
 | 
						|
)
 | 
						|
 | 
						|
func genSecretKey(t *testing.T) *SecretKey {
 | 
						|
	ikm := make([]byte, 32)
 | 
						|
	sk, err := new(SecretKey).Generate(ikm)
 | 
						|
	if err != nil {
 | 
						|
		t.Errorf("Couldn't generate secret key")
 | 
						|
	}
 | 
						|
	return sk
 | 
						|
}
 | 
						|
 | 
						|
func genRandSecretKey(ikm []byte, t *testing.T) *SecretKey {
 | 
						|
	sk, err := new(SecretKey).Generate(ikm)
 | 
						|
	if err != nil {
 | 
						|
		t.Errorf("Couldn't generate secret key")
 | 
						|
	}
 | 
						|
	return sk
 | 
						|
}
 | 
						|
 | 
						|
func genPublicKeyVt(sk *SecretKey, t *testing.T) *PublicKeyVt {
 | 
						|
	pk, err := sk.GetPublicKeyVt()
 | 
						|
	if err != nil {
 | 
						|
		t.Errorf("Expected GetPublicKeyVt to pass but failed: %v", err)
 | 
						|
	}
 | 
						|
	return pk
 | 
						|
}
 | 
						|
 | 
						|
func genPublicKey(sk *SecretKey, t *testing.T) *PublicKey {
 | 
						|
	pk, err := sk.GetPublicKey()
 | 
						|
	if err != nil {
 | 
						|
		t.Errorf("GetPublicKey failed. Couldn't generate public key: %v", err)
 | 
						|
	}
 | 
						|
	return pk
 | 
						|
}
 | 
						|
 | 
						|
func genSignature(sk *SecretKey, message []byte, t *testing.T) *Signature {
 | 
						|
	bls := NewSigPop()
 | 
						|
 | 
						|
	sig, err := bls.Sign(sk, message)
 | 
						|
	if err != nil {
 | 
						|
		t.Errorf("createSignature couldn't sign message: %v", err)
 | 
						|
	}
 | 
						|
	return sig
 | 
						|
}
 | 
						|
 | 
						|
func genSignatureVt(sk *SecretKey, message []byte, t *testing.T) *SignatureVt {
 | 
						|
	bls := NewSigPopVt()
 | 
						|
	sig, err := bls.Sign(sk, message)
 | 
						|
	if err != nil {
 | 
						|
		t.Errorf("createSignatureVt couldn't sign message: %v", err)
 | 
						|
	}
 | 
						|
	return sig
 | 
						|
}
 | 
						|
 | 
						|
func readRand(ikm []byte, t *testing.T) {
 | 
						|
	n, err := rand.Read(ikm)
 | 
						|
	if err != nil || n < len(ikm) {
 | 
						|
		t.Errorf("Not enough data was read or an error occurred")
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func assertSecretKeyGen(seed, expected []byte, t *testing.T) {
 | 
						|
	sk, err := new(SecretKey).Generate(seed)
 | 
						|
	if err != nil {
 | 
						|
		t.Errorf("Expected Generate to succeed but failed")
 | 
						|
	}
 | 
						|
	actual, _ := sk.MarshalBinary()
 | 
						|
	if len(actual) != len(expected) {
 | 
						|
		t.Errorf("Length of Generate output is incorrect. Expected 32, found: %v\n", len(actual))
 | 
						|
	}
 | 
						|
	if !bytes.Equal(actual[:], expected) {
 | 
						|
		t.Errorf("SecretKey was not as expected")
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func marshalStruct(value encoding.BinaryMarshaler, t *testing.T) []byte {
 | 
						|
	out, err := value.MarshalBinary()
 | 
						|
	if err != nil {
 | 
						|
		t.Errorf("MarshalBinary failed: %v", err)
 | 
						|
	}
 | 
						|
	return out
 | 
						|
}
 | 
						|
 | 
						|
func TestSecretKeyZeroBytes(t *testing.T) {
 | 
						|
	seed := []byte{}
 | 
						|
	_, err := new(SecretKey).Generate(seed)
 | 
						|
	if err == nil {
 | 
						|
		t.Errorf("Expected Generate to fail but succeeded")
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestMarshalLeadingZeroes(t *testing.T) {
 | 
						|
	tests := []struct {
 | 
						|
		name string
 | 
						|
		in   []byte
 | 
						|
	}{
 | 
						|
		{"no leading zeroes", []byte{74, 53, 59, 227, 218, 192, 145, 160, 167, 230, 64, 98, 3, 114, 245, 225, 226, 228, 64, 23, 23, 193, 231, 156, 172, 111, 251, 168, 246, 144, 86, 4}},
 | 
						|
		{"one leading zero byte", []byte{00, 53, 59, 227, 218, 192, 145, 160, 167, 230, 64, 98, 3, 114, 245, 225, 226, 228, 64, 23, 23, 193, 231, 156, 172, 111, 251, 168, 246, 144, 86, 4}},
 | 
						|
		{"two leading zeroes", []byte{00, 00, 59, 227, 218, 192, 145, 160, 167, 230, 64, 98, 3, 114, 245, 225, 226, 228, 64, 23, 23, 193, 231, 156, 172, 111, 251, 168, 246, 144, 86, 4}},
 | 
						|
	}
 | 
						|
	// Run all the tests!
 | 
						|
	ss := bls12381.Bls12381FqNew()
 | 
						|
	for _, test := range tests {
 | 
						|
		// Marshal
 | 
						|
		var k big.Int
 | 
						|
		k.SetBytes(test.in)
 | 
						|
		ss.SetBigInt(&k)
 | 
						|
		bytes, err := SecretKey{ss}.MarshalBinary()
 | 
						|
		if err != nil {
 | 
						|
			t.Errorf("%v", err)
 | 
						|
			continue
 | 
						|
		}
 | 
						|
 | 
						|
		// Test that marshal produces a values of the exected len
 | 
						|
		t.Run(test.name, func(t *testing.T) {
 | 
						|
			if len(bytes) != SecretKeySize {
 | 
						|
				t.Errorf("expected len=%v got len=%v", SecretKeySize, len(bytes))
 | 
						|
			}
 | 
						|
		})
 | 
						|
 | 
						|
		// Test that we can also unmarhsal correctly
 | 
						|
		t.Run(test.name, func(t *testing.T) {
 | 
						|
			var actual SecretKey
 | 
						|
			err := actual.UnmarshalBinary(bytes)
 | 
						|
 | 
						|
			// Test for error
 | 
						|
			if err != nil {
 | 
						|
				t.Errorf("%v", err)
 | 
						|
				return
 | 
						|
			}
 | 
						|
 | 
						|
			// Test for correctness
 | 
						|
			if actual.value.Cmp(ss) != 0 {
 | 
						|
				t.Errorf("unmarshaled doens't match original value")
 | 
						|
			}
 | 
						|
		})
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestSecretKey32Bytes(t *testing.T) {
 | 
						|
	seed := make([]byte, 32)
 | 
						|
	expected := []byte{77, 18, 154, 25, 223, 134, 160, 245, 52, 91, 173, 76, 198, 242, 73, 236, 42, 129, 156, 204, 51, 134, 137, 91, 235, 79, 125, 152, 179, 219, 98, 53}
 | 
						|
	assertSecretKeyGen(seed, expected, t)
 | 
						|
}
 | 
						|
 | 
						|
func TestSecretKey128Bytes(t *testing.T) {
 | 
						|
	seed := make([]byte, 128)
 | 
						|
	expected := []byte{97, 207, 109, 96, 94, 90, 233, 215, 221, 207, 240, 139, 24, 209, 152, 170, 73, 209, 151, 241, 148, 176, 173, 92, 101, 48, 39, 175, 201, 219, 146, 168}
 | 
						|
	assertSecretKeyGen(seed, expected, t)
 | 
						|
}
 | 
						|
 | 
						|
func TestRandomSecretKey(t *testing.T) {
 | 
						|
	seed := make([]byte, 48)
 | 
						|
	_, _ = rand.Read(seed)
 | 
						|
	_, err := new(SecretKey).Generate(seed)
 | 
						|
	if err != nil {
 | 
						|
		t.Errorf("Expected Generate to succeed but failed")
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestSecretKeyToBytes(t *testing.T) {
 | 
						|
	sk := genSecretKey(t)
 | 
						|
	skBytes := marshalStruct(sk, t)
 | 
						|
	sk1 := new(SecretKey)
 | 
						|
	err := sk1.UnmarshalBinary(skBytes)
 | 
						|
	if err != nil {
 | 
						|
		t.Errorf("Expected UnmarshalBinary to pass but failed: %v", err)
 | 
						|
	}
 | 
						|
	out := sk1.value.Bytes()
 | 
						|
	for i, b := range internal.ReverseScalarBytes(out[:]) {
 | 
						|
		if skBytes[i] != b {
 | 
						|
			t.Errorf("Expected secret keys to be equal but are different at offset %d: %v != %v", i, skBytes[i], b)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	sk2 := new(SecretKey)
 | 
						|
	err = sk2.UnmarshalBinary(skBytes)
 | 
						|
	if err != nil {
 | 
						|
		t.Errorf("Expected FromBytes to succeed but failed.")
 | 
						|
	}
 | 
						|
	if !bytes.Equal(marshalStruct(sk2, t), skBytes) {
 | 
						|
		t.Errorf("Expected secret keys to be equal but are different")
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Verifies that the thresholdize creates the expected number
 | 
						|
// of shares
 | 
						|
func TestThresholdizeSecretKeyCountsCorrect(t *testing.T) {
 | 
						|
	sk := &SecretKey{value: bls12381.Bls12381FqNew().SetBigInt(big.NewInt(248631463258962596))}
 | 
						|
	tests := []struct {
 | 
						|
		key           *SecretKey
 | 
						|
		t, n          uint
 | 
						|
		expectedError bool
 | 
						|
	}{
 | 
						|
		// bad cases
 | 
						|
		{sk, 1, 1, true},     // n == 1
 | 
						|
		{sk, 1, 5, true},     // t == 1
 | 
						|
		{nil, 3, 5, true},    // sk nil
 | 
						|
		{sk, 101, 100, true}, // t> n
 | 
						|
		{sk, 0, 10, true},    // t == 0
 | 
						|
		{sk, 10, 256, true},  // n > 256
 | 
						|
 | 
						|
		// good cases
 | 
						|
		{sk, 10, 10, false},   // t == n
 | 
						|
		{sk, 2, 10, false},    // boundary case for t
 | 
						|
		{sk, 9, 10, false},    // boundary case for t
 | 
						|
		{sk, 10, 255, false},  // boundary case for n
 | 
						|
		{sk, 254, 255, false}, // boundary case for t,n
 | 
						|
		{sk, 100, 200, false}, // arbitrary t,n values
 | 
						|
		{sk, 10, 20, false},   // arbitrary t,n values
 | 
						|
		{sk, 15, 200, false},  // arbitrary t,n values
 | 
						|
		{sk, 254, 255, false}, // boundary case
 | 
						|
		{sk, 255, 255, false}, // boundary case
 | 
						|
	}
 | 
						|
 | 
						|
	// Run all the tests!
 | 
						|
	for i, test := range tests {
 | 
						|
		shares, err := thresholdizeSecretKey(test.key, test.t, test.n)
 | 
						|
 | 
						|
		// Check for errors
 | 
						|
		if test.expectedError && err == nil {
 | 
						|
			t.Errorf("%d - expected an error but received nil. t=%v, n=%v, sk=%v", i, test.t, test.n, sk)
 | 
						|
		}
 | 
						|
 | 
						|
		// Check for errors
 | 
						|
		if !test.expectedError && err != nil {
 | 
						|
			t.Errorf("%d - received unexpected error %v. t=%v, n=%v, sk=%v", i, err, test.t, test.n, sk)
 | 
						|
		}
 | 
						|
 | 
						|
		// Check the share count == n
 | 
						|
		if !test.expectedError && test.n != uint(len(shares)) {
 | 
						|
			t.Errorf("%d - expected len(shares) = %v != %v (n)", i, len(shares), test.n)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestSecretKeyShareUnmarshalBinary(t *testing.T) {
 | 
						|
	sk := genSecretKey(t)
 | 
						|
	sks, err := thresholdizeSecretKey(sk, 3, 5)
 | 
						|
	if err != nil {
 | 
						|
		t.Errorf("Expected thresholdizeSecretKey to pass but failed.")
 | 
						|
	}
 | 
						|
 | 
						|
	for i, sh := range sks {
 | 
						|
		b1, err := sh.MarshalBinary()
 | 
						|
		if err != nil {
 | 
						|
			t.Errorf("%d - expected MarshalBinary to pass but failed. sh=%v", i, sh)
 | 
						|
		}
 | 
						|
 | 
						|
		// UnmarshalBinary b1 to new SecretKeyShare
 | 
						|
		sh1 := new(SecretKeyShare)
 | 
						|
		err = sh1.UnmarshalBinary(b1)
 | 
						|
		if err != nil {
 | 
						|
			t.Errorf("%d - expected UnmarshalBinary to pass but failed. sh=%v", i, sh)
 | 
						|
		}
 | 
						|
 | 
						|
		// zero bytes slice with length equal to SecretKeySize
 | 
						|
		zeros := make([]byte, SecretKeySize)
 | 
						|
		b2, err := sh1.MarshalBinary()
 | 
						|
		if err != nil {
 | 
						|
			t.Errorf("%d - expected MarshalBinary to pass but failed. sh1=%v", i, sh1)
 | 
						|
		}
 | 
						|
 | 
						|
		// Check if []bytes from UnmarshalBinary != zeros && Initial bytes(b1) == Final bytes(b2)
 | 
						|
		if bytes.Equal(zeros, b2) && !bytes.Equal(b1, b2) {
 | 
						|
			t.Errorf("%d - expected UnmarshalBinary to give non zeros value but failed. sh1=%v, sh=%v", i, sh1, sh)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 |