Skip to content

Commit b07fd4b

Browse files
authored
unit-test: token/core/zkatdlog/nogh/v1/audit #1367 (#1368)
Signed-off-by: Angelo De Caro <adc@zurich.ibm.com>
1 parent 86d243a commit b07fd4b

8 files changed

Lines changed: 654 additions & 204 deletions

File tree

token/core/zkatdlog/nogh/v1/audit/audit_suite_test.go

Lines changed: 0 additions & 18 deletions
This file was deleted.

token/core/zkatdlog/nogh/v1/audit/auditor.go

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -17,29 +17,30 @@ import (
1717
"github.com/hyperledger-labs/fabric-token-sdk/token/core/zkatdlog/nogh/v1/transfer"
1818
"github.com/hyperledger-labs/fabric-token-sdk/token/driver"
1919
"github.com/hyperledger-labs/fabric-token-sdk/token/services/logging"
20-
"github.com/hyperledger-labs/fabric-token-sdk/token/services/utils"
2120
token2 "github.com/hyperledger-labs/fabric-token-sdk/token/token"
2221
"go.opentelemetry.io/otel/trace"
2322
)
2423

24+
// SigningIdentity is an alias for driver.SigningIdentity
25+
//
2526
//go:generate counterfeiter -o mock/signing_identity.go -fake-name SigningIdentity . SigningIdentity
26-
27-
// SigningIdentity models a signing identity
28-
type SigningIdentity interface {
29-
driver.SigningIdentity
30-
}
27+
type SigningIdentity = driver.SigningIdentity
3128

3229
// InfoMatcher deserialize audit information
30+
//
31+
//go:generate counterfeiter -o mock/info_matcher.go -fake-name InfoMatcher . InfoMatcher
3332
type InfoMatcher interface {
3433
MatchIdentity(ctx context.Context, id driver.Identity, ai []byte) error
3534
}
3635

36+
// InspectableIdentity contains the identity and its corresponding audit info.
3737
type InspectableIdentity struct {
3838
Identity driver.Identity
3939
IdentityFromMeta driver.Identity
4040
AuditInfo []byte
4141
}
4242

