From 5c668c0107b58a00068244cd3bda3e0a59b27933 Mon Sep 17 00:00:00 2001 From: Aman Sanghi Date: Tue, 3 Sep 2024 19:25:00 +0530 Subject: [PATCH 01/14] Replace kilic/bls12-381 with gnark-crypto/ecc/bls12-381 --- blsSignatures/blsSignatures.go | 156 +++++++++++++++++++-------------- 1 file changed, 91 insertions(+), 65 deletions(-) diff --git a/blsSignatures/blsSignatures.go b/blsSignatures/blsSignatures.go index cfcbc34d80..b254d37309 100644 --- a/blsSignatures/blsSignatures.go +++ b/blsSignatures/blsSignatures.go @@ -4,25 +4,27 @@ package blsSignatures import ( - cryptorand "crypto/rand" "encoding/base64" "errors" + bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" + "github.com/consensys/gnark-crypto/ecc/bls12-381/fp" + "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" "github.com/ethereum/go-ethereum/crypto" - bls12381 "github.com/kilic/bls12-381" + "math/big" ) type PublicKey struct { - key *bls12381.PointG2 - validityProof *bls12381.PointG1 // if this is nil, key came from a trusted source + key *bls12381.G2Affine + validityProof *bls12381.G1Affine // if this is nil, key came from a trusted source } -type PrivateKey *bls12381.Fr +type PrivateKey *fr.Element -type Signature *bls12381.PointG1 +type Signature *bls12381.G1Affine func GeneratePrivKeyString() (string, error) { - fr := bls12381.NewFr() - privKey, err := fr.Rand(cryptorand.Reader) + fr := new(fr.Element) + privKey, err := fr.SetRandom() if err != nil { return "", err } @@ -33,8 +35,8 @@ func GeneratePrivKeyString() (string, error) { } func GenerateKeys() (PublicKey, PrivateKey, error) { - fr := bls12381.NewFr() - privateKey, err := fr.Rand(cryptorand.Reader) + fr := new(fr.Element) + privateKey, err := fr.SetRandom() if err != nil { return PublicKey{}, nil, err } @@ -43,9 +45,13 @@ func GenerateKeys() (PublicKey, PrivateKey, error) { } func PublicKeyFromPrivateKey(privateKey PrivateKey) (PublicKey, error) { - pubKey := &bls12381.PointG2{} - g2 := bls12381.NewG2() - g2.MulScalar(pubKey, g2.One(), privateKey) + pubKey := new(bls12381.G2Affine) + g2 := new(bls12381.G2Affine) + g2.X.SetOne() + g2.Y.SetOne() + fr := new(fr.Element) + fr.Set(privateKey) + pubKey.ScalarMultiplication(g2, fr.BigInt(new(big.Int))) proof, err := KeyValidityProof(pubKey, privateKey) if err != nil { return PublicKey{}, err @@ -64,15 +70,15 @@ func PublicKeyFromPrivateKey(privateKey PrivateKey) (PublicKey, error) { // // For a proof that this is sufficient, see Theorem 1 in // Ristenpart & Yilek, "The Power of Proofs-of-Possession: ..." from EUROCRYPT 2007. -func KeyValidityProof(pubKey *bls12381.PointG2, privateKey PrivateKey) (Signature, error) { - g2 := bls12381.NewG2() - return signMessage2(privateKey, g2.ToBytes(pubKey), true) +func KeyValidityProof(pubKey *bls12381.G2Affine, privateKey PrivateKey) (Signature, error) { + message := pubKey.Bytes() + return signMessage2(privateKey, message[:], true) } -func NewPublicKey(pubKey *bls12381.PointG2, validityProof *bls12381.PointG1) (PublicKey, error) { - g2 := bls12381.NewG2() +func NewPublicKey(pubKey *bls12381.G2Affine, validityProof *bls12381.G1Affine) (PublicKey, error) { + message := pubKey.Bytes() unverifiedPublicKey := PublicKey{pubKey, validityProof} - verified, err := verifySignature2(validityProof, g2.ToBytes(pubKey), unverifiedPublicKey, true) + verified, err := verifySignature2(validityProof, message[:], unverifiedPublicKey, true) if err != nil { return PublicKey{}, err } @@ -82,7 +88,7 @@ func NewPublicKey(pubKey *bls12381.PointG2, validityProof *bls12381.PointG1) (Pu return unverifiedPublicKey, nil } -func NewTrustedPublicKey(pubKey *bls12381.PointG2) PublicKey { +func NewTrustedPublicKey(pubKey *bls12381.G2Affine) PublicKey { return PublicKey{pubKey, nil} } @@ -102,9 +108,10 @@ func signMessage2(priv PrivateKey, message []byte, keyValidationMode bool) (Sign if err != nil { return nil, err } - g1 := bls12381.NewG1() - result := &bls12381.PointG1{} - g1.MulScalar(result, pointOnCurve, priv) + result := new(bls12381.G1Affine) + fr := new(fr.Element) + fr.Set(priv) + result.ScalarMultiplication(pointOnCurve, fr.BigInt(new(big.Int))) return result, nil } @@ -118,31 +125,35 @@ func verifySignature2(sig Signature, message []byte, publicKey PublicKey, keyVal return false, err } - engine := bls12381.NewEngine() - engine.Reset() - engine.AddPair(pointOnCurve, publicKey.key) - leftSide := engine.Result() - engine.AddPair(sig, engine.G2.One()) - rightSide := engine.Result() - return leftSide.Equal(rightSide), nil + leftSide, err := bls12381.Pair([]bls12381.G1Affine{*pointOnCurve}, []bls12381.G2Affine{*publicKey.key}) + if err != nil { + return false, err + } + g2 := new(bls12381.G2Affine) + g2.X.SetOne() + g2.Y.SetOne() + rightSide, err := bls12381.Pair([]bls12381.G1Affine{*sig}, []bls12381.G2Affine{*g2}) + return leftSide.Equal(&rightSide), nil } func AggregatePublicKeys(pubKeys []PublicKey) PublicKey { - g2 := bls12381.NewG2() - ret := g2.Zero() + g2 := new(bls12381.G2Affine) + g2.X.SetZero() + g2.Y.SetZero() for _, pk := range pubKeys { - g2.Add(ret, ret, pk.key) + g2.Add(g2, pk.key) } - return NewTrustedPublicKey(ret) + return NewTrustedPublicKey(g2) } func AggregateSignatures(sigs []Signature) Signature { - g1 := bls12381.NewG1() - ret := g1.Zero() + g1 := new(bls12381.G1Affine) + g1.X.SetZero() + g1.Y.SetZero() for _, s := range sigs { - g1.Add(ret, ret, s) + g1.Add(g1, s) } - return ret + return g1 } func VerifyAggregatedSignatureSameMessage(sig Signature, message []byte, pubKeys []PublicKey) (bool, error) { @@ -154,21 +165,28 @@ func VerifyAggregatedSignatureDifferentMessages(sig Signature, messages [][]byte if len(messages) != len(pubKeys) { return false, errors.New("len(messages) does not match (len(pub keys) in verification") } - engine := bls12381.NewEngine() - engine.Reset() + var p []bls12381.G1Affine + var q []bls12381.G2Affine for i, msg := range messages { pointOnCurve, err := hashToG1Curve(msg, false) if err != nil { return false, err } - engine.AddPair(pointOnCurve, pubKeys[i].key) + p = append(p, *pointOnCurve) + q = append(q, *pubKeys[i].key) } - leftSide := engine.Result() - - engine.Reset() - engine.AddPair(sig, engine.G2.One()) - rightSide := engine.Result() - return leftSide.Equal(rightSide), nil + leftSide, err := bls12381.Pair(p, q) + if err != nil { + return false, err + } + g2 := new(bls12381.G2Affine) + g2.X.SetOne() + g2.Y.SetOne() + rightSide, err := bls12381.Pair([]bls12381.G1Affine{*sig}, []bls12381.G2Affine{*g2}) + if err != nil { + return false, err + } + return leftSide.Equal(&rightSide), nil } // This hashes a message to a [32]byte, then maps the result to the G1 curve using @@ -177,41 +195,42 @@ func VerifyAggregatedSignatureDifferentMessages(sig Signature, messages [][]byte // // If keyValidationMode is true, this uses a tweaked version of the padding, // so that the result will not collide with a result generated in an ordinary signature. -func hashToG1Curve(message []byte, keyValidationMode bool) (*bls12381.PointG1, error) { +func hashToG1Curve(message []byte, keyValidationMode bool) (*bls12381.G1Affine, error) { var padding [16]byte h := crypto.Keccak256(message) if keyValidationMode { // modify padding, for domain separation padding[0] = 1 } - g1 := bls12381.NewG1() - return g1.MapToCurve(append(padding[:], h...)) + fp := new(fp.Element) + fp.Unmarshal(append(padding[:], h...)) + res := bls12381.MapToG1(*fp) + return &res, nil } func PublicKeyToBytes(pub PublicKey) []byte { - g2 := bls12381.NewG2() + keyBytes := pub.key.Bytes() if pub.validityProof == nil { - return append([]byte{0}, g2.ToBytes(pub.key)...) + return append([]byte{0}, keyBytes[:]...) } - keyBytes := g2.ToBytes(pub.key) sigBytes := SignatureToBytes(pub.validityProof) if len(sigBytes) > 255 { panic("validity proof too large to serialize") } - return append(append([]byte{byte(len(sigBytes))}, sigBytes...), keyBytes...) + return append(append([]byte{byte(len(sigBytes))}, sigBytes...), keyBytes[:]...) } func PublicKeyFromBytes(in []byte, trustedSource bool) (PublicKey, error) { if len(in) == 0 { return PublicKey{}, errors.New("tried to deserialize empty public key") } - g2 := bls12381.NewG2() + key := new(bls12381.G2Affine) proofLen := int(in[0]) if proofLen == 0 { if !trustedSource { return PublicKey{}, errors.New("tried to deserialize unvalidated public key from untrusted source") } - key, err := g2.FromBytes(in[1:]) + err := key.Unmarshal(in[1:]) if err != nil { return PublicKey{}, err } @@ -220,14 +239,14 @@ func PublicKeyFromBytes(in []byte, trustedSource bool) (PublicKey, error) { if len(in) < 1+proofLen { return PublicKey{}, errors.New("invalid serialized public key") } - g1 := bls12381.NewG1() + validityProof := new(bls12381.G1Affine) proofBytes := in[1 : 1+proofLen] - validityProof, err := g1.FromBytes(proofBytes) + err := validityProof.Unmarshal(proofBytes) if err != nil { return PublicKey{}, err } keyBytes := in[1+proofLen:] - key, err := g2.FromBytes(keyBytes) + err = key.Unmarshal(keyBytes) if err != nil { return PublicKey{}, err } @@ -240,19 +259,26 @@ func PublicKeyFromBytes(in []byte, trustedSource bool) (PublicKey, error) { } func PrivateKeyToBytes(priv PrivateKey) []byte { - return bls12381.NewFr().Set(priv).ToBytes() + bytes := new(fr.Element).Set(priv).Bytes() + return bytes[:] } func PrivateKeyFromBytes(in []byte) (PrivateKey, error) { - return bls12381.NewFr().FromBytes(in), nil + return new(fr.Element).SetBytes(in), nil } func SignatureToBytes(sig Signature) []byte { - g1 := bls12381.NewG1() - return g1.ToBytes(sig) + g1 := new(bls12381.G1Affine) + g1.Set(sig) + bytes := g1.Bytes() + return bytes[:] } func SignatureFromBytes(in []byte) (Signature, error) { - g1 := bls12381.NewG1() - return g1.FromBytes(in) + g1 := new(bls12381.G1Affine) + err := g1.Unmarshal(in) + if err != nil { + return nil, err + } + return g1, nil } From 18c11c6d1d85f2c7c50beac454dd83774f9407d5 Mon Sep 17 00:00:00 2001 From: Aman Sanghi Date: Tue, 3 Sep 2024 20:34:12 +0530 Subject: [PATCH 02/14] fix lint --- blsSignatures/blsSignatures.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/blsSignatures/blsSignatures.go b/blsSignatures/blsSignatures.go index b254d37309..56f075fc6b 100644 --- a/blsSignatures/blsSignatures.go +++ b/blsSignatures/blsSignatures.go @@ -133,6 +133,9 @@ func verifySignature2(sig Signature, message []byte, publicKey PublicKey, keyVal g2.X.SetOne() g2.Y.SetOne() rightSide, err := bls12381.Pair([]bls12381.G1Affine{*sig}, []bls12381.G2Affine{*g2}) + if err != nil { + return false, err + } return leftSide.Equal(&rightSide), nil } From 841506e78d1c3d9aa6f94be278a82715cb80afd3 Mon Sep 17 00:00:00 2001 From: Aman Sanghi Date: Mon, 7 Oct 2024 17:43:19 +0530 Subject: [PATCH 03/14] Changes based on PR comments --- blsSignatures/blsSignatures.go | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/blsSignatures/blsSignatures.go b/blsSignatures/blsSignatures.go index 56f075fc6b..61fc8bac96 100644 --- a/blsSignatures/blsSignatures.go +++ b/blsSignatures/blsSignatures.go @@ -46,12 +46,10 @@ func GenerateKeys() (PublicKey, PrivateKey, error) { func PublicKeyFromPrivateKey(privateKey PrivateKey) (PublicKey, error) { pubKey := new(bls12381.G2Affine) - g2 := new(bls12381.G2Affine) - g2.X.SetOne() - g2.Y.SetOne() + _, _, _, g2 := bls12381.Generators() fr := new(fr.Element) fr.Set(privateKey) - pubKey.ScalarMultiplication(g2, fr.BigInt(new(big.Int))) + pubKey.ScalarMultiplication(&g2, fr.BigInt(new(big.Int))) proof, err := KeyValidityProof(pubKey, privateKey) if err != nil { return PublicKey{}, err @@ -129,10 +127,8 @@ func verifySignature2(sig Signature, message []byte, publicKey PublicKey, keyVal if err != nil { return false, err } - g2 := new(bls12381.G2Affine) - g2.X.SetOne() - g2.Y.SetOne() - rightSide, err := bls12381.Pair([]bls12381.G1Affine{*sig}, []bls12381.G2Affine{*g2}) + _, _, _, g2 := bls12381.Generators() + rightSide, err := bls12381.Pair([]bls12381.G1Affine{*sig}, []bls12381.G2Affine{g2}) if err != nil { return false, err } @@ -182,10 +178,8 @@ func VerifyAggregatedSignatureDifferentMessages(sig Signature, messages [][]byte if err != nil { return false, err } - g2 := new(bls12381.G2Affine) - g2.X.SetOne() - g2.Y.SetOne() - rightSide, err := bls12381.Pair([]bls12381.G1Affine{*sig}, []bls12381.G2Affine{*g2}) + _, _, _, g2 := bls12381.Generators() + rightSide, err := bls12381.Pair([]bls12381.G1Affine{*sig}, []bls12381.G2Affine{g2}) if err != nil { return false, err } From 8abaec7c21d0b780f263a85b75d6bb8025818fe9 Mon Sep 17 00:00:00 2001 From: Aman Sanghi Date: Tue, 8 Oct 2024 19:30:26 +0530 Subject: [PATCH 04/14] Changes based on PR comments --- blsSignatures/blsSignatures.go | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/blsSignatures/blsSignatures.go b/blsSignatures/blsSignatures.go index 61fc8bac96..3cb374fe9a 100644 --- a/blsSignatures/blsSignatures.go +++ b/blsSignatures/blsSignatures.go @@ -23,8 +23,7 @@ type PrivateKey *fr.Element type Signature *bls12381.G1Affine func GeneratePrivKeyString() (string, error) { - fr := new(fr.Element) - privKey, err := fr.SetRandom() + privKey, err := new(fr.Element).SetRandom() if err != nil { return "", err } @@ -47,9 +46,7 @@ func GenerateKeys() (PublicKey, PrivateKey, error) { func PublicKeyFromPrivateKey(privateKey PrivateKey) (PublicKey, error) { pubKey := new(bls12381.G2Affine) _, _, _, g2 := bls12381.Generators() - fr := new(fr.Element) - fr.Set(privateKey) - pubKey.ScalarMultiplication(&g2, fr.BigInt(new(big.Int))) + pubKey.ScalarMultiplication(&g2, (*privateKey).BigInt(new(big.Int))) proof, err := KeyValidityProof(pubKey, privateKey) if err != nil { return PublicKey{}, err @@ -107,9 +104,7 @@ func signMessage2(priv PrivateKey, message []byte, keyValidationMode bool) (Sign return nil, err } result := new(bls12381.G1Affine) - fr := new(fr.Element) - fr.Set(priv) - result.ScalarMultiplication(pointOnCurve, fr.BigInt(new(big.Int))) + result.ScalarMultiplication(pointOnCurve, (*priv).BigInt(new(big.Int))) return result, nil } @@ -137,8 +132,6 @@ func verifySignature2(sig Signature, message []byte, publicKey PublicKey, keyVal func AggregatePublicKeys(pubKeys []PublicKey) PublicKey { g2 := new(bls12381.G2Affine) - g2.X.SetZero() - g2.Y.SetZero() for _, pk := range pubKeys { g2.Add(g2, pk.key) } @@ -147,8 +140,6 @@ func AggregatePublicKeys(pubKeys []PublicKey) PublicKey { func AggregateSignatures(sigs []Signature) Signature { g1 := new(bls12381.G1Affine) - g1.X.SetZero() - g1.Y.SetZero() for _, s := range sigs { g1.Add(g1, s) } @@ -256,7 +247,7 @@ func PublicKeyFromBytes(in []byte, trustedSource bool) (PublicKey, error) { } func PrivateKeyToBytes(priv PrivateKey) []byte { - bytes := new(fr.Element).Set(priv).Bytes() + bytes := (*priv).Bytes() return bytes[:] } @@ -265,9 +256,7 @@ func PrivateKeyFromBytes(in []byte) (PrivateKey, error) { } func SignatureToBytes(sig Signature) []byte { - g1 := new(bls12381.G1Affine) - g1.Set(sig) - bytes := g1.Bytes() + bytes := (*sig).Bytes() return bytes[:] } From 24301531914b797c5a5bd16db033f2a34d41259a Mon Sep 17 00:00:00 2001 From: Aman Sanghi Date: Tue, 8 Oct 2024 19:32:23 +0530 Subject: [PATCH 05/14] Changes based on PR comments --- blsSignatures/blsSignatures.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/blsSignatures/blsSignatures.go b/blsSignatures/blsSignatures.go index 3cb374fe9a..e4fcacb352 100644 --- a/blsSignatures/blsSignatures.go +++ b/blsSignatures/blsSignatures.go @@ -34,8 +34,7 @@ func GeneratePrivKeyString() (string, error) { } func GenerateKeys() (PublicKey, PrivateKey, error) { - fr := new(fr.Element) - privateKey, err := fr.SetRandom() + privateKey, err := new(fr.Element).SetRandom() if err != nil { return PublicKey{}, nil, err } From df690976a36b337b9b130de2ac1281cc9912df13 Mon Sep 17 00:00:00 2001 From: Aman Sanghi Date: Fri, 11 Oct 2024 17:59:08 +0530 Subject: [PATCH 06/14] TestPublicKeyFromPrivateKey --- blsSignatures/blsSignatures_test.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/blsSignatures/blsSignatures_test.go b/blsSignatures/blsSignatures_test.go index 6446b31405..647eb1a777 100644 --- a/blsSignatures/blsSignatures_test.go +++ b/blsSignatures/blsSignatures_test.go @@ -4,6 +4,8 @@ package blsSignatures import ( + "bytes" + "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" "math/rand" "testing" "time" @@ -11,6 +13,30 @@ import ( "github.com/offchainlabs/nitro/util/testhelpers" ) +func TestPublicKeyFromPrivateKey(t *testing.T) { + // Hardcoded private key for testing + privateKey := new(fr.Element).SetBytes([]byte{54, 16, 51, 77, 200, 74, 139, 205, 66, 197, 218, 43, 163, 239, 159, 127, 31, 250, 204, 181, 30, 57, 125, 217, 57, 198, 145, 143, 232, 224, 117, 185}) + publicKey, err := PublicKeyFromPrivateKey(privateKey) + Require(t, err) + publicKeyBytes := publicKey.key.RawBytes() + // Compare to the public key generated by the Ethereum BLS library + if !bytes.Equal(publicKeyBytes[:], []byte{5, 26, 203, 151, 1, 124, 221, 162, 29, 13, 15, 227, 78, 232, 125, 200, 232, 245, 251, 196, 153, 185, 66, 74, 49, 126, 168, 225, 101, 252, 124, 184, 52, 101, 97, 135, 1, 36, 242, 88, 206, 106, 47, 226, 161, 148, 35, 61, 8, 234, 6, 124, 238, 224, 58, 64, 92, 163, 210, 25, 221, 204, 20, 149, 121, 193, 175, 168, 157, 184, 16, 216, 30, 181, 114, 184, 201, 251, 46, 246, 7, 80, 87, 34, 101, 34, 123, 51, 58, 176, 132, 118, 190, 53, 158, 161, 19, 144, 72, 109, 52, 189, 109, 245, 80, 64, 229, 196, 99, 200, 215, 204, 77, 156, 60, 196, 6, 167, 27, 227, 96, 190, 228, 57, 53, 32, 128, 67, 192, 155, 233, 163, 171, 83, 86, 81, 93, 20, 221, 52, 75, 254, 66, 42, 17, 79, 254, 35, 80, 175, 30, 100, 210, 109, 164, 150, 197, 88, 104, 152, 160, 178, 69, 78, 56, 215, 38, 180, 215, 212, 202, 233, 219, 224, 245, 184, 223, 248, 166, 91, 147, 62, 53, 61, 251, 83, 155, 92, 68, 201, 65, 92}) { + Fail(t, "public key is incorrect") + } + // Use the validity proof generated by the Ethereum BLS library + _, err = publicKey.validityProof.SetBytes([]byte{24, 152, 185, 33, 240, 229, 254, 108, 130, 235, 47, 25, 45, 224, 93, 56, 103, 226, 157, 91, 233, 2, 73, 218, 179, 213, 171, 7, 54, 4, 113, 43, 19, 25, 188, 71, 45, 232, 233, 95, 223, 113, 104, 118, 210, 115, 248, 126, 18, 80, 5, 160, 54, 207, 82, 154, 150, 84, 98, 19, 68, 17, 230, 124, 32, 106, 80, 143, 74, 214, 105, 109, 69, 114, 47, 239, 145, 131, 19, 145, 77, 207, 249, 122, 229, 239, 228, 89, 42, 207, 97, 244, 39, 21, 115, 60}) + Require(t, err) + message := []byte("The quick brown fox jumped over the lazy dog.") + sig, err := SignMessage(privateKey, message) + Require(t, err) + + verified, err := VerifySignature(sig, message, publicKey) + Require(t, err) + if !verified { + Fail(t, "valid signature failed to verify") + } +} + func TestValidSignature(t *testing.T) { pub, priv, err := GenerateKeys() Require(t, err) From 010ca1e282ca6cc8b788483b11dd04c2d60e4f8a Mon Sep 17 00:00:00 2001 From: Aman Sanghi Date: Fri, 11 Oct 2024 18:18:47 +0530 Subject: [PATCH 07/14] TestPublicKeyToBytes --- blsSignatures/blsSignatures.go | 4 ++-- blsSignatures/blsSignatures_test.go | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/blsSignatures/blsSignatures.go b/blsSignatures/blsSignatures.go index e4fcacb352..184fa5da2f 100644 --- a/blsSignatures/blsSignatures.go +++ b/blsSignatures/blsSignatures.go @@ -196,7 +196,7 @@ func hashToG1Curve(message []byte, keyValidationMode bool) (*bls12381.G1Affine, } func PublicKeyToBytes(pub PublicKey) []byte { - keyBytes := pub.key.Bytes() + keyBytes := pub.key.RawBytes() if pub.validityProof == nil { return append([]byte{0}, keyBytes[:]...) } @@ -255,7 +255,7 @@ func PrivateKeyFromBytes(in []byte) (PrivateKey, error) { } func SignatureToBytes(sig Signature) []byte { - bytes := (*sig).Bytes() + bytes := (*sig).RawBytes() return bytes[:] } diff --git a/blsSignatures/blsSignatures_test.go b/blsSignatures/blsSignatures_test.go index 647eb1a777..8e2061ce8f 100644 --- a/blsSignatures/blsSignatures_test.go +++ b/blsSignatures/blsSignatures_test.go @@ -37,6 +37,15 @@ func TestPublicKeyFromPrivateKey(t *testing.T) { } } +func TestPublicKeyToBytes(t *testing.T) { + expectedPublicKeyBytes := []byte{0, 5, 26, 203, 151, 1, 124, 221, 162, 29, 13, 15, 227, 78, 232, 125, 200, 232, 245, 251, 196, 153, 185, 66, 74, 49, 126, 168, 225, 101, 252, 124, 184, 52, 101, 97, 135, 1, 36, 242, 88, 206, 106, 47, 226, 161, 148, 35, 61, 8, 234, 6, 124, 238, 224, 58, 64, 92, 163, 210, 25, 221, 204, 20, 149, 121, 193, 175, 168, 157, 184, 16, 216, 30, 181, 114, 184, 201, 251, 46, 246, 7, 80, 87, 34, 101, 34, 123, 51, 58, 176, 132, 118, 190, 53, 158, 161, 19, 144, 72, 109, 52, 189, 109, 245, 80, 64, 229, 196, 99, 200, 215, 204, 77, 156, 60, 196, 6, 167, 27, 227, 96, 190, 228, 57, 53, 32, 128, 67, 192, 155, 233, 163, 171, 83, 86, 81, 93, 20, 221, 52, 75, 254, 66, 42, 17, 79, 254, 35, 80, 175, 30, 100, 210, 109, 164, 150, 197, 88, 104, 152, 160, 178, 69, 78, 56, 215, 38, 180, 215, 212, 202, 233, 219, 224, 245, 184, 223, 248, 166, 91, 147, 62, 53, 61, 251, 83, 155, 92, 68, 201, 65, 92} + publicKey, err := PublicKeyFromBytes(expectedPublicKeyBytes, true) + Require(t, err) + publicKeyBytes := PublicKeyToBytes(publicKey) + if !bytes.Equal(publicKeyBytes, expectedPublicKeyBytes) { + Fail(t, "public key to bytes failed") + } +} func TestValidSignature(t *testing.T) { pub, priv, err := GenerateKeys() Require(t, err) From 00148230a829c0b342e33b953eb1f6e4d66bf068 Mon Sep 17 00:00:00 2001 From: Aman Sanghi Date: Fri, 11 Oct 2024 18:32:45 +0530 Subject: [PATCH 08/14] TestHashToG1Curve --- blsSignatures/blsSignatures_test.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/blsSignatures/blsSignatures_test.go b/blsSignatures/blsSignatures_test.go index 8e2061ce8f..24cc5c735d 100644 --- a/blsSignatures/blsSignatures_test.go +++ b/blsSignatures/blsSignatures_test.go @@ -46,6 +46,16 @@ func TestPublicKeyToBytes(t *testing.T) { Fail(t, "public key to bytes failed") } } + +func TestHashToG1Curve(t *testing.T) { + g1, err := hashToG1Curve([]byte{5, 26, 203, 151, 1, 124, 221, 162, 29, 13, 15, 227, 78, 232, 125, 200, 232, 245, 251, 196, 153, 185, 66, 74, 49, 126, 168, 225, 101, 252, 124, 184, 52, 101, 97, 135, 1, 36, 242, 88, 206, 106, 47, 226, 161, 148, 35, 61, 8, 234, 6, 124, 238, 224, 58, 64, 92, 163, 210, 25, 221, 204, 20, 149, 121, 193, 175, 168, 157, 184, 16, 216, 30, 181, 114, 184, 201, 251, 46, 246, 7, 80, 87, 34, 101, 34, 123, 51, 58, 176, 132, 118, 190, 53, 158, 161, 19, 144, 72, 109, 52, 189, 109, 245, 80, 64, 229, 196, 99, 200, 215, 204, 77, 156, 60, 196, 6, 167, 27, 227, 96, 190, 228, 57, 53, 32, 128, 67, 192, 155, 233, 163, 171, 83, 86, 81, 93, 20, 221, 52, 75, 254, 66, 42, 17, 79, 254, 35, 80, 175, 30, 100, 210, 109, 164, 150, 197, 88, 104, 152, 160, 178, 69, 78, 56, 215, 38, 180, 215, 212, 202, 233, 219, 224, 245, 184, 223, 248, 166, 91, 147, 62, 53, 61, 251, 83, 155, 92, 68, 201, 65, 92}, true) + Require(t, err) + g1Bytes := g1.RawBytes() + if !bytes.Equal(g1Bytes[:], []byte{22, 205, 206, 121, 144, 143, 115, 232, 210, 74, 148, 73, 40, 222, 234, 186, 113, 228, 107, 174, 195, 131, 199, 48, 158, 20, 232, 188, 206, 210, 78, 82, 117, 237, 138, 249, 30, 26, 199, 135, 41, 65, 4, 73, 164, 235, 55, 179, 1, 84, 24, 92, 0, 215, 232, 26, 75, 112, 160, 84, 189, 124, 183, 97, 173, 171, 99, 181, 115, 96, 178, 31, 130, 107, 83, 3, 56, 126, 181, 146, 250, 249, 4, 85, 66, 241, 120, 209, 66, 71, 195, 138, 145, 19, 165, 26}) { + Fail(t, "hash to G1 curve failed") + } +} + func TestValidSignature(t *testing.T) { pub, priv, err := GenerateKeys() Require(t, err) From 268f82a4f453c7f2789c11155e9428055922a2e0 Mon Sep 17 00:00:00 2001 From: Aman Sanghi Date: Wed, 16 Oct 2024 16:19:37 +0530 Subject: [PATCH 09/14] Changes based on PR comments --- blsSignatures/blsSignatures.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/blsSignatures/blsSignatures.go b/blsSignatures/blsSignatures.go index 184fa5da2f..b064c6a9f8 100644 --- a/blsSignatures/blsSignatures.go +++ b/blsSignatures/blsSignatures.go @@ -217,6 +217,10 @@ func PublicKeyFromBytes(in []byte, trustedSource bool) (PublicKey, error) { if !trustedSource { return PublicKey{}, errors.New("tried to deserialize unvalidated public key from untrusted source") } + // The most significant bit, when set, indicates that the point is in compressed form. Otherwise, the point is in uncompressed form. + if (in[1] & (1 << 7)) != 0 { + return PublicKey{}, errors.New("invalid serialized public key") + } err := key.Unmarshal(in[1:]) if err != nil { return PublicKey{}, err @@ -228,11 +232,19 @@ func PublicKeyFromBytes(in []byte, trustedSource bool) (PublicKey, error) { } validityProof := new(bls12381.G1Affine) proofBytes := in[1 : 1+proofLen] + // The most significant bit, when set, indicates that the point is in compressed form. Otherwise, the point is in uncompressed form. + if (proofBytes[0] & (1 << 7)) != 0 { + return PublicKey{}, errors.New("invalid serialized validity proof") + } err := validityProof.Unmarshal(proofBytes) if err != nil { return PublicKey{}, err } keyBytes := in[1+proofLen:] + // The most significant bit, when set, indicates that the point is in compressed form. Otherwise, the point is in uncompressed form. + if (keyBytes[0] & (1 << 7)) != 0 { + return PublicKey{}, errors.New("invalid serialized public key") + } err = key.Unmarshal(keyBytes) if err != nil { return PublicKey{}, err @@ -260,6 +272,10 @@ func SignatureToBytes(sig Signature) []byte { } func SignatureFromBytes(in []byte) (Signature, error) { + // The most significant bit, when set, indicates that the point is in compressed form. Otherwise, the point is in uncompressed form. + if (in[0] & (1 << 7)) != 0 { + return nil, errors.New("invalid serialized signature") + } g1 := new(bls12381.G1Affine) err := g1.Unmarshal(in) if err != nil { From d4efeecb5c887877388cc8cba65d78a0ac1a608d Mon Sep 17 00:00:00 2001 From: Aman Sanghi Date: Wed, 16 Oct 2024 21:06:41 +0530 Subject: [PATCH 10/14] Changes based on PR comments --- blsSignatures/blsSignatures.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/blsSignatures/blsSignatures.go b/blsSignatures/blsSignatures.go index b064c6a9f8..14f0da9323 100644 --- a/blsSignatures/blsSignatures.go +++ b/blsSignatures/blsSignatures.go @@ -218,7 +218,7 @@ func PublicKeyFromBytes(in []byte, trustedSource bool) (PublicKey, error) { return PublicKey{}, errors.New("tried to deserialize unvalidated public key from untrusted source") } // The most significant bit, when set, indicates that the point is in compressed form. Otherwise, the point is in uncompressed form. - if (in[1] & (1 << 7)) != 0 { + if len(in) == 1 || (in[1]&(1<<7)) != 0 { return PublicKey{}, errors.New("invalid serialized public key") } err := key.Unmarshal(in[1:]) @@ -233,7 +233,7 @@ func PublicKeyFromBytes(in []byte, trustedSource bool) (PublicKey, error) { validityProof := new(bls12381.G1Affine) proofBytes := in[1 : 1+proofLen] // The most significant bit, when set, indicates that the point is in compressed form. Otherwise, the point is in uncompressed form. - if (proofBytes[0] & (1 << 7)) != 0 { + if len(proofBytes) == 0 || (proofBytes[0]&(1<<7)) != 0 { return PublicKey{}, errors.New("invalid serialized validity proof") } err := validityProof.Unmarshal(proofBytes) @@ -242,7 +242,7 @@ func PublicKeyFromBytes(in []byte, trustedSource bool) (PublicKey, error) { } keyBytes := in[1+proofLen:] // The most significant bit, when set, indicates that the point is in compressed form. Otherwise, the point is in uncompressed form. - if (keyBytes[0] & (1 << 7)) != 0 { + if len(keyBytes) == 0 || (keyBytes[0]&(1<<7)) != 0 { return PublicKey{}, errors.New("invalid serialized public key") } err = key.Unmarshal(keyBytes) @@ -273,7 +273,7 @@ func SignatureToBytes(sig Signature) []byte { func SignatureFromBytes(in []byte) (Signature, error) { // The most significant bit, when set, indicates that the point is in compressed form. Otherwise, the point is in uncompressed form. - if (in[0] & (1 << 7)) != 0 { + if len(in) == 0 || (in[0]&(1<<7)) != 0 { return nil, errors.New("invalid serialized signature") } g1 := new(bls12381.G1Affine) From 89945740970c5eed3f789f44f478f8c52ac0b6e9 Mon Sep 17 00:00:00 2001 From: Aman Sanghi Date: Thu, 17 Oct 2024 21:55:48 +0530 Subject: [PATCH 11/14] update --- blsSignatures/blsSignatures.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/blsSignatures/blsSignatures.go b/blsSignatures/blsSignatures.go index 14f0da9323..1b136d33b4 100644 --- a/blsSignatures/blsSignatures.go +++ b/blsSignatures/blsSignatures.go @@ -4,6 +4,7 @@ package blsSignatures import ( + "bytes" "encoding/base64" "errors" bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" @@ -276,8 +277,15 @@ func SignatureFromBytes(in []byte) (Signature, error) { if len(in) == 0 || (in[0]&(1<<7)) != 0 { return nil, errors.New("invalid serialized signature") } + if len(in) != 96 { + return nil, errors.New("input string should be equal or larger than 96") + } + if new(big.Int).SetBytes(in).Cmp(fp.Modulus()) >= 0 { + return nil, errors.New("must be less than modulus") + } g1 := new(bls12381.G1Affine) - err := g1.Unmarshal(in) + + err := bls12381.NewDecoder(bytes.NewReader(in)).Decode(g1) if err != nil { return nil, err } From 4832a12d9cc89072f83394798c823dbb84648b87 Mon Sep 17 00:00:00 2001 From: Aman Sanghi Date: Thu, 17 Oct 2024 22:05:05 +0530 Subject: [PATCH 12/14] update --- blsSignatures/blsSignatures.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/blsSignatures/blsSignatures.go b/blsSignatures/blsSignatures.go index 1b136d33b4..98ccde4ab7 100644 --- a/blsSignatures/blsSignatures.go +++ b/blsSignatures/blsSignatures.go @@ -4,7 +4,6 @@ package blsSignatures import ( - "bytes" "encoding/base64" "errors" bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" @@ -284,8 +283,7 @@ func SignatureFromBytes(in []byte) (Signature, error) { return nil, errors.New("must be less than modulus") } g1 := new(bls12381.G1Affine) - - err := bls12381.NewDecoder(bytes.NewReader(in)).Decode(g1) + err := g1.Unmarshal(in) if err != nil { return nil, err } From 0aacc8c34522cd2ef4fcdaa7ee9ff7c01bfdef7a Mon Sep 17 00:00:00 2001 From: Aman Sanghi Date: Thu, 17 Oct 2024 22:41:40 +0530 Subject: [PATCH 13/14] update --- blsSignatures/blsSignatures.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/blsSignatures/blsSignatures.go b/blsSignatures/blsSignatures.go index 98ccde4ab7..b971df9918 100644 --- a/blsSignatures/blsSignatures.go +++ b/blsSignatures/blsSignatures.go @@ -4,6 +4,7 @@ package blsSignatures import ( + "bytes" "encoding/base64" "errors" bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" @@ -267,8 +268,9 @@ func PrivateKeyFromBytes(in []byte) (PrivateKey, error) { } func SignatureToBytes(sig Signature) []byte { - bytes := (*sig).RawBytes() - return bytes[:] + buf := new(bytes.Buffer) + bls12381.NewEncoder(buf).Encode(sig) + return buf.Bytes() } func SignatureFromBytes(in []byte) (Signature, error) { @@ -283,7 +285,7 @@ func SignatureFromBytes(in []byte) (Signature, error) { return nil, errors.New("must be less than modulus") } g1 := new(bls12381.G1Affine) - err := g1.Unmarshal(in) + err := bls12381.NewDecoder(bytes.NewReader(in)).Decode(g1) if err != nil { return nil, err } From 08a377ccf2a2b5f7952e3e2dfdfff76a2860786a Mon Sep 17 00:00:00 2001 From: Aman Sanghi Date: Thu, 17 Oct 2024 22:58:50 +0530 Subject: [PATCH 14/14] fix lint --- blsSignatures/blsSignatures.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/blsSignatures/blsSignatures.go b/blsSignatures/blsSignatures.go index b971df9918..2c5d15d66a 100644 --- a/blsSignatures/blsSignatures.go +++ b/blsSignatures/blsSignatures.go @@ -269,7 +269,10 @@ func PrivateKeyFromBytes(in []byte) (PrivateKey, error) { func SignatureToBytes(sig Signature) []byte { buf := new(bytes.Buffer) - bls12381.NewEncoder(buf).Encode(sig) + err := bls12381.NewEncoder(buf).Encode(sig) + if err != nil { + panic("failed to serialize signature") + } return buf.Bytes() }