diff --git a/go.mod b/go.mod index 1ff7c44db..dc26dd18d 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/DATA-DOG/go-sqlmock v1.5.2 github.com/IBM/idemix v0.0.2-0.20250313153527-832db18b9478 github.com/IBM/idemix/bccsp/types v0.0.0-20250313153527-832db18b9478 - github.com/IBM/mathlib v0.0.3-0.20251201181318-11a3ec7f764f + github.com/IBM/mathlib v0.0.3-0.20251211174534-08690b7c5cc8 github.com/dgraph-io/ristretto/v2 v2.3.0 github.com/gin-gonic/gin v1.10.0 github.com/hashicorp/go-uuid v1.0.3 @@ -27,7 +27,7 @@ require ( github.com/sourcegraph/conc v0.3.0 github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.20.1 - github.com/stretchr/testify v1.10.0 + github.com/stretchr/testify v1.11.1 github.com/tedsuo/ifrit v0.0.0-20230516164442-7862c310ad26 github.com/test-go/testify v1.1.4 github.com/thedevsaddam/gojsonq v2.3.0+incompatible @@ -76,7 +76,7 @@ require ( github.com/cockroachdb/errors v1.12.0 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/redact v1.1.5 // indirect - github.com/consensys/gnark-crypto v0.18.1 // indirect + github.com/consensys/gnark-crypto v0.19.2 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/containerd/errdefs v1.0.0 // indirect github.com/containerd/errdefs/pkg v0.3.0 // indirect diff --git a/go.sum b/go.sum index 40f4bf9e8..9c2353b8f 100644 --- a/go.sum +++ b/go.sum @@ -650,8 +650,8 @@ github.com/IBM/idemix/bccsp/schemes/weak-bb v0.0.0-20250313153527-832db18b9478 h github.com/IBM/idemix/bccsp/schemes/weak-bb v0.0.0-20250313153527-832db18b9478/go.mod h1:k4Q5EYKRnYC6t80ipSCY3G8H4FdcxRa8jjlsJdGfNCY= github.com/IBM/idemix/bccsp/types v0.0.0-20250313153527-832db18b9478 h1:Uzmcb4pNb54/fbAjnrZTiJwWV74+twP60N4qBGm4PvU= github.com/IBM/idemix/bccsp/types v0.0.0-20250313153527-832db18b9478/go.mod h1:Pi1QIuIZ+1OXIbnYe27vNwJOnSq2WvkHRT/sfweTw8E= -github.com/IBM/mathlib v0.0.3-0.20251201181318-11a3ec7f764f h1:UyHWQt3a/XrM8u/x6KukEzyTABzfeVLZJn40hIIclsM= -github.com/IBM/mathlib v0.0.3-0.20251201181318-11a3ec7f764f/go.mod h1:O230ebw6/22B7T4C03b99ZcPtc5XAfBTOp+ZT+xmMCk= +github.com/IBM/mathlib v0.0.3-0.20251211174534-08690b7c5cc8 h1:nhdZWnVNu1DBVtjGLs472DryJKhKCxiLd883g94xUts= +github.com/IBM/mathlib v0.0.3-0.20251211174534-08690b7c5cc8/go.mod h1:rq67W1H6L1eorrE7DZ/HcSY/pfMDjbPWOx12SeUfQDk= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= @@ -736,8 +736,8 @@ github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZe github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= -github.com/consensys/gnark-crypto v0.18.1 h1:RyLV6UhPRoYYzaFnPQA4qK3DyuDgkTgskDdoGqFt3fI= -github.com/consensys/gnark-crypto v0.18.1/go.mod h1:L3mXGFTe1ZN+RSJ+CLjUt9x7PNdx8ubaYfDROyp2Z8c= +github.com/consensys/gnark-crypto v0.19.2 h1:qrEAIXq3T4egxqiliFFoNrepkIWVEeIYwt3UL0fvS80= +github.com/consensys/gnark-crypto v0.19.2/go.mod h1:rT23F0XSZqE0mUA0+pRtnL56IbPxs6gp4CeRsBk4XS0= 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= @@ -1532,8 +1532,8 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/sykesm/zap-logfmt v0.0.4 h1:U2WzRvmIWG1wDLCFY3sz8UeEmsdHQjHFNlIdmroVFaI= diff --git a/token/core/common/crypto/math/curves.go b/token/core/common/crypto/math/curves.go index 8f36e4939..591b30057 100644 --- a/token/core/common/crypto/math/curves.go +++ b/token/core/common/crypto/math/curves.go @@ -12,7 +12,7 @@ import ( math "github.com/IBM/mathlib" "github.com/IBM/mathlib/driver" - "github.com/IBM/mathlib/driver/gurvy" + "github.com/IBM/mathlib/driver/gurvy/bls12381" "github.com/hyperledger-labs/fabric-token-sdk/token/core/common/crypto/rng" ) @@ -22,20 +22,23 @@ var ( func init() { BLS12_381_BBS_GURVY_FAST_RNG = math.CurveID(len(math.Curves)) - math.Curves = append(math.Curves, math.NewCurve( - NewCurveWithFastRNG(gurvy.NewBls12_381BBS()), - math.NewG1(gurvy.NewBls12_381BBS().GenG1(), BLS12_381_BBS_GURVY_FAST_RNG), - math.NewG2(gurvy.NewBls12_381BBS().GenG2(), BLS12_381_BBS_GURVY_FAST_RNG), - math.NewGt(gurvy.NewBls12_381BBS().GenGt(), BLS12_381_BBS_GURVY_FAST_RNG), - math.NewZr(gurvy.NewBls12_381().GroupOrder(), BLS12_381_BBS_GURVY_FAST_RNG), - gurvy.NewBls12_381BBS().CoordinateByteSize(), - gurvy.NewBls12_381BBS().G1ByteSize(), - gurvy.NewBls12_381BBS().CompressedG1ByteSize(), - gurvy.NewBls12_381BBS().G2ByteSize(), - gurvy.NewBls12_381BBS().CompressedG2ByteSize(), - gurvy.NewBls12_381BBS().ScalarByteSize(), - BLS12_381_BBS_GURVY_FAST_RNG, - )) + math.Curves = append( + math.Curves, + math.NewCurve( + NewCurveWithFastRNG(bls12381.NewBBSCurve()), + math.NewG1(bls12381.NewBBSCurve().GenG1(), BLS12_381_BBS_GURVY_FAST_RNG), + math.NewG2(bls12381.NewBBSCurve().GenG2(), BLS12_381_BBS_GURVY_FAST_RNG), + math.NewGt(bls12381.NewBBSCurve().GenGt(), BLS12_381_BBS_GURVY_FAST_RNG), + math.NewZr(bls12381.NewCurve().GroupOrder(), BLS12_381_BBS_GURVY_FAST_RNG), + bls12381.NewBBSCurve().CoordinateByteSize(), + bls12381.NewBBSCurve().G1ByteSize(), + bls12381.NewBBSCurve().CompressedG1ByteSize(), + bls12381.NewBBSCurve().G2ByteSize(), + bls12381.NewBBSCurve().CompressedG2ByteSize(), + bls12381.NewBBSCurve().ScalarByteSize(), + BLS12_381_BBS_GURVY_FAST_RNG, + ), + ) } type CurveWithFastRNG struct { diff --git a/token/core/common/crypto/slice.go b/token/core/common/crypto/slice.go new file mode 100644 index 000000000..6a2a183cc --- /dev/null +++ b/token/core/common/crypto/slice.go @@ -0,0 +1,41 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package crypto + +import "encoding/binary" + +// AppendFixed32 appends slices prefixed with a 4-byte Little Endian length. +// Format: [Len(4 bytes)][Data]... +func AppendFixed32(dst []byte, s [][]byte) []byte { + // 1. Precise Size Calculation + // We calculate the exact total growth needed (4 bytes header + data length per slice). + // This allows us to perform exactly one allocation. + const headerSize = 4 + n := 0 + for _, v := range s { + n += headerSize + len(v) + } + + // 2. Single Growth / Allocation + // If the capacity is insufficient, we grow the slice exactly once. + // This avoids the 2x growth strategy of standard append(), saving + // potentially 25-50% memory overhead on large buffers. + if cap(dst)-len(dst) < n { + newDst := make([]byte, len(dst), len(dst)+n) + copy(newDst, dst) + dst = newDst + } + + // 3. Append Loop (Branch-free) + for _, v := range s { + // AppendUint32 is inlinable and highly optimized in Go 1.19+ [web:22] + dst = binary.LittleEndian.AppendUint32(dst, uint32(len(v))) + dst = append(dst, v...) + } + + return dst +} diff --git a/token/core/common/crypto/slice_test.go b/token/core/common/crypto/slice_test.go new file mode 100644 index 000000000..88a766962 --- /dev/null +++ b/token/core/common/crypto/slice_test.go @@ -0,0 +1,120 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package crypto + +import ( + "bytes" + "encoding/binary" + "testing" + + "github.com/stretchr/testify/assert" +) + +// Unit Test: Verifies correct Little Endian encoding and data integrity +func TestAppendFixed32(t *testing.T) { + tests := []struct { + name string + input [][]byte + expected []byte + }{ + { + name: "Basic Join", + input: [][]byte{ + []byte("Go"), + []byte("Lang"), + }, + // Expect: [Len:2][G][o] [Len:4][L][a][n][g] + // Little Endian 2: 0x02, 0x00, 0x00, 0x00 + expected: []byte{ + 0x02, 0x00, 0x00, 0x00, 'G', 'o', + 0x04, 0x00, 0x00, 0x00, 'L', 'a', 'n', 'g', + }, + }, + { + name: "Empty Input", + input: [][]byte{}, + expected: nil, // Or empty slice depending on init + }, + { + name: "Contains Empty Slice", + input: [][]byte{ + []byte("Hi"), + {}, + }, + // Expect: [Len:2][H][i] [Len:0] + expected: []byte{ + 0x02, 0x00, 0x00, 0x00, 'H', 'i', + 0x00, 0x00, 0x00, 0x00, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Using nil as dst to force new allocation + result := AppendFixed32(nil, tt.input) + assert.Equal(t, tt.expected, result) + }) + } +} + +// Verification Test: Reusing an existing buffer +func TestAppendFixed32_ReuseBuffer(t *testing.T) { + buffer := make([]byte, 0, 1024) + buffer = append(buffer, 0xFF) // Simulating existing data (dirty buffer) + + input := [][]byte{[]byte("A")} + result := AppendFixed32(buffer, input) + + // Check that we didn't lose the prefix 0xFF + assert.Equal(t, byte(0xFF), result[0]) + // Check the new data starts at index 1 + // Len: 1 (0x01 00 00 00) + 'A' + expectedPayload := []byte{0x01, 0x00, 0x00, 0x00, 'A'} + assert.Equal(t, expectedPayload, result[1:]) +} + +// --- Benchmarks --- + +// Setup helper for benchmarks +func generateBenchmarkData(count, size int) [][]byte { + data := make([][]byte, count) + for i := 0; i < count; i++ { + data[i] = bytes.Repeat([]byte{'a'}, size) + } + return data +} + +// Optimized Approach +func BenchmarkAppendFixed32(b *testing.B) { + // Scenario: 1000 items, 256 bytes each (~250KB total) + data := generateBenchmarkData(1000, 256) + + b.ReportAllocs() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + // Use nil to strictly measure allocation of the result + _ = AppendFixed32(nil, data) + } +} + +// Comparison: Naive Loop (No pre-calculation) +func BenchmarkAppendFixed32_Naive(b *testing.B) { + data := generateBenchmarkData(1000, 256) + + b.ReportAllocs() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + var dst []byte + for _, v := range data { + dst = binary.LittleEndian.AppendUint32(dst, uint32(len(v))) + dst = append(dst, v...) + } + } +} diff --git a/token/core/zkatdlog/nogh/v1/crypto/common/array.go b/token/core/zkatdlog/nogh/v1/crypto/common/array.go index a86add8fa..22ec2ab2f 100644 --- a/token/core/zkatdlog/nogh/v1/crypto/common/array.go +++ b/token/core/zkatdlog/nogh/v1/crypto/common/array.go @@ -7,11 +7,11 @@ SPDX-License-Identifier: Apache-2.0 package common import ( - "bytes" - "encoding/hex" + "hash" math "github.com/IBM/mathlib" "github.com/hyperledger-labs/fabric-smart-client/pkg/utils/errors" + "github.com/hyperledger-labs/fabric-token-sdk/token/core/common/crypto" ) // Separator is used to delimit to end an array of bytes. @@ -28,11 +28,21 @@ func (a *G1Array) Bytes() ([]byte, error) { if e == nil { return nil, errors.Errorf("failed to marshal array of G1") } - st := hex.EncodeToString(e.Bytes()) - raw[i] = []byte(st) + raw[i] = e.Bytes() } - // join the serialization of the group elements with the predefined separator. - return bytes.Join(raw, []byte(Separator)), nil + return crypto.AppendFixed32([]byte{}, raw), nil +} + +func (a *G1Array) BytesTo(b []byte) ([]byte, error) { + raw := make([][]byte, len([]*math.G1(*a))) + for i, e := range []*math.G1(*a) { + if e == nil { + return nil, errors.Errorf("failed to marshal array of G1") + } + raw[i] = e.Bytes() + } + clear(b) + return crypto.AppendFixed32(b, raw), nil } // GetG1Array takes a series of G1 elements and returns the corresponding array @@ -44,3 +54,12 @@ func GetG1Array(elements ...[]*math.G1) *G1Array { a := G1Array(array) return &a } + +func HashG1Array(h hash.Hash, elements ...*math.G1) []byte { + h.Reset() + + for _, e := range elements { + h.Write(e.Bytes()) + } + return h.Sum(nil) +} diff --git a/token/core/zkatdlog/nogh/v1/crypto/rp/bulletproof.go b/token/core/zkatdlog/nogh/v1/crypto/rp/bulletproof.go index 9025ba754..4cf8be7a1 100644 --- a/token/core/zkatdlog/nogh/v1/crypto/rp/bulletproof.go +++ b/token/core/zkatdlog/nogh/v1/crypto/rp/bulletproof.go @@ -241,7 +241,7 @@ func (p *rangeProver) Prove() (*RangeProof, error) { } // compute the commitment to left and right com := commitVector(left, right, p.LeftGenerators, rightGeneratorsPrime, p.Curve) - rp.Data.InnerProduct = innerProduct(left, right, p.Curve) + rp.Data.InnerProduct = InnerProduct(left, right, p.Curve) // produce the IPA ipp := NewIPAProver( rp.Data.InnerProduct, @@ -275,6 +275,8 @@ func (p *rangeProver) preprocess() ([]*math.Zr, []*math.Zr, *math.Zr, *RangeProo } rho := p.Curve.NewRandomZr(rand) eta := p.Curve.NewRandomZr(rand) + one := p.Curve.NewZrFromInt(1) + two := p.Curve.NewZrFromInt(2) for i := range p.BitLength { b := 1 << i & p.value if b > 0 { @@ -283,7 +285,7 @@ func (p *rangeProver) preprocess() ([]*math.Zr, []*math.Zr, *math.Zr, *RangeProo // this is an array of the bits b_i of p.value left[i] = p.Curve.NewZrFromUint64(b) // this is an array of b_i - 1 - right[i] = p.Curve.ModSub(left[i], p.Curve.NewZrFromInt(1), p.Curve.GroupOrder) + right[i] = p.Curve.ModSub(left[i], one, p.Curve.GroupOrder) // these are randomly generated arrays randomLeft[i] = p.Curve.NewRandomZr(rand) randomRight[i] = p.Curve.NewRandomZr(rand) @@ -315,7 +317,7 @@ func (p *rangeProver) preprocess() ([]*math.Zr, []*math.Zr, *math.Zr, *RangeProo zPrime := make([]*math.Zr, len(left)) // z^2 - zSquare := z.PowMod(p.Curve.NewZrFromInt(2)) + zSquare := z.PowMod(two) var y2i *math.Zr for i := range left { // compute L_i - z @@ -324,7 +326,7 @@ func (p *rangeProver) preprocess() ([]*math.Zr, []*math.Zr, *math.Zr, *RangeProo rightPrime[i] = p.Curve.ModAdd(right[i], z, p.Curve.GroupOrder) // compute y^i if i == 0 { - y2i = p.Curve.NewZrFromInt(1) + y2i = one } else { y2i = p.Curve.ModMul(y, y2i, p.Curve.GroupOrder) } @@ -333,26 +335,24 @@ func (p *rangeProver) preprocess() ([]*math.Zr, []*math.Zr, *math.Zr, *RangeProo // compute V_iy^i randRightPrime[i] = p.Curve.ModMul(randomRight[i], y2i, p.Curve.GroupOrder) // compute 2^iz^2 - zPrime[i] = p.Curve.ModMul(zSquare, p.Curve.NewZrFromInt(2).PowMod(p.Curve.NewZrFromInt(int64(i))), p.Curve.GroupOrder) + zPrime[i] = p.Curve.ModMul(zSquare, two.PowMod(p.Curve.NewZrFromInt(int64(i))), p.Curve.GroupOrder) } // compute \sum y^iV_i(L_i-z) - t1 := innerProduct(leftPrime, randRightPrime, p.Curve) + t1 := InnerProduct(leftPrime, randRightPrime, p.Curve) // compute \sum y^i(V_i(L_i-z) + (R_i +z)U_i) - t1 = p.Curve.ModAdd(t1, innerProduct(rightPrime, randomLeft, p.Curve), p.Curve.GroupOrder) + t1 = p.Curve.ModAdd(t1, InnerProduct(rightPrime, randomLeft, p.Curve), p.Curve.GroupOrder) // compute \sum y^i(V_i(L_i-z) + (R_i+z)U_i) + U_i2^iz^2 - t1 = p.Curve.ModAdd(t1, innerProduct(zPrime, randomLeft, p.Curve), p.Curve.GroupOrder) + t1 = p.Curve.ModAdd(t1, InnerProduct(zPrime, randomLeft, p.Curve), p.Curve.GroupOrder) // commit to t1 tau1 := p.Curve.NewRandomZr(rand) - T1 := p.CommitmentGenerators[0].Mul(t1) - T1.Add(p.CommitmentGenerators[1].Mul(tau1)) + T1 := p.CommitmentGenerators[0].Mul2(t1, p.CommitmentGenerators[1], tau1) // compute = \sum y^iU_iV_i - t2 := innerProduct(randomLeft, randRightPrime, p.Curve) + t2 := InnerProduct(randomLeft, randRightPrime, p.Curve) // commit to t2 tau2 := p.Curve.NewRandomZr(rand) - T2 := p.CommitmentGenerators[0].Mul(t2) - T2.Add(p.CommitmentGenerators[1].Mul(tau2)) + T2 := p.CommitmentGenerators[0].Mul2(t2, p.CommitmentGenerators[1], tau2) // compute challenge x array = common.GetG1Array([]*math.G1{T1, T2}) @@ -368,14 +368,14 @@ func (p *rangeProver) preprocess() ([]*math.Zr, []*math.Zr, *math.Zr, *RangeProo // f(z, y) = \sum (z-z^2)*y^i - z^3*2^i for i := 0; i < len(left); i++ { // compute (L_i-z) + xU_i - left[i] = p.Curve.ModAdd(leftPrime[i], p.Curve.ModMul(x, randomLeft[i], p.Curve.GroupOrder), p.Curve.GroupOrder) + left[i] = p.Curve.ModAddMul2(leftPrime[i], one, x, randomLeft[i], p.Curve.GroupOrder) // compute y^i((R_i+z)+xV_i)+2^iz^2 right[i] = p.Curve.ModAdd(rightPrime[i], p.Curve.ModMul(x, randRightPrime[i], p.Curve.GroupOrder), p.Curve.GroupOrder) right[i] = p.Curve.ModAdd(right[i], zPrime[i], p.Curve.GroupOrder) } // tau = t1x + t2x^2 + z^2p.blindingFactor tau := p.Curve.ModMul(x, tau1, p.Curve.GroupOrder) - tau = p.Curve.ModAdd(tau, p.Curve.ModMul(tau2, x.PowMod(p.Curve.NewZrFromInt(2)), p.Curve.GroupOrder), p.Curve.GroupOrder) + tau = p.Curve.ModAdd(tau, p.Curve.ModMul(tau2, x.PowMod(two), p.Curve.GroupOrder), p.Curve.GroupOrder) tau = p.Curve.ModAdd(tau, p.Curve.ModMul(zSquare, p.blindingFactor, p.Curve.GroupOrder), p.Curve.GroupOrder) // delta = rho + eta*x diff --git a/token/core/zkatdlog/nogh/v1/crypto/rp/bulletproof_test.go b/token/core/zkatdlog/nogh/v1/crypto/rp/bulletproof_test.go index 34791535f..4eb753012 100644 --- a/token/core/zkatdlog/nogh/v1/crypto/rp/bulletproof_test.go +++ b/token/core/zkatdlog/nogh/v1/crypto/rp/bulletproof_test.go @@ -7,23 +7,43 @@ SPDX-License-Identifier: Apache-2.0 package rp_test import ( + "math/bits" + "math/rand" "strconv" "testing" math "github.com/IBM/mathlib" + "github.com/hyperledger-labs/fabric-smart-client/node/start/profile" "github.com/hyperledger-labs/fabric-token-sdk/token/core/zkatdlog/nogh/v1/crypto/rp" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) -func TestBFProofVerify(t *testing.T) { - curve := math.Curves[1] - nr := uint64(3) - l := uint64(1 << nr) +type bfSetup struct { + com *math.G1 + Q *math.G1 + P *math.G1 + H *math.G1 + G *math.G1 + bf *math.Zr + leftGens []*math.G1 + rightGens []*math.G1 + nr uint64 + l uint64 + curve *math.Curve +} + +func NewBfSetup(curveID math.CurveID) (*bfSetup, error) { + curve := math.Curves[curveID] + l := uint64(64) + nr := 63 - uint64(bits.LeadingZeros64(l)) leftGens := make([]*math.G1, l) rightGens := make([]*math.G1, l) rand, err := curve.Rand() - assert.NoError(t, err) + if err != nil { + return nil, err + } Q := curve.GenG1.Mul(curve.NewRandomZr(rand)) P := curve.GenG1.Mul(curve.NewRandomZr(rand)) @@ -36,12 +56,89 @@ func TestBFProofVerify(t *testing.T) { bf := curve.NewRandomZr(rand) com := G.Mul(curve.NewZrFromInt(115)) com.Add(H.Mul(bf)) - prover := rp.NewRangeProver(com, 115, []*math.G1{G, H}, bf, leftGens, rightGens, P, Q, nr, l, curve) - verifier := rp.NewRangeVerifier(com, []*math.G1{G, H}, leftGens, rightGens, P, Q, nr, l, curve) + return &bfSetup{ + com: com, + Q: Q, + P: P, + H: H, + G: G, + bf: bf, + leftGens: leftGens, + rightGens: rightGens, + nr: nr, + l: l, + curve: curve, + }, nil +} + +func TestBFProofVerify(t *testing.T) { + setup, err := NewBfSetup(math.BLS12_381_BBS_GURVY) + require.NoError(t, err) + + prover := rp.NewRangeProver( + setup.com, + 115, + []*math.G1{setup.G, setup.H}, + setup.bf, + setup.leftGens, + setup.rightGens, + setup.P, + setup.Q, + setup.nr, + setup.l, + setup.curve, + ) proof, err := prover.Prove() assert.NoError(t, err) assert.NotNil(t, proof) + + verifier := rp.NewRangeVerifier( + setup.com, + []*math.G1{setup.G, setup.H}, + setup.leftGens, + setup.rightGens, + setup.P, + setup.Q, + setup.nr, + setup.l, + setup.curve, + ) err = verifier.Verify(proof) assert.NoError(t, err) } + +func BenchmarkBFProver(b *testing.B) { + pp, err := profile.New(profile.WithAll(), profile.WithPath("./profile")) + require.NoError(b, err) + require.NoError(b, pp.Start()) + defer pp.Stop() + envs := make([]*bfSetup, 0, 128) + for i := 0; i < 128; i++ { + setup, err := NewBfSetup(math.BLS12_381_BBS_GURVY) + require.NoError(b, err) + envs = append(envs, setup) + } + + b.Run("bench", func(b *testing.B) { + for b.Loop() { + setup := envs[rand.Intn(len(envs))] + prover := rp.NewRangeProver( + setup.com, + 115, + []*math.G1{setup.G, setup.H}, + setup.bf, + setup.leftGens, + setup.rightGens, + setup.P, + setup.Q, + setup.nr, + setup.l, + setup.curve, + ) + proof, err := prover.Prove() + assert.NoError(b, err) + assert.NotNil(b, proof) + } + }) +} diff --git a/token/core/zkatdlog/nogh/v1/crypto/rp/ipa.go b/token/core/zkatdlog/nogh/v1/crypto/rp/ipa.go index c46225759..1a6a067b4 100644 --- a/token/core/zkatdlog/nogh/v1/crypto/rp/ipa.go +++ b/token/core/zkatdlog/nogh/v1/crypto/rp/ipa.go @@ -154,6 +154,7 @@ func (p *ipaProver) Prove() (*IPA, error) { } // compute first challenge x := p.Curve.HashToZr(raw) + // compute a commitment to inner product value and the vectors C := p.Q.Mul(p.Curve.ModMul(x, p.InnerProduct, p.Curve.GroupOrder)) C.Add(p.Commitment) @@ -172,22 +173,18 @@ func (p *ipaProver) Prove() (*IPA, error) { // of the left vector and right is a function of right vector. // Both vectors are committed in com which is passed as a parameter to reduce func (p *ipaProver) reduce(X, com *mathlib.G1) (*mathlib.Zr, *mathlib.Zr, []*mathlib.G1, []*mathlib.G1, error) { - var leftGen, rightGen []*mathlib.G1 - var left, right []*mathlib.Zr - - leftGen = p.LeftGenerators - rightGen = p.RightGenerators + leftGen, rightGen := cloneGenerators(p.LeftGenerators, p.RightGenerators) - left = p.leftVector - right = p.rightVector + left := p.leftVector + right := p.rightVector LArray := make([]*mathlib.G1, p.NumberOfRounds) RArray := make([]*mathlib.G1, p.NumberOfRounds) for i := range p.NumberOfRounds { // in each round the size of the vector is reduced by 2 n := len(leftGen) / 2 - leftIP := innerProduct(left[:n], right[n:], p.Curve) - rightIP := innerProduct(left[n:], right[:n], p.Curve) + leftIP := InnerProduct(left[:n], right[n:], p.Curve) + rightIP := InnerProduct(left[n:], right[:n], p.Curve) // LArray[i] is a commitment to left[:n], right[n:] and their inner product LArray[i] = commitVector(left[:n], right[n:], leftGen[n:], rightGen[:n], p.Curve) LArray[i].Add(X.Mul(leftIP)) @@ -206,7 +203,7 @@ func (p *ipaProver) reduce(X, com *mathlib.G1) (*mathlib.Zr, *mathlib.Zr, []*mat // compute 1/x xInv := x.Copy() - xInv.InvModP(p.Curve.GroupOrder) + xInv.InvModOrder() // reduce the generators by 1/2, as a function of the old generators and x and 1/x leftGen, rightGen = reduceGenerators(leftGen, rightGen, x, xInv) @@ -216,14 +213,13 @@ func (p *ipaProver) reduce(X, com *mathlib.G1) (*mathlib.Zr, *mathlib.Zr, []*mat xSquare := p.Curve.ModMul(x, x, p.Curve.GroupOrder) xSquareInv := xSquare.Copy() - xSquareInv.InvModP(p.Curve.GroupOrder) + xSquareInv.InvModOrder() // compute the commitment to left, right and their inner product - CPrime := LArray[i].Mul(xSquare) + CPrime := LArray[i].Mul2(xSquare, RArray[i], xSquareInv) CPrime.Add(com) - CPrime.Add(RArray[i].Mul(xSquareInv)) // com = L^{x^2}*com*R^{1/x^2} - com = CPrime.Copy() + com = CPrime } return left[0], right[0], LArray, RArray, nil } @@ -299,10 +295,8 @@ func (v *ipaVerifier) Verify(proof *IPA) error { X := v.Q.Mul(x) - var leftGen []*mathlib.G1 - var rightGen []*mathlib.G1 - leftGen = v.LeftGenerators - rightGen = v.RightGenerators + leftGen, rightGen := cloneGenerators(v.LeftGenerators, v.RightGenerators) + for i := range v.NumberOfRounds { // check well-formedness if proof.L[i] == nil || proof.R[i] == nil { @@ -317,24 +311,22 @@ func (v *ipaVerifier) Verify(proof *IPA) error { x = v.Curve.HashToZr(raw) // 1/x xInv := x.Copy() - xInv.InvModP(v.Curve.GroupOrder) + xInv.InvModOrder() // x^2 xSquare := v.Curve.ModMul(x, x, v.Curve.GroupOrder) // 1/x^2 xSquareInv := xSquare.Copy() - xSquareInv.InvModP(v.Curve.GroupOrder) + xSquareInv.InvModOrder() // compute a commitment to the reduced vectors and their inner product - CPrime := proof.L[i].Mul(xSquare) + CPrime := proof.L[i].Mul2(xSquare, proof.R[i], xSquareInv) CPrime.Add(C) - CPrime.Add(proof.R[i].Mul(xSquareInv)) C = CPrime.Copy() // reduce the generators by 1/2, as a function of the old generators and x and 1/x leftGen, rightGen = reduceGenerators(leftGen, rightGen, x, xInv) } // compute a commitment to left, right and their product - CPrime := leftGen[0].Mul(proof.Left) - CPrime.Add(rightGen[0].Mul(proof.Right)) + CPrime := leftGen[0].Mul2(proof.Left, rightGen[0], proof.Right) CPrime.Add(X.Mul(v.Curve.ModMul(proof.Left, proof.Right, v.Curve.GroupOrder))) if !CPrime.Equals(C) { return errors.New("invalid IPA") @@ -345,50 +337,58 @@ func (v *ipaVerifier) Verify(proof *IPA) error { // reduceVectors reduces the size of the vectors passed in the parameters by 1/2, // as a function of the old vectors, x and 1/x func reduceVectors(left, right []*mathlib.Zr, x, xInv *mathlib.Zr, c *mathlib.Curve) ([]*mathlib.Zr, []*mathlib.Zr) { - leftPrime := make([]*mathlib.Zr, len(left)/2) - rightPrime := make([]*mathlib.Zr, len(right)/2) - for i := 0; i < len(leftPrime); i++ { + l := len(left) / 2 + leftPrime := make([]*mathlib.Zr, l) + rightPrime := make([]*mathlib.Zr, l) + for i := 0; i < l; i++ { // a_i = a_ix + a_{i+len(left)/2}x^{-1} - leftPrime[i] = c.ModMul(left[i], x, c.GroupOrder) - leftPrime[i] = c.ModAdd(leftPrime[i], c.ModMul(left[i+len(leftPrime)], xInv, c.GroupOrder), c.GroupOrder) + leftPrime[i] = c.ModAddMul2(left[i], x, left[i+l], xInv, c.GroupOrder) // b_i = b_ix^{-1} + b_{i+len(right)/2}x - rightPrime[i] = c.ModMul(right[i], xInv, c.GroupOrder) - rightPrime[i] = c.ModAdd(rightPrime[i], c.ModMul(right[i+len(rightPrime)], x, c.GroupOrder), c.GroupOrder) + rightPrime[i] = c.ModAddMul2(right[i], xInv, right[i+l], x, c.GroupOrder) } + return leftPrime, rightPrime } // reduceGenerators reduces the number of generators passed in the parameters by 1/2, // as a function of the old generators, x and 1/x func reduceGenerators(leftGen, rightGen []*mathlib.G1, x, xInv *mathlib.Zr) ([]*mathlib.G1, []*mathlib.G1) { - leftGenPrime := make([]*mathlib.G1, len(leftGen)/2) - rightGenPrime := make([]*mathlib.G1, len(rightGen)/2) - for i := 0; i < len(leftGenPrime); i++ { + l := len(leftGen) / 2 + for i := 0; i < l; i++ { // G_i = G_i^x*G_{i+len(left)/2}^{1/x} - leftGenPrime[i] = leftGen[i].Mul(xInv) - leftGenPrime[i].Add(leftGen[i+len(leftGenPrime)].Mul(x)) - + leftGen[i].Mul2InPlace(xInv, leftGen[i+l], x) // H_i = H_i^{1/x}*H_{i+len(right)/2}^{x} - rightGenPrime[i] = rightGen[i].Mul(x) - rightGenPrime[i].Add(rightGen[i+len(rightGenPrime)].Mul(xInv)) + rightGen[i].Mul2InPlace(x, rightGen[i+l], xInv) } - return leftGenPrime, rightGenPrime + return leftGen[:l], rightGen[:l] } -func innerProduct(left []*mathlib.Zr, right []*mathlib.Zr, c *mathlib.Curve) *mathlib.Zr { - ip := c.NewZrFromInt(0) - for i, l := range left { - ip = c.ModAdd(ip, c.ModMul(l, right[i], c.GroupOrder), c.GroupOrder) - } - return ip +func InnerProduct(left []*mathlib.Zr, right []*mathlib.Zr, c *mathlib.Curve) *mathlib.Zr { + return c.ModAddMul(left, right, c.GroupOrder) + // ip := c.NewZrFromInt(0) + // for i, l := range left { + // ip = c.ModAdd(ip, c.ModMul(l, right[i], c.GroupOrder), c.GroupOrder) + // } + // return ip } func commitVector(left []*mathlib.Zr, right []*mathlib.Zr, leftgen []*mathlib.G1, rightgen []*mathlib.G1, c *mathlib.Curve) *mathlib.G1 { com := c.NewG1() for i := range left { - com.Add(leftgen[i].Mul(left[i])) - com.Add(rightgen[i].Mul(right[i])) + com.Add(leftgen[i].Mul2(left[i], rightgen[i], right[i])) } return com } + +func cloneGenerators(LeftGenerators, RightGenerators []*mathlib.G1) ([]*mathlib.G1, []*mathlib.G1) { + leftGen := make([]*mathlib.G1, len(LeftGenerators)) + for i := 0; i < len(LeftGenerators); i++ { + leftGen[i] = LeftGenerators[i].Copy() + } + rightGen := make([]*mathlib.G1, len(RightGenerators)) + for i := 0; i < len(RightGenerators); i++ { + rightGen[i] = RightGenerators[i].Copy() + } + return leftGen, rightGen +} diff --git a/token/core/zkatdlog/nogh/v1/crypto/rp/ipa_test.go b/token/core/zkatdlog/nogh/v1/crypto/rp/ipa_test.go index 63b7167a0..2adf04042 100644 --- a/token/core/zkatdlog/nogh/v1/crypto/rp/ipa_test.go +++ b/token/core/zkatdlog/nogh/v1/crypto/rp/ipa_test.go @@ -7,26 +7,44 @@ SPDX-License-Identifier: Apache-2.0 package rp_test import ( + "math/bits" + "math/rand" "strconv" "testing" math "github.com/IBM/mathlib" + "github.com/hyperledger-labs/fabric-smart-client/node/start/profile" "github.com/hyperledger-labs/fabric-token-sdk/token/core/zkatdlog/nogh/v1/crypto/rp" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) -func TestIPAProofVerify(t *testing.T) { - curve := math.Curves[0] - nr := uint64(6) - l := uint64(1 << nr) +type ipaSetup struct { + left []*math.Zr + right []*math.Zr + Q *math.G1 + leftGens []*math.G1 + rightGens []*math.G1 + curve *math.Curve + com *math.G1 + nr uint64 +} + +func NewIpaSetup(curveID math.CurveID) (*ipaSetup, error) { + curve := math.Curves[curveID] + l := uint64(64) + nr := 63 - uint64(bits.LeadingZeros64(l)) leftGens := make([]*math.G1, l) rightGens := make([]*math.G1, l) left := make([]*math.Zr, l) right := make([]*math.Zr, l) rand, err := curve.Rand() - assert.NoError(t, err) + if err != nil { + return nil, err + } com := curve.NewG1() Q := curve.GenG1 + for i := 0; i < len(left); i++ { leftGens[i] = curve.HashToG1([]byte(strconv.Itoa(i))) rightGens[i] = curve.HashToG1([]byte(strconv.Itoa(i + 1))) @@ -35,20 +53,79 @@ func TestIPAProofVerify(t *testing.T) { com.Add(leftGens[i].Mul(left[i])) com.Add(rightGens[i].Mul(right[i])) } + return &ipaSetup{ + left: left, + right: right, + Q: Q, + leftGens: leftGens, + rightGens: rightGens, + curve: curve, + com: com, + nr: nr, + }, nil +} + +func TestIPAProofVerify(t *testing.T) { + setup, err := NewIpaSetup(math.BLS12_381_BBS_GURVY) + require.NoError(t, err) - prover := rp.NewIPAProver(innerProduct(left, right, curve), left, right, Q, leftGens, rightGens, com, nr, curve) + prover := rp.NewIPAProver( + rp.InnerProduct(setup.left, setup.right, setup.curve), + setup.left, + setup.right, + setup.Q, + setup.leftGens, + setup.rightGens, + setup.com, + setup.nr, + setup.curve, + ) proof, err := prover.Prove() - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, proof) - verifier := rp.NewIPAVerifier(innerProduct(left, right, curve), Q, leftGens, rightGens, com, nr, curve) + + verifier := rp.NewIPAVerifier( + rp.InnerProduct(setup.left, setup.right, setup.curve), + setup.Q, + setup.leftGens, + setup.rightGens, + setup.com, + setup.nr, + setup.curve, + ) err = verifier.Verify(proof) - assert.NoError(t, err) + require.NoError(t, err) } -func innerProduct(left []*math.Zr, right []*math.Zr, c *math.Curve) *math.Zr { - ip := c.NewZrFromInt(0) - for i, l := range left { - ip = c.ModAdd(ip, c.ModMul(l, right[i], c.GroupOrder), c.GroupOrder) +func BenchmarkIPAProver(b *testing.B) { + pp, err := profile.New(profile.WithAll(), profile.WithPath("./profile")) + require.NoError(b, err) + require.NoError(b, pp.Start()) + defer pp.Stop() + envs := make([]*ipaSetup, 0, 128) + for i := 0; i < 128; i++ { + setup, err := NewIpaSetup(math.BLS12_381_BBS_GURVY) + require.NoError(b, err) + envs = append(envs, setup) } - return ip + + b.Run("bench", func(b *testing.B) { + for b.Loop() { + setup := envs[rand.Intn(len(envs))] + prover := rp.NewIPAProver( + rp.InnerProduct(setup.left, setup.right, setup.curve), + setup.left, + setup.right, + setup.Q, + setup.leftGens, + setup.rightGens, + setup.com, + setup.nr, + setup.curve, + ) + proof, err := prover.Prove() + require.NoError(b, err) + assert.NotNil(b, proof) + } + }) } diff --git a/token/core/zkatdlog/nogh/v1/issue/issuer_test.go b/token/core/zkatdlog/nogh/v1/issue/issuer_test.go index 40c866021..5ae43dc9b 100644 --- a/token/core/zkatdlog/nogh/v1/issue/issuer_test.go +++ b/token/core/zkatdlog/nogh/v1/issue/issuer_test.go @@ -22,7 +22,7 @@ import ( ) func TestProverVerifier(t *testing.T) { - prover, verifier := prepareZKIssue(t, 32, math.BN254, 2) + prover, verifier := prepareZKIssue(t, 32, math.BLS12_381_BBS_GURVY, 2) proof, err := prover.Prove() assert.NoError(t, err) assert.NotNil(t, proof) @@ -31,7 +31,7 @@ func TestProverVerifier(t *testing.T) { } func TestIssuer(t *testing.T) { - pp := setup(t, 32, math.BN254) + pp := setup(t, 32, math.BLS12_381_BBS_GURVY) issuer := issue2.NewIssuer("ABC", &mock.SigningIdentity{}, pp) action, _, err := issuer.GenerateZKIssue([]uint64{10, 20}, [][]byte{[]byte("alice"), []byte("bob")}) require.NoError(t, err) diff --git a/token/services/identity/storage/kvs/hashicorp/go.mod b/token/services/identity/storage/kvs/hashicorp/go.mod index c5f13eb0e..1c710ecda 100644 --- a/token/services/identity/storage/kvs/hashicorp/go.mod +++ b/token/services/identity/storage/kvs/hashicorp/go.mod @@ -10,7 +10,7 @@ require ( github.com/hashicorp/vault/api v1.16.0 github.com/hyperledger-labs/fabric-smart-client v0.7.0 github.com/hyperledger-labs/fabric-token-sdk v0.4.1-0.20250528165839-032fb9265504 - github.com/stretchr/testify v1.10.0 + github.com/stretchr/testify v1.11.1 ) replace github.com/hyperledger-labs/fabric-token-sdk => ./../../../../../../ @@ -21,7 +21,7 @@ require ( github.com/IBM/idemix v0.0.2-0.20250313153527-832db18b9478 // indirect github.com/IBM/idemix/bccsp/schemes/weak-bb v0.0.0-20250313153527-832db18b9478 // indirect github.com/IBM/idemix/bccsp/types v0.0.0-20250313153527-832db18b9478 // indirect - github.com/IBM/mathlib v0.0.3-0.20251201181318-11a3ec7f764f // indirect + github.com/IBM/mathlib v0.0.3-0.20251211174534-08690b7c5cc8 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.20.0 // indirect @@ -30,7 +30,7 @@ require ( github.com/cockroachdb/errors v1.12.0 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/redact v1.1.5 // indirect - github.com/consensys/gnark-crypto v0.18.1 // indirect + github.com/consensys/gnark-crypto v0.19.2 // indirect github.com/containerd/errdefs v1.0.0 // indirect github.com/containerd/errdefs/pkg v0.3.0 // indirect github.com/containerd/log v0.1.0 // indirect diff --git a/token/services/identity/storage/kvs/hashicorp/go.sum b/token/services/identity/storage/kvs/hashicorp/go.sum index b09105845..1cc9587f7 100644 --- a/token/services/identity/storage/kvs/hashicorp/go.sum +++ b/token/services/identity/storage/kvs/hashicorp/go.sum @@ -11,8 +11,8 @@ github.com/IBM/idemix/bccsp/schemes/weak-bb v0.0.0-20250313153527-832db18b9478 h github.com/IBM/idemix/bccsp/schemes/weak-bb v0.0.0-20250313153527-832db18b9478/go.mod h1:k4Q5EYKRnYC6t80ipSCY3G8H4FdcxRa8jjlsJdGfNCY= github.com/IBM/idemix/bccsp/types v0.0.0-20250313153527-832db18b9478 h1:Uzmcb4pNb54/fbAjnrZTiJwWV74+twP60N4qBGm4PvU= github.com/IBM/idemix/bccsp/types v0.0.0-20250313153527-832db18b9478/go.mod h1:Pi1QIuIZ+1OXIbnYe27vNwJOnSq2WvkHRT/sfweTw8E= -github.com/IBM/mathlib v0.0.3-0.20251201181318-11a3ec7f764f h1:UyHWQt3a/XrM8u/x6KukEzyTABzfeVLZJn40hIIclsM= -github.com/IBM/mathlib v0.0.3-0.20251201181318-11a3ec7f764f/go.mod h1:O230ebw6/22B7T4C03b99ZcPtc5XAfBTOp+ZT+xmMCk= +github.com/IBM/mathlib v0.0.3-0.20251211174534-08690b7c5cc8 h1:nhdZWnVNu1DBVtjGLs472DryJKhKCxiLd883g94xUts= +github.com/IBM/mathlib v0.0.3-0.20251211174534-08690b7c5cc8/go.mod h1:rq67W1H6L1eorrE7DZ/HcSY/pfMDjbPWOx12SeUfQDk= github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= @@ -35,8 +35,8 @@ github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZe github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= -github.com/consensys/gnark-crypto v0.18.1 h1:RyLV6UhPRoYYzaFnPQA4qK3DyuDgkTgskDdoGqFt3fI= -github.com/consensys/gnark-crypto v0.18.1/go.mod h1:L3mXGFTe1ZN+RSJ+CLjUt9x7PNdx8ubaYfDROyp2Z8c= +github.com/consensys/gnark-crypto v0.19.2 h1:qrEAIXq3T4egxqiliFFoNrepkIWVEeIYwt3UL0fvS80= +github.com/consensys/gnark-crypto v0.19.2/go.mod h1:rT23F0XSZqE0mUA0+pRtnL56IbPxs6gp4CeRsBk4XS0= github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE= @@ -239,8 +239,8 @@ github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/sykesm/zap-logfmt v0.0.4 h1:U2WzRvmIWG1wDLCFY3sz8UeEmsdHQjHFNlIdmroVFaI= github.com/sykesm/zap-logfmt v0.0.4/go.mod h1:AuBd9xQjAe3URrWT1BBDk2v2onAZHkZkWRMiYZXiZWA= github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE=