@@ -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
3332type 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.
3737type InspectableIdentity struct {
3838 Identity driver.Identity
3939 IdentityFromMeta driver.Identity
4040 AuditInfo []byte
4141}
4242
43+ // InspectableData contains the token data and its opening.
4344type 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.
5759func 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.
133118func (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.
175161func (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.
194182func (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.
259251func (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.
281275func (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 .
340336func (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.
406406func commit (vector []* math.Zr , generators []* math.G1 , c * math.Curve ) * math.G1 {
407407 com := c .NewG1 ()
408408 for i := range vector {
0 commit comments