package bls import ( "crypto/ed25519" "crypto/sha256" "crypto/sha512" "encoding/hex" "fmt" "testing" "unsafe" "github.com/herumi/bls-eth-go-binary/bls" "github.com/stretchr/testify/assert" ) func TestGetSafePublicKey(t *testing.T) { if bls.Init(bls.BLS12_381) != nil { t.Fatalf("Init") } var sec bls.SecretKey pub, err := sec.GetSafePublicKey() if pub != nil || err == nil { t.Fatalf("sec must be zero") } sec.SetByCSPRNG() pub, err = sec.GetSafePublicKey() if pub == nil || err != nil { t.Fatalf("sec must be non-zero") } } func TestEthDraft07(t *testing.T) { secHex := "0000000000000000000000000000000000000000000000000000000000000001" msgHex := "61736466" sigHex := "b45a264e0d6f8614c4640ea97bae13effd3c74c4e200e3b1596d6830debc952602a7d210eca122dc4f596fa01d7f6299106933abd29477606f64588595e18349afe22ecf2aeeeb63753e88a42ef85b24140847e05620a28422f8c30f1d33b9aa" ethSignOneTest(t, secHex, msgHex, sigHex) } func ethSignOneTest(t *testing.T, secHex string, msgHex string, sigHex string) { var sec bls.SecretKey if sec.DeserializeHexStr(secHex) != nil { t.Fatalf("bad sec") } var sig bls.Sign if sig.DeserializeHexStr(sigHex) != nil { t.Logf("bad sig %v\n", sigHex) return } pub := sec.GetPublicKey() msg, _ := hex.DecodeString(msgHex) sig = *sec.SignByte(msg) if !sig.VerifyByte(pub, msg) { t.Fatalf("bad verify %v %v", secHex, msgHex) } s := sig.SerializeToHexStr() if s != sigHex { t.Fatalf("bad sign\nL=%v\nR=%v\nsec=%v\nmsg=%v", s, sigHex, secHex, msgHex) } } func TestBlsAggregateVerifyNoCheck(t *testing.T) { nTbl := []int{1, 2, 15, 16, 17, 50} for i := 0; i < len(nTbl); i++ { blsAggregateVerifyNoCheckTestOne(t, nTbl[i]) } } func blsAggregateVerifyNoCheckTestOne(t *testing.T, n int) { t.Logf("blsAggregateVerifyNoCheckTestOne %v\n", n) pubs, sigs, msgs := makeMultiSig(n) if !bls.AreAllMsgDifferent(msgs) { t.Fatalf("bad msgs") } var aggSig bls.Sign aggSig.Aggregate(sigs) if !aggSig.AggregateVerifyNoCheck(pubs, msgs) { t.Fatalf("bad AggregateVerifyNoCheck 1") } msgs[1] = 1 if aggSig.AggregateVerifyNoCheck(pubs, msgs) { t.Fatalf("bad AggregateVerifyNoCheck 2") } } func makeMultiSig(n int) (pubs []bls.PublicKey, sigs []bls.Sign, msgs []byte) { msgSize := 32 pubs = make([]bls.PublicKey, n) sigs = make([]bls.Sign, n) msgs = make([]byte, n*msgSize) for i := 0; i < n; i++ { var sec bls.SecretKey sec.SetByCSPRNG() pubs[i] = *sec.GetPublicKey() msgs[msgSize*i] = byte(i) sigs[i] = *sec.SignByte(msgs[msgSize*i : msgSize*(i+1)]) } return pubs, sigs, msgs } func TestMultiVerify(t *testing.T) { pubs, sigs, msgs := makeMultiSig(5) t.Log(msgs) for _, pub := range pubs { t.Log(pub.SerializeToHexStr()) } for _, sig := range sigs { t.Log(sig.SerializeToHexStr()) } assert.True(t, bls.MultiVerify(sigs, pubs, msgs)) } func TestBlsAggregateVerify(t *testing.T) { m := "test" var sec bls.SecretKey sec.SetByCSPRNG() t.Log(sec.GetPop().SerializeToHexStr()) pub := sec.GetPublicKey() sign := sec.Sign(m) t.Log(sec.SerializeToHexStr()) t.Log(pub.SerializeToHexStr()) t.Log(sign.SerializeToHexStr()) assert.True(t, sign.Verify(pub, m)) t.Log(sec.GetPop().SerializeToHexStr()) var sec1 bls.SecretKey sec1.SetByCSPRNG() pub1 := sec1.GetPublicKey() sign1 := sec1.Sign(m) t.Log(sec1.SerializeToHexStr()) t.Log(pub1.SerializeToHexStr()) t.Log(sign1.SerializeToHexStr()) assert.True(t, sign1.Verify(pub1, m)) sign.Add(sign1) pub.Add(pub1) t.Log(pub.SerializeToHexStr()) t.Log(sign.SerializeToHexStr()) pub.Add(pub1) t.Log(pub.SerializeToHexStr()) sign.Add(sign1) t.Log(sign.SerializeToHexStr()) var sec3 bls.SecretKey sec3.SetByCSPRNG() pub3 := sec3.GetPublicKey() sign3 := sec3.GetPop() t.Log(sign.VerifyPop(pub)) t.Log(sign.VerifyPop(pub1)) t.Log(sign.VerifyPop(pub3)) t.Log(sign1.VerifyPop(pub1)) t.Log(sign3.VerifyPop(pub3)) assert.True(t, sign.Verify(pub, m)) // assert.True(t, sign.VerifyPop(pub1)) t.Log(sec.GetPop().SerializeToHexStr()) t.Log(sec.GetPop().SerializeToHexStr()) assert.False(t, sec.GetPop().VerifyPop(pub1)) assert.False(t, sec.GetPop().VerifyPop(pub)) // assert.True(t,sec.GetPop().VerifyPop(pub)) assert.True(t, sec1.GetPop().VerifyPop(pub1)) // Verify self public key assert.False(t, sign.Verify(pub1, m)) assert.False(t, sign.Verify(sec.GetPublicKey(), m)) t.Log("=========: ", sign1.VerifyPop(pub1)) t.Log(bls.HashAndMapToSignature([]byte(m)).SerializeToHexStr()) t.Log(bls.HashAndMapToSignature([]byte(m)).SerializeToHexStr()) pub33 := bls.DHKeyExchange(&sec3, pub3) t.Log(pub33.SerializeToHexStr()) t.Log(pub3.SerializeToHexStr()) assert.False(t, pub33.IsEqual(pub3)) } func TestDHKeyExchange(t *testing.T) { var sec bls.SecretKey sec.SetByCSPRNG() pub := sec.GetPublicKey() var sec1 bls.SecretKey sec1.SetByCSPRNG() pub1 := sec1.GetPublicKey() out := bls.DHKeyExchange(&sec1, pub) out1 := bls.DHKeyExchange(&sec, pub1) assert.True(t, out1.IsEqual(&out)) } func TestRead(t *testing.T) { pk := ed25519.NewKeyFromSeed([]byte("test1231231321122222222221212121")) t.Log(string(pk.Seed())) t.Log(string(pk)) } func TestPop(t *testing.T) { t.Log("testPop") var sec bls.SecretKey sec.SetByCSPRNG() pop := sec.GetPop() if !pop.VerifyPop(sec.GetPublicKey()) { t.Errorf("Valid Pop does not verify") } sec.SetByCSPRNG() if pop.VerifyPop(sec.GetPublicKey()) { t.Errorf("Invalid Pop verifies") } } func TestPairing(t *testing.T) { var sec bls.SecretKey sec.SetByCSPRNG() pub := sec.GetPublicKey() m := "abc" sig1 := sec.Sign(m) sig2 := bls.HashAndMapToSignature([]byte(m)) if !bls.VerifyPairing(sig1, sig2, pub) { t.Errorf("VerifyPairing") } } func TestAggregate(t *testing.T) { var sec bls.SecretKey sec.SetByCSPRNG() pub := sec.GetPublicKey() msgTbl := []string{"abc", "def", "123"} n := len(msgTbl) sigVec := make([]*bls.Sign, n) for i := 0; i < n; i++ { m := msgTbl[i] sigVec[i] = sec.Sign(m) } aggSign := sigVec[0] for i := 1; i < n; i++ { aggSign.Add(sigVec[i]) } hashPt := bls.HashAndMapToSignature([]byte(msgTbl[0])) for i := 1; i < n; i++ { hashPt.Add(bls.HashAndMapToSignature([]byte(msgTbl[i]))) } if !bls.VerifyPairing(aggSign, hashPt, pub) { t.Errorf("aggregate2") } } func TestIsSign(t *testing.T) { m := "test" var sec bls.SecretKey sec.SetByCSPRNG() pub := sec.GetPublicKey() sign := sec.SignByte([]byte(m)) var sec1 bls.SecretKey sec1.SetByCSPRNG() pub1 := sec1.GetPublicKey() sign1 := sec.SignByte([]byte(m)) sign.Add(sign1) hashPt := bls.HashAndMapToSignature([]byte(m)) hashPt.Add(bls.HashAndMapToSignature([]byte(m))) assert.True(t, IsSign(sign, hashPt, pub)) assert.False(t, IsSign(sign, hashPt, pub1)) } func TestAggregateHashes(t *testing.T) { n := 1000 pubVec := make([]bls.PublicKey, n) sigVec := make([]*bls.Sign, n) h := make([][]byte, n) for i := 0; i < n; i++ { sec := new(bls.SecretKey) sec.SetByCSPRNG() pubVec[i] = *sec.GetPublicKey() m := fmt.Sprintf("abc-%d", i) h[i] = Hash([]byte(m)) sigVec[i] = sec.SignHash(h[i]) } // aggregate sig sig := sigVec[0] for i := 1; i < n; i++ { sig.Add(sigVec[i]) } if !sig.VerifyAggregateHashes(pubVec, h) { t.Errorf("sig.VerifyAggregateHashes") } } func Hash(buf []byte) []byte { if bls.GetOpUnitSize() == 4 { d := sha256.Sum256([]byte(buf)) return d[:] } // use SHA512 if bitSize > 256 d := sha512.Sum512([]byte(buf)) return d[:] } func TestHash(t *testing.T) { var sec bls.SecretKey sec.SetByCSPRNG() pub := sec.GetPublicKey() m := "abc" h := Hash([]byte(m)) sig1 := sec.Sign(m) sig2 := sec.SignHash(h) t.Log(sig1.SerializeToHexStr()) t.Log(sig2.SerializeToHexStr()) // TODO fix bug? if sig1.IsEqual(sig2) { t.Errorf("SignHash") } if !sig1.Verify(pub, m) { t.Errorf("sig1.Verify") } if !sig2.VerifyHash(pub, h) { t.Errorf("sig2.VerifyHash") } } func TestCast(t *testing.T) { var sec bls.SecretKey sec.SetByCSPRNG() { x := *bls.CastFromSecretKey(&sec) sec2 := *bls.CastToSecretKey(&x) if !sec.IsEqual(&sec2) { t.Error("sec is not equal") } } var pub bls.Sign var g2 bls.G2 if unsafe.Sizeof(pub) != unsafe.Sizeof(g2) { return } pub = *sec.GetPop() g2 = *bls.CastFromSign(&pub) bls.G2Add(&g2, &g2, &g2) pub.Add(&pub) if !pub.IsEqual(bls.CastToSign(&g2)) { t.Error("pub not equal") } sig := sec.Sign("abc") g2 = *bls.CastFromSign(sig) bls.G2Add(&g2, &g2, &g2) sig.Add(sig) if !sig.IsEqual(bls.CastToSign(&g2)) { t.Error("sig not equal") } } func TestZero(t *testing.T) { var sec bls.SecretKey sec.SetByCSPRNG() pub := sec.GetPublicKey() sig := sec.Sign("abc") if sec.IsZero() { t.Fatal("sec is zero") } if pub.IsZero() { t.Fatal("pub is zero") } if sig.IsZero() { t.Fatal("sig is zero") } sec.SetDecString("0") pub = sec.GetPublicKey() sig = sec.Sign("abc") if !sec.IsZero() { t.Fatal("sec is not zero") } if !pub.IsZero() { t.Fatal("pub is not zero") } if !sig.IsZero() { t.Fatal("sig is not zero") } } func TestAddress(t *testing.T) { pk := PublicKey{ curve: BlsEth, PublicKey: &bls.PublicKey{}, } address, err := pk.Address() assert.Nil(t, err) assert.NotNil(t, address) t.Log(address) }