mirror of
https://github.com/sonr-io/crypto.git
synced 2026-08-02 15:31:38 +00:00
482 lines
8.6 KiB
Go
482 lines
8.6 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"
|
|
|
|
"github.com/sonr-io/sonr/crypto/core/curves/native/bls12381"
|
|
"github.com/sonr-io/sonr/crypto/internal"
|
|
)
|
|
|
|
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{
|
|
0o0,
|
|
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{
|
|
0o0,
|
|
0o0,
|
|
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,
|
|
)
|
|
}
|
|
}
|
|
}
|