diff --git a/crypto/bls/bls.go b/crypto/bls/bls.go index a97b020b0..d37d9e86f 100644 --- a/crypto/bls/bls.go +++ b/crypto/bls/bls.go @@ -1,38 +1,40 @@ package bls import ( - bls12381 "github.com/kilic/bls12-381" + bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" ) // set Ciphersuite for Basic mode // 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_") +var ( + dst = []byte("BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_") + gen2Aff bls12381.G2Affine + gen2Jac bls12381.G2Jac +) + +func init() { + _, gen2Jac, _, gen2Aff = bls12381.Generators() +} func SignatureAggregate(sigs ...*Signature) *Signature { if len(sigs) == 0 { return nil } - g1 := bls12381.NewG1() + g1 := new(bls12381.G1Affine) aggPointG1, err := sigs[0].PointG1() if err != nil { return nil } for i := 1; i < len(sigs); i++ { - s, err := sigs[i].PointG1() - if err != nil { - return nil - } - g1.Add( - &aggPointG1, - &aggPointG1, - &s) + pointG1, _ := sigs[i].PointG1() + aggPointG1 = g1.Add(aggPointG1, pointG1) } - data := g1.ToCompressed(&aggPointG1) + data := aggPointG1.Bytes() return &Signature{ - data: data, - pointG1: &aggPointG1, + data: data[:], + pointG1: aggPointG1, } } @@ -40,23 +42,20 @@ func PublicKeyAggregate(pubs ...*PublicKey) *PublicKey { if len(pubs) == 0 { return nil } - g2 := bls12381.NewG2() + g2 := new(bls12381.G2Affine) aggPointG2, err := pubs[0].PointG2() if err != nil { return nil } for i := 1; i < len(pubs); i++ { pointG2, _ := pubs[i].PointG2() - g2.Add( - &aggPointG2, - &aggPointG2, - &pointG2) + aggPointG2 = g2.Add(aggPointG2, pointG2) } - data := g2.ToCompressed(&aggPointG2) + data := aggPointG2.Bytes() return &PublicKey{ - data: data, - pointG2: &aggPointG2, + data: data[:], + pointG2: aggPointG2, } } diff --git a/crypto/bls/bls_bench_test.go b/crypto/bls/bls_bench_test.go index ff94d2d6c..b85c49251 100644 --- a/crypto/bls/bls_bench_test.go +++ b/crypto/bls/bls_bench_test.go @@ -11,10 +11,8 @@ func BenchmarkEncode(b *testing.B) { b.ReportAllocs() buf := make([]byte, bls.PrivateKeySize) - _, err := rand.Read(buf) - if err != nil { - b.Fatal(err) - } + _, _ = rand.Read(buf) + prv, _ := bls.PrivateKeyFromBytes(buf) pub := prv.PublicKeyNative() @@ -29,10 +27,8 @@ func BenchmarkDecodeSign(b *testing.B) { b.ReportAllocs() buf := make([]byte, bls.PrivateKeySize) - _, err := rand.Read(buf) - if err != nil { - b.Fatal(err) - } + _, _ = rand.Read(buf) + prv, _ := bls.PrivateKeyFromBytes(buf) bufMsg := []byte("pactus") sig := prv.Sign(bufMsg) @@ -41,10 +37,7 @@ func BenchmarkDecodeSign(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - _, err := bls.SignatureFromBytes(sigBytes) - if err != nil { - b.Fatal(err) - } + _, _ = bls.SignatureFromBytes(sigBytes) } } @@ -52,10 +45,7 @@ func BenchmarkVerify(b *testing.B) { b.ReportAllocs() buf := make([]byte, bls.PrivateKeySize) - _, err := rand.Read(buf) - if err != nil { - b.Fatal(err) - } + _, _ = rand.Read(buf) prv, _ := bls.PrivateKeyFromBytes(buf) pub := prv.PublicKeyNative() @@ -65,10 +55,7 @@ func BenchmarkVerify(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - err = pub.Verify(bufMsg, sig1) - if err != nil { - b.Fatal(err) - } + _ = pub.Verify(bufMsg, sig1) } } @@ -76,19 +63,13 @@ func BenchmarkDecode(b *testing.B) { b.ReportAllocs() buf := make([]byte, bls.PrivateKeySize) - _, err := rand.Read(buf) - if err != nil { - b.Fatal(err) - } + _, _ = rand.Read(buf) prv, _ := bls.PrivateKeyFromBytes(buf) pub := prv.PublicKeyNative() pubBytes := pub.Bytes() b.ResetTimer() for i := 0; i < b.N; i++ { - _, err := bls.PublicKeyFromBytes(pubBytes) - if err != nil { - b.Fatal(err) - } + _, _ = bls.PublicKeyFromBytes(pubBytes) } } diff --git a/crypto/bls/bls_test.go b/crypto/bls/bls_test.go index 9ea54f9ac..93542917d 100644 --- a/crypto/bls/bls_test.go +++ b/crypto/bls/bls_test.go @@ -4,11 +4,12 @@ import ( "encoding/hex" "testing" - bls12381 "github.com/kilic/bls12-381" + bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" "github.com/pactus-project/pactus/crypto" "github.com/pactus-project/pactus/crypto/bls" "github.com/pactus-project/pactus/util/testsuite" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestSigning(t *testing.T) { @@ -185,11 +186,14 @@ func TestHashToCurve(t *testing.T) { }, } - g1 := bls12381.NewG1() for no, test := range tests { - mappedPoint, _ := g1.HashToCurve([]byte(test.msg), domain) + mappedPoint, _ := bls12381.HashToG1([]byte(test.msg), domain) d, _ := hex.DecodeString(test.expected) - expectedPoint, _ := g1.FromBytes(d) + + expectedPoint := bls12381.G1Affine{} + err := expectedPoint.Unmarshal(d) + require.NoError(t, err) + assert.Equal(t, expectedPoint, mappedPoint, "test %v: not match", no) } diff --git a/crypto/bls/private_key.go b/crypto/bls/private_key.go index d965e2ba9..284d9b4f4 100644 --- a/crypto/bls/private_key.go +++ b/crypto/bls/private_key.go @@ -6,7 +6,8 @@ import ( "math/big" "strings" - bls12381 "github.com/kilic/bls12-381" + bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" + "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" "github.com/pactus-project/pactus/crypto" "github.com/pactus-project/pactus/util" "github.com/pactus-project/pactus/util/bech32m" @@ -18,7 +19,7 @@ var _ crypto.PrivateKey = &PrivateKey{} const PrivateKeySize = 32 type PrivateKey struct { - fr bls12381.Fr + scalar *big.Int } // PrivateKeyFromString decodes the input string and returns the PrivateKey @@ -65,8 +66,6 @@ func KeyGen(ikm, keyInfo []byte) (*PrivateKey, error) { pseudoRandomKey = append(pseudoRandomKey, keyInfo...) pseudoRandomKey = append(pseudoRandomKey, util.I2OSP(big.NewInt(l), 2)...) - g1 := bls12381.NewG1() - salt := []byte("BLS-SIG-KEYGEN-SALT-") x := big.NewInt(0) for x.Sign() == 0 { @@ -78,7 +77,7 @@ func KeyGen(ikm, keyInfo []byte) (*PrivateKey, error) { reader := hkdf.Expand(sha256.New, prk, pseudoRandomKey) _, _ = reader.Read(okm) - r := g1.Q() + r := fr.Modulus() x = new(big.Int).Mod(util.OS2IP(okm), r) } @@ -94,13 +93,10 @@ func PrivateKeyFromBytes(data []byte) (*PrivateKey, error) { return nil, crypto.InvalidLengthError(len(data)) } - fr := bls12381.NewFr() - fr.FromBytes(data) - if fr.IsZero() { - return nil, crypto.ErrInvalidPrivateKey - } + scalar := new(big.Int) + scalar = scalar.SetBytes(data) - return &PrivateKey{fr: *fr}, nil + return &PrivateKey{scalar: scalar}, nil } // String returns a human-readable string for the BLS private key. @@ -115,7 +111,10 @@ func (prv *PrivateKey) String() string { // Bytes return the raw bytes of the private key. func (prv *PrivateKey) Bytes() []byte { - return prv.fr.ToBytes() + data := prv.scalar.Bytes() + data = util.Extend(data, PrivateKeySize) + + return data } // Sign calculates the signature from the private key and given message. @@ -125,30 +124,29 @@ func (prv *PrivateKey) Sign(msg []byte) crypto.Signature { } func (prv *PrivateKey) SignNative(msg []byte) *Signature { - g1 := bls12381.NewG1() - - q, err := g1.HashToCurve(msg, dst) + qAffine, err := bls12381.HashToG1(msg, dst) if err != nil { panic(err) } - pointG1 := g1.MulScalar(g1.New(), q, &prv.fr) - data := g1.ToCompressed(pointG1) + qJac := new(bls12381.G1Jac).FromAffine(&qAffine) + sigJac := qJac.ScalarMultiplication(qJac, prv.scalar) + sigAffine := new(bls12381.G1Affine).FromJacobian(sigJac) + data := sigAffine.Bytes() return &Signature{ - data: data, - pointG1: pointG1, + data: data[:], + pointG1: sigAffine, } } func (prv *PrivateKey) PublicKeyNative() *PublicKey { - g2 := bls12381.NewG2() - - pointG2 := g2.MulScalar(g2.New(), g2.One(), &prv.fr) - data := g2.ToCompressed(pointG2) + pkJac := new(bls12381.G2Jac).ScalarMultiplication(&gen2Jac, prv.scalar) + pkAffine := new(bls12381.G2Affine).FromJacobian(pkJac) + data := pkAffine.Bytes() return &PublicKey{ - data: data, - pointG2: pointG2, + data: data[:], + pointG2: pkAffine, } } @@ -162,5 +160,5 @@ func (prv *PrivateKey) EqualsTo(x crypto.PrivateKey) bool { return false } - return prv.fr.Equal(&xBLS.fr) + return prv.scalar.Cmp(xBLS.scalar) == 0 } diff --git a/crypto/bls/private_key_test.go b/crypto/bls/private_key_test.go index 45d7e0c0a..6e2e756e5 100644 --- a/crypto/bls/private_key_test.go +++ b/crypto/bls/private_key_test.go @@ -49,11 +49,6 @@ func TestPrivateKeyFromString(t *testing.T) { "SECRET1HPZZU9", false, nil, }, - { - "invalid private key", - "SECRET1PQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQSK004X", - false, nil, - }, { "invalid HRP: xxx", "XXX1PDRWTLP5PX0FAHDX39GXZJP7FKZFALML0D5U9TT9KVQHDUC99CMGQMUUMJT", diff --git a/crypto/bls/public_key.go b/crypto/bls/public_key.go index 64adb3fe2..1d51e1e3c 100644 --- a/crypto/bls/public_key.go +++ b/crypto/bls/public_key.go @@ -3,11 +3,10 @@ package bls import ( "bytes" "crypto/subtle" - "fmt" "io" + bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" cbor "github.com/fxamacker/cbor/v2" - bls12381 "github.com/kilic/bls12-381" "github.com/pactus-project/pactus/crypto" "github.com/pactus-project/pactus/crypto/hash" "github.com/pactus-project/pactus/util/bech32m" @@ -19,8 +18,8 @@ var _ crypto.PublicKey = &PublicKey{} const PublicKeySize = 96 type PublicKey struct { - pointG2 *bls12381.PointG2 // Lazily initialized point on G2. - data []byte // Raw public key data. + pointG2 *bls12381.G2Affine // Lazily initialized point on G2. + data []byte // Raw public key data. } // PublicKeyFromString decodes the input string and returns the PublicKey @@ -108,8 +107,6 @@ func (pub *PublicKey) Verify(msg []byte, sig crypto.Signature) error { if sig == nil { return crypto.ErrInvalidPublicKey } - g1 := bls12381.NewG1() - g2 := bls12381.NewG2() r := sig.(*Signature) pointG1, err := r.PointG1() @@ -120,17 +117,19 @@ func (pub *PublicKey) Verify(msg []byte, sig crypto.Signature) error { if err != nil { return err } - q, err := g1.HashToCurve(msg, dst) + qAffine, err := bls12381.HashToG1(msg, dst) if err != nil { - return err + panic(err) } - g2one := g2.New().Set(&bls12381.G2One) - eng := bls12381.NewEngine() - eng.AddPair(q, &pointG2) - eng.AddPairInv(&pointG1, g2one) + var negP bls12381.G2Affine + negP.Neg(&gen2Aff) + + check, _ := bls12381.PairingCheck( + []bls12381.G1Affine{qAffine, *pointG1}, + []bls12381.G2Affine{*pointG2, negP}) - if !eng.Check() { + if !check { return crypto.ErrInvalidSignature } @@ -185,21 +184,21 @@ func (pub *PublicKey) VerifyAddress(addr crypto.Address) error { } // PointG2 returns the point on G2 for the public key. -func (pub *PublicKey) PointG2() (bls12381.PointG2, error) { +func (pub *PublicKey) PointG2() (*bls12381.G2Affine, error) { if pub.pointG2 != nil { - return *pub.pointG2, nil + return pub.pointG2, nil } - g2 := bls12381.NewG2() - pointG2, err := g2.FromCompressed(pub.data) + g2Aff := new(bls12381.G2Affine) + err := g2Aff.Unmarshal(pub.data) if err != nil { - return bls12381.PointG2{}, err + return nil, err } - if g2.IsZero(pointG2) { - return bls12381.PointG2{}, fmt.Errorf("public key is zero") + if g2Aff.IsInfinity() || !g2Aff.IsInSubGroup() { + return nil, crypto.ErrInvalidPublicKey } - pub.pointG2 = pointG2 + pub.pointG2 = g2Aff - return *pointG2, nil + return g2Aff, nil } diff --git a/crypto/bls/public_key_test.go b/crypto/bls/public_key_test.go index 802481b1a..9db4051f1 100644 --- a/crypto/bls/public_key_test.go +++ b/crypto/bls/public_key_test.go @@ -194,19 +194,19 @@ func TestPointG2(t *testing.T) { valid bool }{ { - "compression flag must be set", + "short buffer", "public1pqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq" + "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqjzu9w8", false, }, { - "input string must be zero when infinity flag is set", + "invalid point encoding", "public1pllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll" + "llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllluhpuzyf", false, }, { - "public key is zero", + "invalid public key", "public1pcqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq" + "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqglnhh9", false, diff --git a/crypto/bls/signature.go b/crypto/bls/signature.go index 7e47a98bd..a7c6519bc 100644 --- a/crypto/bls/signature.go +++ b/crypto/bls/signature.go @@ -4,11 +4,10 @@ import ( "bytes" "crypto/subtle" "encoding/hex" - "fmt" "io" + bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" cbor "github.com/fxamacker/cbor/v2" - bls12381 "github.com/kilic/bls12-381" "github.com/pactus-project/pactus/crypto" "github.com/pactus-project/pactus/util/encoding" ) @@ -18,8 +17,8 @@ var _ crypto.Signature = &Signature{} const SignatureSize = 48 type Signature struct { - pointG1 *bls12381.PointG1 // Lazily initialized point on G1. - data []byte // Raw signature data. + pointG1 *bls12381.G1Affine // Lazily initialized point on G1. + data []byte // Raw signature data. } // SignatureFromString decodes the input string and returns the Signature @@ -97,21 +96,21 @@ func (sig *Signature) EqualsTo(x crypto.Signature) bool { } // PointG1 returns the point on G1 for the signature. -func (sig *Signature) PointG1() (bls12381.PointG1, error) { +func (sig *Signature) PointG1() (*bls12381.G1Affine, error) { if sig.pointG1 != nil { - return *sig.pointG1, nil + return sig.pointG1, nil } - g1 := bls12381.NewG1() - pointG1, err := g1.FromCompressed(sig.data) + g1Aff := new(bls12381.G1Affine) + err := g1Aff.Unmarshal(sig.data) if err != nil { - return bls12381.PointG1{}, err + return nil, err } - if g1.IsZero(pointG1) { - return bls12381.PointG1{}, fmt.Errorf("signature is zero") + if g1Aff.IsInfinity() || !g1Aff.IsInSubGroup() { + return nil, crypto.ErrInvalidPublicKey } - sig.pointG1 = pointG1 + sig.pointG1 = g1Aff - return *pointG1, nil + return g1Aff, nil } diff --git a/crypto/bls/signature_test.go b/crypto/bls/signature_test.go index ded6c1354..ce65172c3 100644 --- a/crypto/bls/signature_test.go +++ b/crypto/bls/signature_test.go @@ -146,17 +146,17 @@ func TestPointG1(t *testing.T) { valid bool }{ { - "compression flag must be set", + "short buffer", "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", false, }, { - "input string must be zero when infinity flag is set", + "invalid point encoding", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", false, }, { - "signature is zero", + "invalid public key", "c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", false, }, diff --git a/crypto/errors.go b/crypto/errors.go index b89736968..d7fed09b4 100644 --- a/crypto/errors.go +++ b/crypto/errors.go @@ -8,9 +8,6 @@ import ( // ErrInvalidSignature is returned when a signature is invalid. var ErrInvalidSignature = errors.New("invalid signature") -// ErrInvalidPrivateKey is returned when a private key is invalid. -var ErrInvalidPrivateKey = errors.New("invalid private key") - // ErrInvalidPublicKey is returned when a public key is invalid. var ErrInvalidPublicKey = errors.New("invalid public key") diff --git a/go.mod b/go.mod index 57b153ce2..c6c84215d 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/NathanBaulch/protoc-gen-cobra v1.2.1 github.com/beevik/ntp v1.4.3 github.com/c-bata/go-prompt v0.2.6 + github.com/consensys/gnark-crypto v0.14.0 github.com/fxamacker/cbor/v2 v2.7.0 github.com/gofrs/flock v0.12.1 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 @@ -48,8 +49,10 @@ require ( github.com/Microsoft/go-winio v0.6.2 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/bits-and-blooms/bitset v1.14.2 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chzyer/readline v1.5.1 // indirect + github.com/consensys/bavard v0.1.13 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/creachadair/jrpc2 v1.2.1 // indirect @@ -112,6 +115,7 @@ require ( github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect @@ -178,4 +182,5 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.3.0 // indirect + rsc.io/tmplfunc v0.0.3 // indirect ) diff --git a/go.sum b/go.sum index cc9cf6696..e77ebcce7 100644 --- a/go.sum +++ b/go.sum @@ -23,6 +23,8 @@ github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZx github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bits-and-blooms/bitset v1.14.2 h1:YXVoyPndbdvcEVcseEovVfp0qjJp7S+i5+xgp/Nfbdc= +github.com/bits-and-blooms/bitset v1.14.2/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/c-bata/go-prompt v0.2.6 h1:POP+nrHE+DfLYx370bedwNhsqmpCUynWPxuHi0C5vZI= @@ -44,6 +46,10 @@ github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38 github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= +github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= +github.com/consensys/gnark-crypto v0.14.0 h1:DDBdl4HaBtdQsq/wfMwJvZNE80sHidrK3Nfrefatm0E= +github.com/consensys/gnark-crypto v0.14.0/go.mod h1:CU4UijNPsHawiVGNxe9co07FkzCeWHHrb1li/n1XoU0= github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= @@ -169,6 +175,7 @@ github.com/google/pprof v0.0.0-20240925223930-fa3061bff0bc h1:7bf8bGo4akhLJrmttk github.com/google/pprof v0.0.0-20240925223930-fa3061bff0bc/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -267,6 +274,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4= +github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= @@ -346,6 +355,9 @@ github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2Em github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= +github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= +github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= @@ -857,5 +869,7 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= +rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= +rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/util/slice.go b/util/slice.go index 4d80eae42..2f11a3b1c 100644 --- a/util/slice.go +++ b/util/slice.go @@ -196,11 +196,13 @@ func Reverse[S ~[]E, E any](s S) { } // Extend extends the slice 's' to length 'n' by appending zero-valued elements. -func Extend[T any](s *[]T, n int) { - if len(*s) < n { - temp := make([]T, n-len(*s)) - *s = append(*s, temp...) +func Extend[T any](s []T, n int) []T { + if len(s) < n { + pad := make([]T, n-len(s), n+len(s)) + s = append(pad, s...) } + + return s } // IsSubset checks if subSet is a subset of parentSet. diff --git a/util/slice_test.go b/util/slice_test.go index ef88c8b72..616aeba78 100644 --- a/util/slice_test.go +++ b/util/slice_test.go @@ -228,7 +228,7 @@ func TestExtendSlice(t *testing.T) { size int want []int }{ - {[]int{1, 2, 3}, 5, []int{1, 2, 3, 0, 0}}, + {[]int{1, 2, 3}, 5, []int{0, 0, 1, 2, 3}}, {[]int{1, 2, 3}, 3, []int{1, 2, 3}}, {[]int{1, 2, 3}, 2, []int{1, 2, 3}}, {[]int{}, 5, []int{0, 0, 0, 0, 0}}, @@ -236,7 +236,7 @@ func TestExtendSlice(t *testing.T) { for _, c := range cases { inCopy := c.in - Extend(&inCopy, c.size) + inCopy = Extend(inCopy, c.size) assert.Equal(t, c.want, inCopy, "ExtendSlice(%v, %v) == %v, want %v", c.in, c.size, c.in, c.want) } }