Skip to content

Commit c23481b

Browse files
authored
perf(csp): thread ExecutorProvider through csp.RangeCorrectnessProver and csp.RangeCorrectnessVerifier (#1526)
Signed-off-by: Ankit Basu <ankitbasu14@gmail.com>
1 parent 6880552 commit c23481b

7 files changed

Lines changed: 129 additions & 51 deletions

File tree

token/core/zkatdlog/nogh/v1/crypto/rp/bulletproof/ipa.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
"github.com/hyperledger-labs/fabric-token-sdk/token/core/common/encoding/asn1"
1313
"github.com/hyperledger-labs/fabric-token-sdk/token/core/zkatdlog/nogh/v1/crypto/common"
1414
"github.com/hyperledger-labs/fabric-token-sdk/token/core/zkatdlog/nogh/v1/crypto/math"
15-
rp "github.com/hyperledger-labs/fabric-token-sdk/token/core/zkatdlog/nogh/v1/crypto/rp/executor"
15+
executor "github.com/hyperledger-labs/fabric-token-sdk/token/core/zkatdlog/nogh/v1/crypto/rp/executor"
1616
)
1717

1818
// IPA contains the proof for the inner product argument.
@@ -113,7 +113,7 @@ type ipaProver struct {
113113
Curve *mathlib.Curve
114114
// Provider creates a fresh Executor for each Prove call.
115115
// If nil, DefaultProvider (SerialProvider) is used.
116-
Provider rp.ExecutorProvider
116+
Provider executor.ExecutorProvider
117117
}
118118

