Skip to content

Commit 25cd47b

Browse files
authored
enhanced redeem: make issuer signature optional #1134 (#1216)
Signed-off-by: Angelo De Caro <adc@zurich.ibm.com>
1 parent f75aa62 commit 25cd47b

File tree

15 files changed

+100
-117
lines changed

15 files changed

+100
-117
lines changed

cmd/tokengen/cobra/pp/fabtokenv1/gen.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,12 @@ func Gen(args *GeneratorArgs) ([]byte, error) {
103103
if err := common.SetupIssuersAndAuditors(pp, args.Auditors, args.Issuers); err != nil {
104104
return nil, err
105105
}
106+
107+
// warn in case no issuers are specified
108+
if len(pp.Issuers()) == 0 {
109+
fmt.Println("No issuers specified. The public parameters allow anyone to create tokens.")
110+
}
111+
106112
// Store Public Params
107113
raw, err := pp.Serialize()
108114
if err != nil {

cmd/tokengen/cobra/pp/zkatdlognoghv1/gen.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,11 @@ func Gen(args *GeneratorArgs) ([]byte, error) {
149149
return nil, errors.Wrapf(err, "failed to validate public parameters")
150150
}
151151

152+
// warn in case no issuers are specified
153+
if len(pp.Issuers()) == 0 {
154+
fmt.Println("No issuers specified. The public parameters allow anyone to create tokens.")
155+
}
156+
152157
// Store Public Params
153158
raw, err := pp.Serialize()
154159
if err != nil {

token/core/common/ppm.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ func NewPublicParamsManager[T driver.PublicParameters](
4444
if err := pp.Validate(); err != nil {
4545
return nil, errors.WithMessagef(err, "invalid public parameters")
4646
}
47+
if len(pp.Issuers()) == 0 {
48+
logger.Warnf("no issuers definied in the public parameters")
49+
}
4750
ppm.publicParameters = pp
4851
ppm.ppHash = utils.Hashable(ppRaw).Raw()
4952

@@ -54,6 +57,9 @@ func NewPublicParamsManagerFromParams[T driver.PublicParameters](pp T) (*PublicP
5457
if err := pp.Validate(); err != nil {
5558
return nil, errors.WithMessagef(err, "invalid public parameters")
5659
}
60+
if len(pp.Issuers()) == 0 {
61+
logger.Warnf("no issuers definied in the public parameters")
62+
}
5763
return &PublicParamsManager[T]{
5864
publicParameters: pp,
5965
}, nil

token/core/common/transfer.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ import (
1616
// If opts specify an FSC issuer identity, then we expect to find the opts also the public key to add in the transfer action.
1717
// Otherwise, the first public key in the public params is used.
1818
func SelectIssuerForRedeem(issuers []driver.Identity, opts *driver.TransferOptions) (driver.Identity, error) {
19+
if len(issuers) == 0 {
20+
// nothing to do here
21+
return nil, nil
22+
}
1923
issuerNetworkIdentity, err := ttx.GetFSCIssuerIdentityFromOpts(opts.Attributes)
2024
if err != nil {
2125
return nil, errors.Wrap(err, "failed to get issuer network identity")

token/core/common/transfer_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,15 @@ func TestSelectIssuerForRedeem(t *testing.T) {
3636
ttx.IssuerPublicParamsPublicKey: issuerPPPublicKey,
3737
},
3838
expectError: false,
39-
expectIdentity: issuerPPPublicKey,
39+
expectIdentity: nil,
4040
},
4141
{
4242
name: "opts with FSC issuer identity but no public key",
4343
issuers: nil,
4444
attributes: map[interface{}]interface{}{
4545
ttx.IssuerFSCIdentityKey: issuerFSCIdentity,
4646
},
47-
expectError: true,
47+
expectError: false,
4848
expectIdentity: nil,
4949
},
5050
{
@@ -58,7 +58,7 @@ func TestSelectIssuerForRedeem(t *testing.T) {
5858
name: "opts with no FSC issuer identity, no issuers",
5959
issuers: []driver.Identity{},
6060
attributes: map[interface{}]interface{}{},
61-
expectError: true,
61+
expectError: false,
6262
expectIdentity: nil,
6363
},
6464
{
@@ -67,7 +67,7 @@ func TestSelectIssuerForRedeem(t *testing.T) {
6767
attributes: map[interface{}]interface{}{
6868
ttx.IssuerFSCIdentityKey: 1234,
6969
},
70-
expectError: true,
70+
expectError: false,
7171
expectIdentity: nil,
7272
},
7373
{
@@ -77,7 +77,7 @@ func TestSelectIssuerForRedeem(t *testing.T) {
7777
ttx.IssuerFSCIdentityKey: issuerFSCIdentity,
7878
ttx.IssuerPublicParamsPublicKey: 1234,
7979
},
80-
expectError: true,
80+
expectError: false,
8181
expectIdentity: nil,
8282
},
8383
}

token/core/fabtoken/v1/setup/setup.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,8 @@ func (p *PublicParams) Precision() uint64 {
233233
return p.QuantityPrecision
234234
}
235235

236-
// Validate validates the public parameters
236+
// Validate validates the public parameters.
237+
// The list of issues can be empty meaning that anyone can create tokens.
237238
func (p *PublicParams) Validate() error {
238239
if p.QuantityPrecision > 64 {
239240
return errors.Errorf("invalid precision [%d], must be less than 64", p.QuantityPrecision)
@@ -245,9 +246,6 @@ func (p *PublicParams) Validate() error {
245246
if p.MaxToken > maxTokenValue {
246247
return errors.Errorf("max token value is invalid [%d]>[%d]", p.MaxToken, maxTokenValue)
247248
}
248-
if len(p.IssuerIDs) == 0 {
249-
return errors.New("invalid public parameters: empty list of issuers")
250-
}
251249
return nil
252250
}
253251

token/core/fabtoken/v1/setup/setup_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,15 @@ func TestPublicParams_Validate_Valid(t *testing.T) {
4848
DriverName: FabTokenDriverName,
4949
QuantityPrecision: 32,
5050
MaxToken: 1<<32 - 1,
51-
IssuerIDs: []driver.Identity{[]byte("issuer1"), []byte("issuer2")},
5251
}
52+
// without issuers
5353
err := pp.Validate()
5454
assert.NoError(t, err)
55+
56+
// with issuers
57+
pp.IssuerIDs = []driver.Identity{[]byte("issuer1"), []byte("issuer2")}
58+
err = pp.Validate()
59+
assert.NoError(t, err)
5560
}
5661

5762
func TestPublicParams_Validate_InvalidPrecision(t *testing.T) {

token/core/fabtoken/v1/validator/validator_transfer.go

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -50,34 +50,32 @@ func TransferSignatureValidate(c context.Context, ctx *Context) error {
5050
}
5151
ctx.Signatures = append(ctx.Signatures, sigma)
5252
}
53-
54-
var isRedeem bool
55-
for _, output := range ctx.TransferAction.Outputs {
56-
if output.Owner == nil {
57-
isRedeem = true
58-
break
59-
}
60-
}
61-
62-
// If transfer action is a redeem, verify the signature of the issuer
63-
if isRedeem {
64-
ctx.Logger.Infof("action is a redeem, verify the signature of the issuer")
65-
66-
issuer := ctx.TransferAction.GetIssuer()
67-
if issuer == nil {
68-
return errors.Errorf("On Redeem action, must have at least one issuer")
69-
}
70-
71-
issuerVerifier, err := ctx.Deserializer.GetIssuerVerifier(c, issuer)
72-
if err != nil {
73-
return errors.Wrapf(err, "failed deserializing issuer [%s]", issuer.UniqueID())
53+
if len(ctx.PP.Issuers()) > 0 {
54+
// In this case we must ensure that an issuer signed as well if the action redeems tokens as well
55+
var isRedeem bool
56+
for _, output := range ctx.TransferAction.Outputs {
57+
if output.Owner == nil {
58+
isRedeem = true
59+
break
60+
}
7461
}
75-
76-
sigma, err := ctx.SignatureProvider.HasBeenSignedBy(c, issuer, issuerVerifier)
77-
if err != nil {
78-
return errors.Wrapf(err, "failed signature verification [%s]", issuer.UniqueID())
62+
// If transfer action is a redeem, verify the signature of the issuer
63+
if isRedeem {
64+
ctx.Logger.Infof("action is a redeem, verify the signature of the issuer")
65+
issuer := ctx.TransferAction.GetIssuer()
66+
if issuer == nil {
67+
return errors.Errorf("On Redeem action, must have at least one issuer")
68+
}
69+
issuerVerifier, err := ctx.Deserializer.GetIssuerVerifier(c, issuer)
70+
if err != nil {
71+
return errors.Wrapf(err, "failed deserializing issuer [%s]", issuer.UniqueID())
72+
}
73+
sigma, err := ctx.SignatureProvider.HasBeenSignedBy(c, issuer, issuerVerifier)
74+
if err != nil {
75+
return errors.Wrapf(err, "failed signature verification [%s]", issuer.UniqueID())
76+
}
77+
ctx.Signatures = append(ctx.Signatures, sigma)
7978
}
80-
ctx.Signatures = append(ctx.Signatures, sigma)
8179
}
8280

8381
ctx.InputTokens = inputToken

token/core/zkatdlog/nogh/v1/setup/setup.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -476,10 +476,9 @@ func (p *PublicParams) String() string {
476476
return string(res)
477477
}
478478

479+
// Validate validates the public parameters.
480+
// The list of issues can be empty meaning that anyone can create tokens.
479481
func (p *PublicParams) Validate() error {
480-
// if p.DriverVersion != ProtocolV1 {
481-
// return errors.Errorf("invalid version [%d], expected [%d]", p.DriverVersion, ProtocolV1)
482-
// }
483482
if int(p.Curve) > len(mathlib.Curves)-1 {
484483
return errors.Errorf("invalid public parameters: invalid curveID [%d > %d]", int(p.Curve), len(mathlib.Curves)-1)
485484
}
@@ -520,9 +519,6 @@ func (p *PublicParams) Validate() error {
520519
if maxToken != p.MaxToken {
521520
return errors.Errorf("invalid maxt token, [%d]!=[%d]", maxToken, p.MaxToken)
522521
}
523-
if len(p.IssuerIDs) == 0 {
524-
return errors.New("invalid public parameters: empty list of issuers")
525-
}
526522
return nil
527523
}
528524

token/core/zkatdlog/nogh/v1/setup/setup_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@ func TestSerialization(t *testing.T) {
3636
assert.Equal(t, pp, pp2)
3737
assert.Equal(t, ser, ser2)
3838

39-
assert.Error(t, pp.Validate())
39+
// no issuers
40+
assert.NoError(t, pp.Validate())
4041

42+
// with issuers
4143
pp.IssuerIDs = []driver.Identity{[]byte("issuer")}
4244
assert.NoError(t, pp.Validate())
4345
}

0 commit comments

Comments
 (0)