github.com/dusk-network/dusk-crypto@v0.1.3/bls/bls_test.go (about)

     1  package bls
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/rand"
     6  	"fmt"
     7  	"io"
     8  	"math/big"
     9  	"reflect"
    10  	"testing"
    11  
    12  	"github.com/dusk-network/bn256"
    13  	"github.com/stretchr/testify/assert"
    14  	"github.com/stretchr/testify/require"
    15  )
    16  
    17  func randomMessage() []byte {
    18  	msg := make([]byte, 32)
    19  	_, _ = rand.Read(msg)
    20  	return msg
    21  }
    22  
    23  func TestCopyApk(t *testing.T) {
    24  	require := require.New(t)
    25  	pub, _, err := GenKeyPair(rand.Reader)
    26  	require.NoError(err)
    27  	apk := NewApk(pub)
    28  
    29  	cpy := apk.Copy()
    30  	require.True(reflect.DeepEqual(apk, cpy))
    31  }
    32  
    33  func TestCopySig(t *testing.T) {
    34  	require := require.New(t)
    35  	pub, priv, err := GenKeyPair(rand.Reader)
    36  	require.NoError(err)
    37  
    38  	sigma, err := Sign(priv, pub, []byte("ciao!!"))
    39  	require.NoError(err)
    40  
    41  	cpy := sigma.Copy()
    42  	require.True(reflect.DeepEqual(sigma, cpy))
    43  }
    44  
    45  // TestSignVerify
    46  func TestSignVerify(t *testing.T) {
    47  	msg := randomMessage()
    48  	pub, priv, err := GenKeyPair(rand.Reader)
    49  	require.NoError(t, err)
    50  
    51  	sig, err := UnsafeSign(priv, msg)
    52  	require.NoError(t, err)
    53  	require.NoError(t, VerifyUnsafe(pub, msg, sig))
    54  
    55  	// Testing that changing the message, the signature is no longer valid
    56  	require.NotNil(t, VerifyUnsafe(pub, randomMessage(), sig))
    57  
    58  	// Testing that using a random PK, the signature cannot be verified
    59  	pub2, _, err := GenKeyPair(rand.Reader)
    60  	require.NoError(t, err)
    61  	require.NotNil(t, VerifyUnsafe(pub2, msg, sig))
    62  }
    63  
    64  // TestCombine checks for the Batched form of the BLS signature
    65  func TestCombine(t *testing.T) {
    66  	reader := rand.Reader
    67  	msg1 := []byte("Get Funky Tonight")
    68  	msg2 := []byte("Gonna Get Funky Tonight")
    69  
    70  	pub1, priv1, err := GenKeyPair(reader)
    71  	require.NoError(t, err)
    72  
    73  	pub2, priv2, err := GenKeyPair(reader)
    74  	require.NoError(t, err)
    75  
    76  	str1, err := pub1.MarshalText()
    77  	require.NoError(t, err)
    78  
    79  	str2, err := pub2.MarshalText()
    80  	require.NoError(t, err)
    81  
    82  	require.NotEqual(t, str1, str2)
    83  
    84  	sig1, err := UnsafeSign(priv1, msg1)
    85  	require.NoError(t, err)
    86  	require.NoError(t, VerifyUnsafe(pub1, msg1, sig1))
    87  
    88  	sig2, err := UnsafeSign(priv2, msg2)
    89  	require.NoError(t, err)
    90  	require.NoError(t, VerifyUnsafe(pub2, msg2, sig2))
    91  
    92  	sig3 := UnsafeAggregate(sig1, sig2)
    93  	pkeys := []*PublicKey{pub1, pub2}
    94  	require.NoError(t, VerifyUnsafeBatch(pkeys, [][]byte{msg1, msg2}, sig3))
    95  }
    96  
    97  func TestHashToPoint(t *testing.T) {
    98  	msg := []byte("test data")
    99  	g1, err := h0(msg)
   100  	assert.Equal(t, nil, err)
   101  	assert.NotEqual(t, nil, g1)
   102  }
   103  
   104  func randomInt(r io.Reader) *big.Int {
   105  	for {
   106  		k, _ := rand.Int(r, bn256.Order)
   107  		if k.Sign() > 0 {
   108  			return k
   109  		}
   110  	}
   111  }
   112  func TestRogueKey(t *testing.T) {
   113  	reader := rand.Reader
   114  	pub, _, err := GenKeyPair(reader)
   115  	require.NoError(t, err)
   116  	// α is the pseudo-secret key of the attacker
   117  	alpha := randomInt(reader)
   118  	// g₂ᵅ
   119  	g2Alpha := newG2().ScalarBaseMult(alpha)
   120  
   121  	// pk⁻¹
   122  	rogueGx := newG2()
   123  	rogueGx.Neg(pub.gx)
   124  
   125  	pRogue := newG2()
   126  	pRogue.Add(g2Alpha, rogueGx)
   127  
   128  	sk, pk := &SecretKey{alpha}, &PublicKey{pRogue}
   129  
   130  	msg := []byte("test data")
   131  	rogueSignature, err := UnsafeSign(sk, msg)
   132  	require.NoError(t, err)
   133  
   134  	require.NoError(t, verifyBatch([]*bn256.G2{pub.gx, pk.gx}, [][]byte{msg, msg}, rogueSignature.e, true))
   135  }
   136  
   137  func TestMarshalPk(t *testing.T) {
   138  	reader := rand.Reader
   139  	pub, _, err := GenKeyPair(reader)
   140  	require.NoError(t, err)
   141  
   142  	pkByteRepr := pub.Marshal()
   143  
   144  	g2 := newG2()
   145  	_, _ = g2.Unmarshal(pkByteRepr)
   146  
   147  	g2ByteRepr := g2.Marshal()
   148  	require.Equal(t, pkByteRepr, g2ByteRepr)
   149  
   150  	pkInt := new(big.Int).SetBytes(pkByteRepr)
   151  	g2Int := new(big.Int).SetBytes(g2ByteRepr)
   152  	require.Equal(t, pkInt, g2Int)
   153  
   154  	pk, err := UnmarshalPk(pkByteRepr)
   155  	require.NoError(t, err)
   156  	require.Equal(t, pub, pk)
   157  }
   158  
   159  func TestApkVerificationSingleKey(t *testing.T) {
   160  	reader := rand.Reader
   161  	msg := []byte("Get Funky Tonight")
   162  
   163  	pub1, priv1, err := GenKeyPair(reader)
   164  	require.NoError(t, err)
   165  
   166  	apk := NewApk(pub1)
   167  
   168  	signature, err := Sign(priv1, pub1, msg)
   169  	require.NoError(t, err)
   170  	require.NoError(t, Verify(apk, msg, signature))
   171  
   172  	// testing unmarshalling
   173  	bApk := apk.Marshal()
   174  	uApk, err := UnmarshalApk(bApk)
   175  	assert.NoError(t, err)
   176  	require.NoError(t, Verify(uApk, msg, signature))
   177  }
   178  
   179  func TestApkVerification(t *testing.T) {
   180  	reader := rand.Reader
   181  	msg := []byte("Get Funky Tonight")
   182  
   183  	pub1, priv1, err := GenKeyPair(reader)
   184  	require.NoError(t, err)
   185  
   186  	pub2, priv2, err := GenKeyPair(reader)
   187  	require.NoError(t, err)
   188  
   189  	apk := NewApk(pub1)
   190  	assert.NoError(t, apk.Aggregate(pub2))
   191  
   192  	signature, err := Sign(priv1, pub1, msg)
   193  	require.NoError(t, err)
   194  	sig2, err := Sign(priv2, pub2, msg)
   195  	require.NoError(t, err)
   196  
   197  	signature.Aggregate(sig2)
   198  	require.NoError(t, Verify(apk, msg, signature))
   199  }
   200  
   201  func TestApkBatchVerification(t *testing.T) {
   202  	reader := rand.Reader
   203  	msg := []byte("Get Funky Tonight")
   204  
   205  	pub1, priv1, err := GenKeyPair(reader)
   206  	require.NoError(t, err)
   207  
   208  	pub2, priv2, err := GenKeyPair(reader)
   209  	require.NoError(t, err)
   210  
   211  	apk := NewApk(pub1)
   212  	assert.NoError(t, apk.Aggregate(pub2))
   213  
   214  	sigma, err := Sign(priv1, pub1, msg)
   215  	require.NoError(t, err)
   216  	sig2_1, err := Sign(priv2, pub2, msg)
   217  	require.NoError(t, err)
   218  	sig := sigma.Aggregate(sig2_1)
   219  	require.NoError(t, Verify(apk, msg, sig))
   220  
   221  	msg2 := []byte("Gonna get Shwifty tonight")
   222  	pub3, priv3, err := GenKeyPair(reader)
   223  	require.NoError(t, err)
   224  	apk2 := NewApk(pub2)
   225  	require.NoError(t, apk2.Aggregate(pub3))
   226  	sig2_2, err := Sign(priv2, pub2, msg2)
   227  	require.NoError(t, err)
   228  	sig3_2, err := Sign(priv3, pub3, msg2)
   229  	require.NoError(t, err)
   230  	sig2 := sig2_2.Aggregate(sig3_2)
   231  	require.NoError(t, Verify(apk2, msg2, sig2))
   232  
   233  	sigma.Aggregate(sig2)
   234  	require.NoError(t, VerifyBatch(
   235  		[]*Apk{apk, apk2},
   236  		[][]byte{msg, msg2},
   237  		sigma,
   238  	))
   239  }
   240  
   241  func TestSafeCompress(t *testing.T) {
   242  	msg := randomMessage()
   243  	pub, priv, err := GenKeyPair(rand.Reader)
   244  	require.NoError(t, err)
   245  
   246  	sig, err := Sign(priv, pub, msg)
   247  	require.NoError(t, err)
   248  	require.NoError(t, Verify(NewApk(pub), msg, sig))
   249  
   250  	sigb := sig.Compress()
   251  	sigTest := &Signature{e: newG1()}
   252  	require.NoError(t, sigTest.Decompress(sigb))
   253  
   254  	require.Equal(t, sig.Marshal(), sigTest.Marshal())
   255  }
   256  
   257  func TestUnsafeCompress(t *testing.T) {
   258  	msg := randomMessage()
   259  	pub, priv, err := GenKeyPair(rand.Reader)
   260  	require.NoError(t, err)
   261  
   262  	sig, err := UnsafeSign(priv, msg)
   263  	require.NoError(t, err)
   264  	require.NoError(t, VerifyUnsafe(pub, msg, sig))
   265  
   266  	sigb := sig.Compress()
   267  	sigTest := &UnsafeSignature{e: newG1()}
   268  	require.NoError(t, sigTest.Decompress(sigb))
   269  
   270  	sigM := sig.e.Marshal()
   271  	require.NotEmpty(t, sigM)
   272  	require.Equal(t, sigM, sigTest.e.Marshal())
   273  }
   274  
   275  func TestAmbiguousCompress(t *testing.T) {
   276  	msg := randomMessage()
   277  	pub, priv, err := GenKeyPair(rand.Reader)
   278  	require.NoError(t, err)
   279  
   280  	sig, err := UnsafeSign(priv, msg)
   281  	require.NoError(t, err)
   282  	require.NoError(t, VerifyUnsafe(pub, msg, sig))
   283  
   284  	sigb := sig.Compress()
   285  	require.Equal(t, len(sigb), 33)
   286  
   287  	xy1, xy2, err := bn256.DecompressAmbiguous(sigb)
   288  	require.NoError(t, err)
   289  
   290  	if xy1 == nil && xy2 == nil {
   291  		fmt.Printf("Original signature: %v\n", new(big.Int).SetBytes(sig.Marshal()).String())
   292  		fmt.Printf("Compressed signature: %v\n", new(big.Int).SetBytes(sigb).String())
   293  		require.Fail(t, "Orcoddue")
   294  	}
   295  
   296  	sigM := sig.e.Marshal()
   297  	require.NotEmpty(t, sigM)
   298  
   299  	if xy1 != nil {
   300  		sig1 := &UnsafeSignature{xy1}
   301  		if bytes.Equal(sigM, sig1.e.Marshal()) {
   302  			return
   303  		}
   304  	}
   305  	if xy2 != nil {
   306  		sig2 := &UnsafeSignature{xy2}
   307  		if bytes.Equal(sigM, sig2.e.Marshal()) {
   308  			return
   309  		}
   310  	}
   311  
   312  	require.Fail(t, "Decompression failed both xy1 and xy2 are nil")
   313  }
   314  
   315  func BenchmarkSign(b *testing.B) {
   316  	msg := randomMessage()
   317  	pk, sk, _ := GenKeyPair(rand.Reader)
   318  
   319  	b.ReportAllocs()
   320  	b.StopTimer()
   321  	b.ResetTimer()
   322  
   323  	for i := 0; i < b.N; i++ {
   324  		b.StartTimer()
   325  		_, _ = Sign(sk, pk, msg)
   326  		b.StopTimer()
   327  	}
   328  }
   329  
   330  func aggregateXSignatures(b *testing.B, nr int) {
   331  	var sigmas = make([]*Signature, nr)
   332  	reader := rand.Reader
   333  	msg := []byte("Get Funky Tonight")
   334  
   335  	for i := 0; i < nr; i++ {
   336  		pk, sk, _ := GenKeyPair(reader)
   337  		sigmas[i], _ = Sign(sk, pk, msg)
   338  	}
   339  
   340  	s, sigmas := sigmas[0], sigmas[1:]
   341  
   342  	b.ReportAllocs()
   343  	b.ResetTimer()
   344  	for i := 0; i < b.N; i++ {
   345  		for _, sig := range sigmas {
   346  			s = s.Aggregate(sig)
   347  		}
   348  	}
   349  }
   350  
   351  func BenchmarkAggregate10Signatures(b *testing.B) {
   352  	aggregateXSignatures(b, 10)
   353  }
   354  
   355  func BenchmarkAggregate100Signatures(b *testing.B) {
   356  	aggregateXSignatures(b, 100)
   357  }
   358  
   359  func BenchmarkAggregate1000Signatures(b *testing.B) {
   360  	aggregateXSignatures(b, 1000)
   361  }
   362  
   363  func BenchmarkVerifySingleSignature(b *testing.B) {
   364  	msg := randomMessage()
   365  	pk, sk, _ := GenKeyPair(rand.Reader)
   366  	b.StopTimer()
   367  	b.ResetTimer()
   368  	b.ReportAllocs()
   369  
   370  	for i := 0; i < b.N; i++ {
   371  		signature, _ := Sign(sk, pk, msg)
   372  
   373  		b.StartTimer()
   374  		_ = Verify(NewApk(pk), msg, signature)
   375  		b.StopTimer()
   376  	}
   377  }
   378  
   379  func BenchmarkVerifyUnsafeSingleSignature(b *testing.B) {
   380  	msg := randomMessage()
   381  	b.StopTimer()
   382  	b.ResetTimer()
   383  
   384  	for i := 0; i < b.N; i++ {
   385  		pk, sk, _ := GenKeyPair(rand.Reader)
   386  		signature, _ := UnsafeSign(sk, msg)
   387  
   388  		b.StartTimer()
   389  		_ = VerifyUnsafe(pk, msg, signature)
   390  		b.StopTimer()
   391  	}
   392  }
   393  
   394  func BenchmarkVerifySingleCompressedSignature(b *testing.B) {
   395  	msg := randomMessage()
   396  	b.StopTimer()
   397  	b.ResetTimer()
   398  
   399  	for i := 0; i < b.N; i++ {
   400  		pk, sk, _ := GenKeyPair(rand.Reader)
   401  		signature, _ := Sign(sk, pk, msg)
   402  		sigb := signature.Compress()
   403  		apk := NewApk(pk)
   404  
   405  		b.StartTimer()
   406  		signature = &Signature{}
   407  		_ = signature.Decompress(sigb)
   408  		_ = Verify(apk, msg, signature)
   409  		b.StopTimer()
   410  	}
   411  }
   412  
   413  func BenchmarkVerifySingleCompressedUnsafeSignature(b *testing.B) {
   414  	msg := randomMessage()
   415  	b.StopTimer()
   416  	b.ResetTimer()
   417  
   418  	for i := 0; i < b.N; i++ {
   419  		pk, sk, _ := GenKeyPair(rand.Reader)
   420  		signature, _ := UnsafeSign(sk, msg)
   421  		sigb := signature.Compress()
   422  
   423  		b.StartTimer()
   424  		signature = &UnsafeSignature{}
   425  		_ = signature.Decompress(sigb)
   426  		_ = VerifyUnsafe(pk, msg, signature)
   427  		b.StopTimer()
   428  	}
   429  }