119119
// NewIPAProver returns a new ipaProver instance.
@@ -127,10 +127,10 @@ func NewIPAProver(
127127
Commitment *mathlib.G1,
128128
rounds uint64,
129129
c *mathlib.Curve,
130-
provider rp.ExecutorProvider,
130+
provider executor.ExecutorProvider,
131131
) *ipaProver {
132132
if provider == nil {
133-
provider = rp.DefaultProvider
133+
provider = executor.DefaultProvider
134134
}
135135

136136
return &ipaProver{
@@ -254,7 +254,7 @@ type ipaVerifier struct {
254254
Curve *mathlib.Curve
255255
// Provider creates a fresh Executor for each Prove call.
256256
// If nil, DefaultProvider (SerialProvider) is used.
257-
Provider rp.ExecutorProvider
257+
Provider executor.ExecutorProvider
258258
}
259259

260260
// NewIPAVerifier returns an ipaVerifier instance.
@@ -267,10 +267,10 @@ func NewIPAVerifier(
267267
Commitment *mathlib.G1,
268268
rounds uint64,
269269
c *mathlib.Curve,
270-
provider rp.ExecutorProvider,
270+
provider executor.ExecutorProvider,
271271
) *ipaVerifier {
272272
if provider == nil {
273-
provider = rp.DefaultProvider
273+
provider = executor.DefaultProvider
274274
}
275275

276276
return &ipaVerifier{
@@ -406,7 +406,7 @@ func reduceVectors(left, right []*mathlib.Zr, x, xInv *mathlib.Zr, c *mathlib.Cu
406406

407407
// reduceGenerators reduces the number of generators passed in the parameters by 1/2,
408408
// as a function of the old generators, x and 1/x
409-
func reduceGenerators(leftGen, rightGen []*mathlib.G1, x, xInv *mathlib.Zr, provider rp.ExecutorProvider) ([]*mathlib.G1, []*mathlib.G1) {
409+
func reduceGenerators(leftGen, rightGen []*mathlib.G1, x, xInv *mathlib.Zr, provider executor.ExecutorProvider) ([]*mathlib.G1, []*mathlib.G1) {
410410
l := len(leftGen) / 2
411411
// Use the Executor abstraction so that the execution strategy can be
412412
// swapped without changing this function. SerialExecutor runs each task

token/core/zkatdlog/nogh/v1/crypto/rp/bulletproof/rangecorrectness.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
math "github.com/IBM/mathlib"
1111
"github.com/hyperledger-labs/fabric-smart-client/pkg/utils/errors"
1212
"github.com/hyperledger-labs/fabric-token-sdk/token/core/common/encoding/asn1"
13-
rp "github.com/hyperledger-labs/fabric-token-sdk/token/core/zkatdlog/nogh/v1/crypto/rp/executor"
13+
executor "github.com/hyperledger-labs/fabric-token-sdk/token/core/zkatdlog/nogh/v1/crypto/rp/executor"
1414
)
1515

1616
// RangeCorrectness contains a set of range proofs for multiple commitments.
@@ -87,7 +87,7 @@ type RangeCorrectnessProver struct {
8787
Curve *math.Curve
8888
// Provider creates a fresh Executor for each Prove call.
8989
// If nil, DefaultProvider (SerialProvider) is used.
90-
Provider rp.ExecutorProvider
90+
Provider executor.ExecutorProvider
9191
}
9292

9393
// NewRangeCorrectnessProver returns a new RangeCorrectnessProver.
@@ -101,10 +101,10 @@ func NewRangeCorrectnessProver(
101101
P, Q *math.G1,
102102
bitLength, rounds uint64,
103103
c *math.Curve,
104-
provider rp.ExecutorProvider,
104+
provider executor.ExecutorProvider,
105105
) *RangeCorrectnessProver {
106106
if provider == nil {
107-
provider = rp.DefaultProvider
107+
provider = executor.DefaultProvider
108108
}
109109

110110
return &RangeCorrectnessProver{
@@ -188,7 +188,7 @@ type RangeCorrectnessVerifier struct {
188188
Curve *math.Curve
189189
// Provider creates a fresh Executor for each Prove call.
190190
// If nil, DefaultProvider (SerialProvider) is used.
191-
Provider rp.ExecutorProvider
191+
Provider executor.ExecutorProvider
192192
}
193193

194194
// NewRangeCorrectnessVerifier returns a new RangeCorrectnessVerifier.
@@ -199,10 +199,10 @@ func NewRangeCorrectnessVerifier(
199199
P, Q *math.G1,
200200
bitLength, rounds uint64,
201201
curve *math.Curve,
202-
provider rp.ExecutorProvider,
202+
provider executor.ExecutorProvider,
203203
) *RangeCorrectnessVerifier {
204204
if provider == nil {
205-
provider = rp.DefaultProvider
205+
provider = executor.DefaultProvider
206206
}
207207

208208
return &RangeCorrectnessVerifier{

token/core/zkatdlog/nogh/v1/crypto/rp/bulletproof/rp.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
"github.com/hyperledger-labs/fabric-token-sdk/token/core/common/encoding/asn1"
1313
"github.com/hyperledger-labs/fabric-token-sdk/token/core/zkatdlog/nogh/v1/crypto/common"
1414
math2 "github.com/hyperledger-labs/fabric-token-sdk/token/core/zkatdlog/nogh/v1/crypto/math"
15-
rp "github.com/hyperledger-labs/fabric-token-sdk/token/core/zkatdlog/nogh/v1/crypto/rp/executor"
15+
executor "github.com/hyperledger-labs/fabric-token-sdk/token/core/zkatdlog/nogh/v1/crypto/rp/executor"
1616
)
1717

1818
// RangeProofData contains the elements of a Bulletproof-style range proof.
@@ -202,7 +202,7 @@ type rangeProver struct {
202202
Curve *math.Curve
203203
// Provider creates a fresh Executor for each Prove call.
204204
// If nil, DefaultProvider (SerialProvider) is used.
205-
Provider rp.ExecutorProvider
205+
Provider executor.ExecutorProvider
206206
}
207207

208208
// NewRangeProver returns a rangeProver based on the passed arguments
@@ -216,7 +216,7 @@ func NewRangeProver(
216216
P, Q *math.G1,
217217
numberOfRounds, bitLength uint64,
218218
curve *math.Curve,
219-
provider rp.ExecutorProvider,
219+
provider executor.ExecutorProvider,
220220
) *rangeProver {
221221
return &rangeProver{
222222
Commitment: com,
@@ -451,7 +451,7 @@ type rangeVerifier struct {
451451
Curve *math.Curve
452452
// Provider creates a fresh Executor for each Prove call.
453453
// If nil, DefaultProvider (SerialProvider) is used.
454-
Provider rp.ExecutorProvider
454+
Provider executor.ExecutorProvider
455455
}
456456

457457
// NewRangeVerifier returns a rangeVerifier based on the passed arguments
@@ -463,7 +463,7 @@ func NewRangeVerifier(
463463
P, Q *math.G1,
464464
numberOfRounds, bitLength uint64,
465465
curve *math.Curve,
466-
provider rp.ExecutorProvider,
466+
provider executor.ExecutorProvider,
467467
) *rangeVerifier {
468468
return &rangeVerifier{
469469
Commitment: com,

token/core/zkatdlog/nogh/v1/crypto/rp/csp/rangecorrectness.go

Lines changed: 89 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/hyperledger-labs/fabric-smart-client/pkg/utils/errors"
1212
"github.com/hyperledger-labs/fabric-token-sdk/token/core/common/encoding/asn1"
1313
math2 "github.com/hyperledger-labs/fabric-token-sdk/token/core/zkatdlog/nogh/v1/crypto/math"
14+
executor "github.com/hyperledger-labs/fabric-token-sdk/token/core/zkatdlog/nogh/v1/crypto/rp/executor"
1415
)
1516

1617
// RangeCorrectness contains a set of range proofs for multiple commitments.
@@ -80,17 +81,27 @@ type RangeCorrectnessProver struct {
8081
// Curve is the mathematical curve.
8182
Curve *math.Curve
8283
TranscriptHeader []byte
84+
// Provider creates a fresh Executor for each Prove call.
85+
// If nil, executor.DefaultProvider (SerialProvider) is used.
86+
Provider executor.ExecutorProvider
8387
}
8488

8589
// NewRangeCorrectnessProver returns a new RangeCorrectnessProver instance.
90+
// provider controls how independent range proofs are executed; pass nil
91+
// to use SerialProvider, which preserves the previous serial behaviour.
8692
func NewRangeCorrectnessProver(
8793
coms []*math.G1,
8894
values []uint64,
8995
blindingFactors []*math.Zr,
9096
pedersenParameters, leftGenerators, rightGenerators []*math.G1,
9197
bitLength uint64,
9298
c *math.Curve,
99+
provider executor.ExecutorProvider,
93100
) *RangeCorrectnessProver {
101+
if provider == nil {
102+
provider = executor.DefaultProvider
103+
}
104+
94105
return &RangeCorrectnessProver{
95106
Commitments: coms,
96107
Values: values,
@@ -100,32 +111,49 @@ func NewRangeCorrectnessProver(
100111
RightGenerators: rightGenerators,
101112
BitLength: bitLength,
102113
Curve: c,
114+
Provider: provider,
103115
}
104116
}
105117

106-
// Prove generates a set of range proofs.
118+
// Prove generates a set of range proofs, one per commitment.
119+
// Independent proofs are executed using the Provider's Executor strategy.
107120
func (p *RangeCorrectnessProver) Prove() (*RangeCorrectness, error) {
108121
if len(p.TranscriptHeader) == 0 {
109122
return nil, errors.New("transcript header is empty")
110123
}
111-
rc := &RangeCorrectness{}
112-
rc.Proofs = make([]*RangeProof, len(p.Commitments))
113-
for i := range len(p.Commitments) {
114-
bp := NewRangeProver(
115-
p.Commitments[i],
116-
math2.NewCachedZrFromInt(p.Curve, p.Values[i]),
117-
p.BlindingFactors[i],
118-
p.PedersenParameters,
119-
p.LeftGenerators,
120-
p.RightGenerators,
121-
p.BitLength,
122-
p.Curve,
123-
).WithTranscriptHeader(p.TranscriptHeader)
124-
proof, err := bp.Prove()
124+
125+
n := len(p.Commitments)
126+
rc := &RangeCorrectness{
127+
Proofs: make([]*RangeProof, n),
128+
}
129+
errs := make([]error, n)
130+
131+
// A fresh Executor is obtained per Prove call so that concurrent callers
132+
// on the same RangeCorrectnessProver never share an Executor instance.
133+
exec := p.Provider.New()
134+
135+
for i := range n {
136+
exec.Submit(func() {
137+
bp := NewRangeProver(
138+
p.Commitments[i],
139+
math2.NewCachedZrFromInt(p.Curve, p.Values[i]),
140+
p.BlindingFactors[i],
141+
p.PedersenParameters,
142+
p.LeftGenerators,
143+
p.RightGenerators,
144+
p.BitLength,
145+
p.Curve,
146+
).WithTranscriptHeader(p.TranscriptHeader)
147+
rc.Proofs[i], errs[i] = bp.Prove()
148+
})
149+
}
150+
151+
exec.Wait()
152+
153+
for _, err := range errs {
125154
if err != nil {
126155
return nil, err
127156
}
128-
rc.Proofs[i] = proof
129157
}
130158

131159
return rc, nil
@@ -150,47 +178,77 @@ type RangeCorrectnessVerifier struct {
150178
// BitLength is the maximum bit length of the values.
151179
BitLength uint64
152180
// Curve is the mathematical curve.
153-
Curve *math.Curve
154-
181+
Curve *math.Curve
155182
TranscriptHeader []byte
183+
// Provider creates a fresh Executor for each Verify call.
184+
// If nil, executor.DefaultProvider (SerialProvider) is used.
185+
Provider executor.ExecutorProvider
156186
}
157187

158188
// NewRangeCorrectnessVerifier returns a new RangeCorrectnessVerifier instance.
189+
// provider controls how independent range proofs are verified; pass nil
190+
// to use SerialProvider, which preserves the previous serial behaviour.
159191
func NewRangeCorrectnessVerifier(
160192
pedersenParameters, leftGenerators, rightGenerators []*math.G1,
161193
bitLength uint64,
162194
curve *math.Curve,
195+
provider executor.ExecutorProvider,
163196
) *RangeCorrectnessVerifier {
197+
if provider == nil {
198+
provider = executor.DefaultProvider
199+
}
200+
164201
return &RangeCorrectnessVerifier{
165202
PedersenParameters: pedersenParameters,
166203
LeftGenerators: leftGenerators,
167204
RightGenerators: rightGenerators,
168205
BitLength: bitLength,
169206
Curve: curve,
207+
Provider: provider,
170208
}
171209
}
172210

173211
// Verify checks if the provided set of range proofs is valid.
212+
// Independent proofs are verified using the Provider's Executor strategy.
174213
func (v *RangeCorrectnessVerifier) Verify(rc *RangeCorrectness) error {
175214
if len(rc.Proofs) != len(v.Commitments) {
176215
return errors.New("invalid range proof")
177216
}
178217
if len(v.TranscriptHeader) == 0 {
179218
return errors.New("transcript header is empty")
180219
}
181-
for i := range len(rc.Proofs) {
182-
if rc.Proofs[i] == nil {
183-
return errors.Errorf("invalid range proof: nil proof at index %d", i)
184-
}
185-
bv := NewRangeVerifier(
186-
v.PedersenParameters,
187-
v.LeftGenerators,
188-
v.RightGenerators,
189-
v.Commitments[i],
190-
v.BitLength,
191-
v.Curve,
192-
).WithTranscriptHeader(v.TranscriptHeader)
193-
err := bv.Verify(rc.Proofs[i])
220+
221+
n := len(rc.Proofs)
222+
errs := make([]error, n)
223+
224+
// A fresh Executor is obtained per Verify call so that concurrent callers
225+
// on the same RangeCorrectnessVerifier never share an Executor instance.
226+
exec := v.Provider.New()
227+
228+
for i := range n {
229+
exec.Submit(func() {
230+
if rc.Proofs[i] == nil {
231+
errs[i] = errors.Errorf("invalid range proof: nil proof at index %d", i)
232+
233+
return
234+
}
235+
236+
bv := NewRangeVerifier(
237+
v.PedersenParameters,
238+
v.LeftGenerators,
239+
v.RightGenerators,
240+
v.Commitments[i],
241+
v.BitLength,
242+
v.Curve,
243+
).WithTranscriptHeader(v.TranscriptHeader)
244+
245+
errs[i] = bv.Verify(rc.Proofs[i])
246+
})
247+
}
248+
249+
exec.Wait()
250+
251+
for i, err := range errs {
194252
if err != nil {
195253
return errors.Wrapf(err, "invalid range proof at index %d", i)
196254
}

0 commit comments

Comments
 (0)