github.com/cloudflare/circl@v1.5.0/sign/bls/bls_test.go (about)

     1  package bls_test
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/rand"
     6  	"crypto/rsa"
     7  	"encoding"
     8  	"fmt"
     9  	"testing"
    10  
    11  	"github.com/cloudflare/circl/internal/test"
    12  	"github.com/cloudflare/circl/sign/bls"
    13  )
    14  
    15  func TestBls(t *testing.T) {
    16  	t.Run("G1/API", testBls[bls.G1])
    17  	t.Run("G2/API", testBls[bls.G2])
    18  	t.Run("G1/Marshal", testMarshalKeys[bls.G1])
    19  	t.Run("G2/Marshal", testMarshalKeys[bls.G2])
    20  	t.Run("G1/Errors", testErrors[bls.G1])
    21  	t.Run("G2/Errors", testErrors[bls.G2])
    22  	t.Run("G1/Aggregation", testAggregation[bls.G1])
    23  	t.Run("G2/Aggregation", testAggregation[bls.G2])
    24  }
    25  
    26  func testBls[K bls.KeyGroup](t *testing.T) {
    27  	const testTimes = 1 << 7
    28  	msg := []byte("hello world")
    29  	keyInfo := []byte("KeyInfo for BLS")
    30  	salt := [32]byte{}
    31  	ikm := [32]byte{}
    32  	_, _ = rand.Reader.Read(ikm[:])
    33  	_, _ = rand.Reader.Read(salt[:])
    34  
    35  	for i := 0; i < testTimes; i++ {
    36  		_, _ = rand.Reader.Read(ikm[:])
    37  
    38  		priv, err := bls.KeyGen[K](ikm[:], salt[:], keyInfo)
    39  		test.CheckNoErr(t, err, "failed to keygen")
    40  		signature := bls.Sign(priv, msg)
    41  		pub := priv.Public().(*bls.PublicKey[K])
    42  		test.CheckOk(bls.Verify(pub, msg, signature), "failed verification", t)
    43  	}
    44  }
    45  
    46  func testMarshalKeys[K bls.KeyGroup](t *testing.T) {
    47  	ikm := [32]byte{}
    48  	priv, err := bls.KeyGen[K](ikm[:], nil, nil)
    49  	test.CheckNoErr(t, err, "failed to keygen")
    50  	pub := priv.PublicKey()
    51  
    52  	auxPriv := new(bls.PrivateKey[K])
    53  	auxPub := new(bls.PublicKey[K])
    54  
    55  	t.Run("PrivateKey", func(t *testing.T) {
    56  		testMarshal[K](t, priv, auxPriv)
    57  		test.CheckOk(priv.Equal(auxPriv), "private keys do not match", t)
    58  	})
    59  	t.Run("PublicKey", func(t *testing.T) {
    60  		testMarshal[K](t, pub, auxPub)
    61  		test.CheckOk(pub.Equal(auxPub), "public keys do not match", t)
    62  	})
    63  }
    64  
    65  func testMarshal[K bls.KeyGroup](
    66  	t *testing.T,
    67  	left, right interface {
    68  		encoding.BinaryMarshaler
    69  		encoding.BinaryUnmarshaler
    70  	},
    71  ) {
    72  	want, err := left.MarshalBinary()
    73  	test.CheckNoErr(t, err, "failed to marshal")
    74  
    75  	err = right.UnmarshalBinary(want)
    76  	test.CheckNoErr(t, err, "failed to unmarshal")
    77  
    78  	got, err := right.MarshalBinary()
    79  	test.CheckNoErr(t, err, "failed to marshal")
    80  
    81  	if !bytes.Equal(got, want) {
    82  		test.ReportError(t, got, want)
    83  	}
    84  
    85  	err = right.UnmarshalBinary(nil)
    86  	test.CheckIsErr(t, err, "should fail: empty input")
    87  }
    88  
    89  func testErrors[K bls.KeyGroup](t *testing.T) {
    90  	// Short IKM
    91  	_, err := bls.KeyGen[K](nil, nil, nil)
    92  	test.CheckIsErr(t, err, "should fail: short ikm")
    93  
    94  	// Bad Signature size
    95  	ikm := [32]byte{}
    96  	priv, err := bls.KeyGen[K](ikm[:], nil, nil)
    97  	test.CheckNoErr(t, err, "failed to keygen")
    98  	pub := priv.PublicKey()
    99  	test.CheckOk(bls.Verify(pub, nil, nil) == false, "should fail: bad signature", t)
   100  
   101  	// Bad public key
   102  	msg := []byte("hello")
   103  	sig := bls.Sign[K](priv, msg)
   104  	pub = new(bls.PublicKey[K])
   105  	test.CheckOk(pub.Validate() == false, "should fail: bad public key", t)
   106  	test.CheckOk(bls.Verify(pub, msg, sig) == false, "should fail: bad signature", t)
   107  
   108  	// Bad private key
   109  	priv = new(bls.PrivateKey[K])
   110  	test.CheckOk(priv.Validate() == false, "should fail: bad private key", t)
   111  	err = test.CheckPanic(func() { bls.Sign(priv, msg) })
   112  	test.CheckNoErr(t, err, "sign should panic")
   113  
   114  	// Wrong comparisons
   115  	test.CheckOk(priv.Equal(new(rsa.PrivateKey)) == false, "should fail: bad private key types", t)
   116  	test.CheckOk(pub.Equal(new(rsa.PublicKey)) == false, "should fail: bad public key types", t)
   117  
   118  	// Aggregate nil
   119  	_, err = bls.Aggregate[K](*new(K), nil)
   120  	test.CheckIsErr(t, err, "should fail: empty signatures")
   121  
   122  	// VerifyAggregate nil
   123  	test.CheckOk(bls.VerifyAggregate([]*bls.PublicKey[K]{}, nil, nil) == false, "should fail: empty keys", t)
   124  
   125  	// VerifyAggregate empty signature
   126  	test.CheckOk(bls.VerifyAggregate([]*bls.PublicKey[K]{pub}, [][]byte{msg}, nil) == false, "should fail: empty signature", t)
   127  }
   128  
   129  func testAggregation[K bls.KeyGroup](t *testing.T) {
   130  	const N = 3
   131  
   132  	ikm := [32]byte{}
   133  	_, _ = rand.Reader.Read(ikm[:])
   134  
   135  	msgs := make([][]byte, N)
   136  	sigs := make([]bls.Signature, N)
   137  	pubKeys := make([]*bls.PublicKey[K], N)
   138  
   139  	for i := range sigs {
   140  		priv, err := bls.KeyGen[K](ikm[:], nil, nil)
   141  		test.CheckNoErr(t, err, "failed to keygen")
   142  		pubKeys[i] = priv.PublicKey()
   143  
   144  		msgs[i] = []byte(fmt.Sprintf("Message number: %v", i))
   145  		sigs[i] = bls.Sign(priv, msgs[i])
   146  	}
   147  
   148  	aggSig, err := bls.Aggregate(*new(K), sigs)
   149  	test.CheckNoErr(t, err, "failed to aggregate")
   150  
   151  	ok := bls.VerifyAggregate(pubKeys, msgs, aggSig)
   152  	test.CheckOk(ok, "failed to verify aggregated signature", t)
   153  }
   154  
   155  func BenchmarkBls(b *testing.B) {
   156  	b.Run("G1", benchmarkBls[bls.G1])
   157  	b.Run("G2", benchmarkBls[bls.G2])
   158  }
   159  
   160  func benchmarkBls[K bls.KeyGroup](b *testing.B) {
   161  	msg := []byte("hello world")
   162  	keyInfo := []byte("KeyInfo for BLS")
   163  	salt := [32]byte{}
   164  	ikm := [32]byte{}
   165  	_, _ = rand.Reader.Read(ikm[:])
   166  	_, _ = rand.Reader.Read(salt[:])
   167  
   168  	priv, _ := bls.KeyGen[K](ikm[:], salt[:], keyInfo)
   169  
   170  	const N = 3
   171  	msgs := make([][]byte, N)
   172  	sigs := make([]bls.Signature, N)
   173  	pubKeys := make([]*bls.PublicKey[K], N)
   174  
   175  	for i := range sigs {
   176  		pubKeys[i] = priv.PublicKey()
   177  
   178  		msgs[i] = []byte(fmt.Sprintf("Message number: %v", i))
   179  		sigs[i] = bls.Sign(priv, msgs[i])
   180  	}
   181  
   182  	b.Run("Keygen", func(b *testing.B) {
   183  		for i := 0; i < b.N; i++ {
   184  			_, _ = rand.Reader.Read(ikm[:])
   185  			_, _ = bls.KeyGen[K](ikm[:], salt[:], keyInfo)
   186  		}
   187  	})
   188  
   189  	b.Run("Sign", func(b *testing.B) {
   190  		for i := 0; i < b.N; i++ {
   191  			_ = bls.Sign(priv, msg)
   192  		}
   193  	})
   194  
   195  	b.Run("Verify", func(b *testing.B) {
   196  		pub := priv.PublicKey()
   197  		signature := bls.Sign(priv, msg)
   198  
   199  		b.ResetTimer()
   200  		for i := 0; i < b.N; i++ {
   201  			bls.Verify(pub, msg, signature)
   202  		}
   203  	})
   204  
   205  	b.Run("Aggregate3", func(b *testing.B) {
   206  		for i := 0; i < b.N; i++ {
   207  			_, _ = bls.Aggregate(*new(K), sigs)
   208  		}
   209  	})
   210  
   211  	b.Run("VerifyAggregate3", func(b *testing.B) {
   212  		aggSig, _ := bls.Aggregate(*new(K), sigs)
   213  
   214  		b.ResetTimer()
   215  		for i := 0; i < b.N; i++ {
   216  			_ = bls.VerifyAggregate(pubKeys, msgs, aggSig)
   217  		}
   218  	})
   219  }