43+
// InspectableData contains the token data and its opening.
4344
type InspectableData struct {
4445
Data *math.G1
4546
TokenType token2.Type
@@ -54,6 +55,7 @@ type InspectableToken struct {
5455
Data InspectableData
5556
}
5657

58+
// NewInspectableToken creates a new InspectableToken.
5759
func NewInspectableToken(
5860
token *token.Token,
5961
ownerAuditInfo []byte,
@@ -94,42 +96,25 @@ type Auditor struct {
9496
Tracer trace.Tracer
9597
// Owner Identity InfoMatcher
9698
InfoMatcher InfoMatcher
97-
// Auditor's signing identity
98-
Signer SigningIdentity
9999
// Pedersen generators used to compute TokenData
100100
PedersenParams []*math.G1
101101
// Elliptic curve
102102
Curve *math.Curve
103103
}
104104

105-
func NewAuditor(logger logging.Logger, tracer trace.Tracer, infoMatcher InfoMatcher, pp []*math.G1, signer SigningIdentity, c *math.Curve) *Auditor {
105+
// NewAuditor creates a new Auditor.
106+
func NewAuditor(logger logging.Logger, tracer trace.Tracer, infoMatcher InfoMatcher, pp []*math.G1, c *math.Curve) *Auditor {
106107
return &Auditor{
107108
Logger: logger,
108109
Tracer: tracer,
109110
InfoMatcher: infoMatcher,
110111
PedersenParams: pp,
111-
Signer: signer,
112112
Curve: c,
113113
}
114114
}
115115

116-
// Endorse is called to sign a valid token request
117-
func (a *Auditor) Endorse(tokenRequest *driver.TokenRequest, txID string) ([]byte, error) {
118-
// Marshal tokenRequest
119-
bytes, err := tokenRequest.MarshalToMessageToSign([]byte(txID))
120-
if err != nil {
121-
return nil, errors.Wrapf(err, "failed marshalling token request [%s]", txID)
122-
}
123-
// Sign
124-
a.Logger.Debugf("Endorse [%s][%s]", utils.Hashable(bytes).String(), txID)
125-
if a.Signer == nil {
126-
return nil, errors.Errorf("audit of tx [%s] failed: signer is nil", txID)
127-
}
128-
129-
return a.Signer.Sign(bytes)
130-
}
131-
132-
// Check validates TokenRequest against TokenRequestMetadata
116+
// Check validates TokenRequest against TokenRequestMetadata.
117+
// It de-obfuscates issue and transfer requests and verifies their validity.
133118
func (a *Auditor) Check(
134119
ctx context.Context,
135120
tokenRequest *driver.TokenRequest,
@@ -150,6 +135,7 @@ func (a *Auditor) Check(
150135
if err != nil {
151136
return errors.Wrapf(err, "failed checking issues for [%s]", txID)
152137
}
138+
// verify issuer identities
153139
for i, id := range identitiesFromIssue {
154140
err = a.InspectIdentity(ctx, a.InfoMatcher, &id, i)
155141
if err != nil {
@@ -173,13 +159,15 @@ func (a *Auditor) Check(
173159

174160
// CheckTransferRequests verifies that the commitments in transfer inputs and outputs match the information provided in the clear.
175161
func (a *Auditor) CheckTransferRequests(ctx context.Context, inputs [][]*InspectableToken, outputsFromTransfer [][]*InspectableToken, txID driver.TokenRequestAnchor) error {
162+
// Inspect outputs of each transfer action
176163
for k, transferred := range outputsFromTransfer {
177164
err := a.InspectOutputs(ctx, transferred)
178165
if err != nil {
179166
return errors.Wrapf(err, "audit of %d th transfer in tx [%s] failed", k, txID)
180167
}
181168
}
182169

170+
// Inspect inputs of each transfer action
183171
for k, i := range inputs {
184172
err := a.InspectInputs(ctx, i)
185173
if err != nil {
@@ -192,7 +180,7 @@ func (a *Auditor) CheckTransferRequests(ctx context.Context, inputs [][]*Inspect
192180

193181
// CheckIssueRequests verifies that the commitments in issue outputs match the information provided in the clear.
194182
func (a *Auditor) CheckIssueRequests(ctx context.Context, outputsFromIssue [][]*InspectableToken, txID driver.TokenRequestAnchor) error {
195-
// Inspect
183+
// Inspect outputs of each issue action
196184
for k, issued := range outputsFromIssue {
197185
err := a.InspectOutputs(ctx, issued)
198186
if err != nil {
@@ -221,14 +209,17 @@ func (a *Auditor) InspectOutput(ctx context.Context, output *InspectableToken, i
221209
if output == nil || output.Data.Data == nil {
222210
return errors.Errorf("invalid output at index [%d]", index)
223211
}
212+
// Recompute commitment from provided cleartext data
224213
tokenComm := commit([]*math.Zr{
225214
a.Curve.HashToZr([]byte(output.Data.TokenType)),
226215
output.Data.Value,
227216
output.Data.BF,
228217
}, a.PedersenParams, a.Curve)
218+
// Verify it matches the commitment in the token
229219
if !tokenComm.Equals(output.Data.Data) {
230220
return errors.Errorf("output at index [%d] does not match the provided opening", index)
231221
}
222+
// Verify owner identity if it's not a redeemed output
232223
if !output.Identity.Identity.IsNone() { // this is not a redeemed output
233224
if err := a.InspectIdentity(ctx, a.InfoMatcher, &output.Identity, index); err != nil {
234225
return errors.Wrapf(err, "failed inspecting output at index [%d]", index)
@@ -245,6 +236,7 @@ func (a *Auditor) InspectInputs(ctx context.Context, inputs []*InspectableToken)
245236
return errors.Errorf("invalid input at index [%d]", i)
246237
}
247238

239+
// Verify input owner identity
248240
if !input.Identity.Identity.IsNone() {
249241
if err := a.InspectIdentity(ctx, a.InfoMatcher, &input.Identity, i); err != nil {
250242
return errors.Wrapf(err, "failed inspecting input at index [%d]", i)
@@ -255,29 +247,31 @@ func (a *Auditor) InspectInputs(ctx context.Context, inputs []*InspectableToken)
255247
return nil
256248
}
257249

258-
// InspectIdentity verifies that the audit info matches the token owner
250+
// InspectIdentity verifies that the audit info matches the token owner.
259251
func (a *Auditor) InspectIdentity(ctx context.Context, matcher InfoMatcher, identity *InspectableIdentity, index int) error {
260252
if identity.Identity.IsNone() {
261253
return errors.Errorf("identity at index [%d] is nil, cannot inspect it", index)
262254
}
263255
if len(identity.AuditInfo) == 0 {
264256
return errors.Errorf("failed to inspect identity at index [%d]: audit info is nil", index)
265257
}
258+
// If identity is provided in metadata, it must match the one in the action
266259
if len(identity.IdentityFromMeta) != 0 {
267260
// enforce equality
268261
if !bytes.Equal(identity.IdentityFromMeta, identity.Identity) {
269262
return errors.Errorf("failed to inspect identity at index [%d]: identity does not match the identity form metadata", index)
270263
}
271264
}
265+
// Use InfoMatcher to verify that AuditInfo corresponds to the Identity
272266
if err := matcher.MatchIdentity(ctx, identity.Identity, identity.AuditInfo); err != nil {
273267
return errors.Wrapf(err, "owner at index [%d] does not match the provided opening", index)
274268
}
275269

276270
return nil
277271
}
278272

279-
// GetAuditInfoForIssues returns an array of InspectableToken for each issue action
280-
// It takes a deserializer, an array of serialized issue actions and an array of issue metadata.
273+
// GetAuditInfoForIssues returns an array of InspectableToken for each issue action.
274+
// It takes an array of serialized issue actions and an array of issue metadata.
281275
func (a *Auditor) GetAuditInfoForIssues(issues [][]byte, issueMetadata []*driver.IssueMetadata) ([][]*InspectableToken, []InspectableIdentity, error) {
282276
if len(issues) != len(issueMetadata) {
283277
return nil, nil, errors.Errorf("number of issues does not match number of provided metadata")
@@ -307,13 +301,15 @@ func (a *Auditor) GetAuditInfoForIssues(issues [][]byte, issueMetadata []*driver
307301
if ia.Outputs[i] == nil {
308302
return nil, nil, errors.Errorf("output token at index [%d] is nil", i)
309303
}
304+
// Issue actions cannot redeem tokens
310305
if ia.Outputs[i].IsRedeem() {
311306
return nil, nil, errors.Errorf("issue cannot redeem tokens")
312307
}
313308
if len(o.Receivers) == 0 || o.Receivers[0] == nil {
314309
return nil, nil, errors.Errorf("issue must have at least one receiver")
315310
}
316311

312+
// Create auditable token using the metadata provided in the request
317313
outputs[k][i], err = NewInspectableToken(
318314
ia.Outputs[i],
319315
o.Receivers[0].AuditInfo,
@@ -336,7 +332,7 @@ func (a *Auditor) GetAuditInfoForIssues(issues [][]byte, issueMetadata []*driver
336332
}
337333

338334
// GetAuditInfoForTransfers returns an array of InspectableToken for each transfer action.
339-
// It takes a deserializer, an array of serialized transfer actions and an array of transfer metadata.
335+
// It takes an array of serialized transfer actions, an array of transfer metadata and input tokens.
340336
func (a *Auditor) GetAuditInfoForTransfers(transfers [][]byte, metadata []*driver.TransferMetadata, inputs [][]*token.Token) ([][]*InspectableToken, [][]*InspectableToken, error) {
341337
if len(transfers) != len(metadata) {
342338
return nil, nil, errors.Errorf("number of transfers does not match the number of provided metadata")
@@ -350,6 +346,7 @@ func (a *Auditor) GetAuditInfoForTransfers(transfers [][]byte, metadata []*drive
350346
if len(transferMetadata.Inputs) != len(inputs[k]) {
351347
return nil, nil, errors.Errorf("number of inputs does not match the number of senders [%d]!=[%d]", len(transferMetadata.Inputs), len(inputs[k]))
352348
}
349+
// Process auditable inputs
353350
auditableInputs[k] = make([]*InspectableToken, len(transferMetadata.Inputs))
354351
for i := range len(transferMetadata.Inputs) {
355352
var err error
@@ -359,6 +356,7 @@ func (a *Auditor) GetAuditInfoForTransfers(transfers [][]byte, metadata []*drive
359356
if transferMetadata.Inputs[i] == nil || len(transferMetadata.Inputs[i].Senders) == 0 || transferMetadata.Inputs[i].Senders[0] == nil {
360357
return nil, nil, errors.Errorf("invalid metadata for input[%d][%d]", k, i)
361358
}
359+
// For inputs, we only need the audit info to identify the sender
362360
auditableInputs[k][i], err = NewInspectableToken(inputs[k][i], transferMetadata.Inputs[i].Senders[0].AuditInfo, "", nil, nil)
363361
if err != nil {
364362
return nil, nil, err
@@ -372,6 +370,7 @@ func (a *Auditor) GetAuditInfoForTransfers(transfers [][]byte, metadata []*drive
372370
if len(ta.Outputs) != len(transferMetadata.Outputs) {
373371
return nil, nil, errors.Errorf("number of outputs does not match the number of output metadata [%d]!=[%d]", len(ta.Outputs), len(transferMetadata.Outputs))
374372
}
373+
// Process auditable outputs
375374
outputs[k] = make([]*InspectableToken, len(ta.Outputs))
376375
for i := range len(ta.Outputs) {
377376
if ta.Outputs[i] == nil {
@@ -403,6 +402,7 @@ func (a *Auditor) GetAuditInfoForTransfers(transfers [][]byte, metadata []*drive
403402
return auditableInputs, outputs, nil
404403
}
405404

405+
// commit computes a Pedersen commitment for the given vector and generators.
406406
func commit(vector []*math.Zr, generators []*math.G1, c *math.Curve) *math.G1 {
407407
com := c.NewG1()
408408
for i := range vector {

0 commit comments

Comments
 (0)