From 088bf8ad54cdad5c2421ad3caf981bbd59ca6f29 Mon Sep 17 00:00:00 2001 From: RXRD Date: Wed, 5 Jul 2023 21:03:05 +0700 Subject: [PATCH 1/3] refactor:public key aggregate --- consensus/consensus_test.go | 2 +- consensus/voteset/voteset.go | 2 +- crypto/bls/bls.go | 16 ++++++---- crypto/bls/bls_test.go | 58 +++++++++++++++++++++++++++++------- state/state_test.go | 4 +-- state/validation_test.go | 2 +- util/testsuite/testsuite.go | 2 +- 7 files changed, 64 insertions(+), 22 deletions(-) diff --git a/consensus/consensus_test.go b/consensus/consensus_test.go index 4c579e332..e76ed65bd 100644 --- a/consensus/consensus_test.go +++ b/consensus/consensus_test.go @@ -290,7 +290,7 @@ func (td *testData) commitBlockForAllStates(t *testing.T) (*block.Block, *block. sig2 := td.signers[1].SignData(sb).(*bls.Signature) sig4 := td.signers[3].SignData(sb).(*bls.Signature) - sig := bls.Aggregate([]*bls.Signature{sig1, sig2, sig4}) + sig := bls.SignatureAggregate([]*bls.Signature{sig1, sig2, sig4}) cert := block.NewCertificate(0, []int32{0, 1, 2, 3}, []int32{2}, sig) block := p.Block() diff --git a/consensus/voteset/voteset.go b/consensus/voteset/voteset.go index 860463aa1..c0006ca49 100644 --- a/consensus/voteset/voteset.go +++ b/consensus/voteset/voteset.go @@ -166,7 +166,7 @@ func (vs *VoteSet) ToCertificate() *block.Certificate { committers[i] = val.Number() } - sig := bls.Aggregate(sigs) + sig := bls.SignatureAggregate(sigs) return block.NewCertificate(vs.Round(), committers, absentees, sig) } diff --git a/crypto/bls/bls.go b/crypto/bls/bls.go index 940db5b4e..3d606858f 100644 --- a/crypto/bls/bls.go +++ b/crypto/bls/bls.go @@ -8,7 +8,7 @@ import ( // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-4.2.1 var dst = []byte("BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_") -func Aggregate(sigs []*Signature) *Signature { +func SignatureAggregate(sigs []*Signature) *Signature { if len(sigs) == 0 { return nil } @@ -26,22 +26,28 @@ func Aggregate(sigs []*Signature) *Signature { } } -func VerifyAggregated(sig *Signature, pubs []*PublicKey, msg []byte) bool { +func PublicKeyAggregate(pubs []*PublicKey) *PublicKey { if len(pubs) == 0 { - return false + return nil } g2 := bls12381.NewG2() aggPointG2 := pubs[0].pointG2 for i := 1; i < len(pubs); i++ { if g2.IsZero(&pubs[i].pointG2) { - return false + return nil } g2.Add( &aggPointG2, &aggPointG2, &pubs[i].pointG2) } + return &PublicKey{ + pointG2: aggPointG2, + } +} + +func VerifyAggregated(sig *Signature, pubs []*PublicKey, msg []byte) bool { - aggPub := PublicKey{pointG2: aggPointG2} + aggPub := PublicKeyAggregate(pubs) return aggPub.Verify(msg, sig) == nil } diff --git a/crypto/bls/bls_test.go b/crypto/bls/bls_test.go index 26d73e9bb..940886a94 100644 --- a/crypto/bls/bls_test.go +++ b/crypto/bls/bls_test.go @@ -39,7 +39,7 @@ func TestSignatureAggregate(t *testing.T) { sig1 := prv1.Sign(msg).(*bls.Signature) sig2 := prv2.Sign(msg).(*bls.Signature) - assert.True(t, bls.Aggregate([]*bls.Signature{sig1, sig2}).EqualsTo(agg)) + assert.True(t, bls.SignatureAggregate([]*bls.Signature{sig1, sig2}).EqualsTo(agg)) assert.False(t, prv1.EqualsTo(prv2)) } @@ -59,17 +59,22 @@ func TestAggregateFailed(t *testing.T) { sig3 := prv3.Sign(msg1).(*bls.Signature) sig4 := prv4.Sign(msg1).(*bls.Signature) - agg1 := bls.Aggregate([]*bls.Signature{sig1, sig2, sig3}) - agg2 := bls.Aggregate([]*bls.Signature{sig1, sig2, sig4}) - agg3 := bls.Aggregate([]*bls.Signature{sig11, sig2, sig3}) - agg4 := bls.Aggregate([]*bls.Signature{sig1, sig2}) - agg5 := bls.Aggregate([]*bls.Signature{sig3, sig2, sig1}) + agg1 := bls.SignatureAggregate([]*bls.Signature{sig1, sig2, sig3}) + agg2 := bls.SignatureAggregate([]*bls.Signature{sig1, sig2, sig4}) + agg3 := bls.SignatureAggregate([]*bls.Signature{sig11, sig2, sig3}) + agg4 := bls.SignatureAggregate([]*bls.Signature{sig1, sig2}) + agg5 := bls.SignatureAggregate([]*bls.Signature{sig3, sig2, sig1}) pubs1 := []*bls.PublicKey{pub1, pub2, pub3} pubs2 := []*bls.PublicKey{pub1, pub2, pub4} pubs3 := []*bls.PublicKey{pub1, pub2} pubs4 := []*bls.PublicKey{pub3, pub2, pub1} + pubAgg1 := bls.PublicKeyAggregate(pubs1) + pubAgg2 := bls.PublicKeyAggregate(pubs2) + pubAgg3 := bls.PublicKeyAggregate(pubs3) + pubAgg4 := bls.PublicKeyAggregate(pubs4) + assert.NoError(t, pub1.Verify(msg1, sig1)) assert.NoError(t, pub2.Verify(msg1, sig2)) assert.NoError(t, pub3.Verify(msg1, sig3)) @@ -91,10 +96,25 @@ func TestAggregateFailed(t *testing.T) { assert.False(t, bls.VerifyAggregated(agg1, pubs3, msg1)) assert.True(t, bls.VerifyAggregated(agg5, pubs1, msg1)) assert.True(t, bls.VerifyAggregated(agg1, pubs4, msg1)) + + assert.NotNil(t, pubAgg1.Verify(msg1,agg1)) + assert.Nil(t, pubAgg1.Verify(msg2,agg1)) + assert.Nil(t, pubAgg1.Verify(msg1,agg2)) + assert.Nil(t, pubAgg2.Verify(msg1,agg1)) + assert.NotNil(t, pubAgg2.Verify(msg1,agg2)) + assert.Nil(t, pubAgg2.Verify(msg2,agg2)) + assert.Nil(t, pubAgg1.Verify(msg1,agg3)) + assert.Nil(t, pubAgg1.Verify(msg2,agg3)) + assert.Nil(t, pubAgg1.Verify(msg1,agg4)) + assert.Nil(t, pubAgg3.Verify(msg1,agg1)) + assert.NotNil(t, pubAgg1.Verify(msg1,agg5)) + assert.NotNil(t, pubAgg4.Verify(msg1,agg1)) } + func TestAggregateNil(t *testing.T) { - assert.Nil(t, bls.Aggregate(nil)) + assert.Nil(t, bls.SignatureAggregate(nil)) + assert.Nil(t, bls.PublicKeyAggregate(nil)) } func TestAggregateOnlyOneSignature(t *testing.T) { @@ -103,11 +123,20 @@ func TestAggregateOnlyOneSignature(t *testing.T) { _, prv1 := ts.RandomBLSKeyPair() msg1 := []byte("zarb") sig1 := prv1.Sign(msg1).(*bls.Signature) - agg1 := bls.Aggregate([]*bls.Signature{sig1}) + agg1 := bls.SignatureAggregate([]*bls.Signature{sig1}) assert.True(t, agg1.EqualsTo(sig1)) } +func TestAggregateOnlyOnePublicKey(t *testing.T) { + ts := testsuite.NewTestSuite(t) + + pub1, _ := ts.RandomBLSKeyPair() + agg1 := bls.PublicKeyAggregate([]*bls.PublicKey{pub1}) + + assert.True(t, agg1.EqualsTo(pub1)) +} + // TODO: should we check for duplication here? func TestDuplicatedAggregate(t *testing.T) { ts := testsuite.NewTestSuite(t) @@ -120,15 +149,22 @@ func TestDuplicatedAggregate(t *testing.T) { sig1 := prv1.Sign(msg1).(*bls.Signature) sig2 := prv2.Sign(msg1).(*bls.Signature) - agg1 := bls.Aggregate([]*bls.Signature{sig1, sig2, sig1}) - agg2 := bls.Aggregate([]*bls.Signature{sig1, sig2}) + agg1 := bls.SignatureAggregate([]*bls.Signature{sig1, sig2, sig1}) + agg2 := bls.SignatureAggregate([]*bls.Signature{sig1, sig2}) assert.False(t, agg1.EqualsTo(agg2)) pubs1 := []*bls.PublicKey{pub1, pub2} + pubs2 := []*bls.PublicKey{pub1, pub2, pub1} + pubAgg1 := bls.PublicKeyAggregate(pubs1) + pubAgg2 := bls.PublicKeyAggregate(pubs2) + assert.False(t, pubAgg1.EqualsTo(pubAgg2)) + assert.False(t, bls.VerifyAggregated(agg1, pubs1, msg1)) + assert.Nil(t, pubAgg1.Verify(msg1,agg1)) - pubs2 := []*bls.PublicKey{pub1, pub2, pub1} + assert.True(t, bls.VerifyAggregated(agg1, pubs2, msg1)) + assert.NotNil(t, pubAgg2.Verify(msg1,agg1)) } // TestHashToCurve ensures that the hash-to-curve function in kilic/bls12-381 diff --git a/state/state_test.go b/state/state_test.go index 07b4bd2bc..e3d5db6c7 100644 --- a/state/state_test.go +++ b/state/state_test.go @@ -151,7 +151,7 @@ func (td *testData) makeCertificateAndSign(t *testing.T, blockHash hash.Hash, ro } absentees := util.Subtracts(committers, signedBy) - return block.NewCertificate(round, committers, absentees, bls.Aggregate(sigs)) + return block.NewCertificate(round, committers, absentees, bls.SignatureAggregate(sigs)) } func (td *testData) commitBlockForAllStates(t *testing.T, b *block.Block, c *block.Certificate) { @@ -449,7 +449,7 @@ func TestSortition(t *testing.T) { sigs[1] = td.valSigner3.SignData(sb).(*bls.Signature) sigs[2] = td.valSigner4.SignData(sb).(*bls.Signature) sigs[3] = signer.SignData(sb).(*bls.Signature) - c14 := block.NewCertificate(3, []int32{4, 0, 1, 2, 3}, []int32{0}, bls.Aggregate(sigs)) + c14 := block.NewCertificate(3, []int32{4, 0, 1, 2, 3}, []int32{0}, bls.SignatureAggregate(sigs)) height++ assert.NoError(t, st1.CommitBlock(height, b14, c14)) diff --git a/state/validation_test.go b/state/validation_test.go index 68f317eb8..f2e28cf4f 100644 --- a/state/validation_test.go +++ b/state/validation_test.go @@ -16,7 +16,7 @@ func aggregate(sigs []crypto.Signature) *bls.Signature { for i, s := range sigs { blsSigs[i] = s.(*bls.Signature) } - return bls.Aggregate(blsSigs) + return bls.SignatureAggregate(blsSigs) } func TestCertificateValidation(t *testing.T) { diff --git a/util/testsuite/testsuite.go b/util/testsuite/testsuite.go index 4516091ce..d65ff52e0 100644 --- a/util/testsuite/testsuite.go +++ b/util/testsuite/testsuite.go @@ -287,7 +287,7 @@ func (ts *TestSuite) GenerateTestCertificate(blockHash hash.Hash) *block.Certifi priv3.Sign(blockHash.Bytes()).(*bls.Signature), priv4.Sign(blockHash.Bytes()).(*bls.Signature), } - sig := bls.Aggregate(sigs) + sig := bls.SignatureAggregate(sigs) c1 := ts.RandInt32(10) c2 := ts.RandInt32(10) + 10 From ef52258fa7f13fa74f7ca9c3cbe0bccfab519b67 Mon Sep 17 00:00:00 2001 From: RXRD Date: Wed, 5 Jul 2023 21:36:05 +0700 Subject: [PATCH 2/3] format fix --- crypto/bls/bls_test.go | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/crypto/bls/bls_test.go b/crypto/bls/bls_test.go index 940886a94..da8025849 100644 --- a/crypto/bls/bls_test.go +++ b/crypto/bls/bls_test.go @@ -97,21 +97,20 @@ func TestAggregateFailed(t *testing.T) { assert.True(t, bls.VerifyAggregated(agg5, pubs1, msg1)) assert.True(t, bls.VerifyAggregated(agg1, pubs4, msg1)) - assert.NotNil(t, pubAgg1.Verify(msg1,agg1)) - assert.Nil(t, pubAgg1.Verify(msg2,agg1)) - assert.Nil(t, pubAgg1.Verify(msg1,agg2)) - assert.Nil(t, pubAgg2.Verify(msg1,agg1)) - assert.NotNil(t, pubAgg2.Verify(msg1,agg2)) - assert.Nil(t, pubAgg2.Verify(msg2,agg2)) - assert.Nil(t, pubAgg1.Verify(msg1,agg3)) - assert.Nil(t, pubAgg1.Verify(msg2,agg3)) - assert.Nil(t, pubAgg1.Verify(msg1,agg4)) - assert.Nil(t, pubAgg3.Verify(msg1,agg1)) - assert.NotNil(t, pubAgg1.Verify(msg1,agg5)) - assert.NotNil(t, pubAgg4.Verify(msg1,agg1)) + assert.Nil(t, pubAgg1.Verify(msg1, agg1)) + assert.NotNil(t, pubAgg1.Verify(msg2, agg1)) + assert.NotNil(t, pubAgg1.Verify(msg1, agg2)) + assert.NotNil(t, pubAgg2.Verify(msg1, agg1)) + assert.Nil(t, pubAgg2.Verify(msg1, agg2)) + assert.NotNil(t, pubAgg2.Verify(msg2, agg2)) + assert.NotNil(t, pubAgg1.Verify(msg1, agg3)) + assert.NotNil(t, pubAgg1.Verify(msg2, agg3)) + assert.NotNil(t, pubAgg1.Verify(msg1, agg4)) + assert.NotNil(t, pubAgg3.Verify(msg1, agg1)) + assert.Nil(t, pubAgg1.Verify(msg1, agg5)) + assert.Nil(t, pubAgg4.Verify(msg1, agg1)) } - func TestAggregateNil(t *testing.T) { assert.Nil(t, bls.SignatureAggregate(nil)) assert.Nil(t, bls.PublicKeyAggregate(nil)) @@ -160,11 +159,10 @@ func TestDuplicatedAggregate(t *testing.T) { assert.False(t, pubAgg1.EqualsTo(pubAgg2)) assert.False(t, bls.VerifyAggregated(agg1, pubs1, msg1)) - assert.Nil(t, pubAgg1.Verify(msg1,agg1)) + assert.NotNil(t, pubAgg1.Verify(msg1, agg1)) - assert.True(t, bls.VerifyAggregated(agg1, pubs2, msg1)) - assert.NotNil(t, pubAgg2.Verify(msg1,agg1)) + assert.Nil(t, pubAgg2.Verify(msg1, agg1)) } // TestHashToCurve ensures that the hash-to-curve function in kilic/bls12-381 From 3efcabd694f7474a9173abcf6ec738497be07509 Mon Sep 17 00:00:00 2001 From: RXRD Date: Wed, 5 Jul 2023 21:55:09 +0700 Subject: [PATCH 3/3] format fix --- crypto/bls/bls.go | 1 - 1 file changed, 1 deletion(-) diff --git a/crypto/bls/bls.go b/crypto/bls/bls.go index 3d606858f..ab5bf7af9 100644 --- a/crypto/bls/bls.go +++ b/crypto/bls/bls.go @@ -47,7 +47,6 @@ func PublicKeyAggregate(pubs []*PublicKey) *PublicKey { } func VerifyAggregated(sig *Signature, pubs []*PublicKey, msg []byte) bool { - aggPub := PublicKeyAggregate(pubs) return aggPub.Verify(msg, sig) == nil }