Skip to content

Commit e223d27

Browse files
committed
[FAB-12602] Idemix Credential Revocation Information
This change-set does the following: - introduces opts to geenrate and verify the CRI - introduces a BCCSP signer and verifier for the CRI - tests Change-Id: I69becce66a69345034dbcf288af3529532835b42 Signed-off-by: Angelo De Caro <adc@zurich.ibm.com>
1 parent b2ea980 commit e223d27

File tree

5 files changed

+488
-2
lines changed

5 files changed

+488
-2
lines changed

bccsp/idemix/idemix.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,23 @@ type Credential interface {
8080
Verify(sk Big, ipk IssuerPublicKey, credential []byte, attributes []bccsp.IdemixAttribute) error
8181
}
8282

83-
// Revocation handles idemix revocation-related operations
83+
// Revocation is a local interface to decouple from the idemix implementation
84+
// the revocation-related operations
8485
type Revocation interface {
8586

8687
// NewKey generates a long term signing key that will be used for revocation
8788
NewKey() (*ecdsa.PrivateKey, error)
89+
90+
// Sign creates the Credential Revocation Information for a certain time period (epoch).
91+
// Users can use the CRI to prove that they are not revoked.
92+
// Note that when not using revocation (i.e., alg = ALG_NO_REVOCATION), the entered unrevokedHandles are not used,
93+
// and the resulting CRI can be used by any signer.
94+
Sign(key *ecdsa.PrivateKey, unrevokedHandles [][]byte, epoch int, alg bccsp.RevocationAlgorithm) ([]byte, error)
95+
96+
// Verify verifies that the revocation PK for a certain epoch is valid,
97+
// by checking that it was signed with the long term revocation key.
98+
// Note that even if we use no revocation (i.e., alg = ALG_NO_REVOCATION), we need
99+
// to verify the signature to make sure the issuer indeed signed that no revocation
100+
// is used in this epoch.
101+
Verify(pk *ecdsa.PublicKey, cri []byte, epoch int, alg bccsp.RevocationAlgorithm) error
88102
}

bccsp/idemix/mock/revocation.go

Lines changed: 150 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bccsp/idemix/revocation.go

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ type revocationPublicKey struct {
7272
pubKey *ecdsa.PublicKey
7373
}
7474

75+
func NewRevocationPublicKey(pubKey *ecdsa.PublicKey) *revocationPublicKey {
76+
return &revocationPublicKey{pubKey: pubKey}
77+
}
78+
7579
// Bytes converts this key to its byte representation,
7680
// if this operation is allowed.
7781
func (k *revocationPublicKey) Bytes() (raw []byte, err error) {
@@ -120,7 +124,7 @@ type RevocationKeyGen struct {
120124
Revocation Revocation
121125
}
122126

123-
func (g *RevocationKeyGen) KeyGen(opts bccsp.KeyGenOpts) (k bccsp.Key, err error) {
127+
func (g *RevocationKeyGen) KeyGen(opts bccsp.KeyGenOpts) (bccsp.Key, error) {
124128
// Create a new key pair
125129
key, err := g.Revocation.NewKey()
126130
if err != nil {
@@ -129,3 +133,61 @@ func (g *RevocationKeyGen) KeyGen(opts bccsp.KeyGenOpts) (k bccsp.Key, err error
129133

130134
return &revocationSecretKey{exportable: g.Exportable, privKey: key}, nil
131135
}
136+
137+
type CriSigner struct {
138+
Revocation Revocation
139+
}
140+
141+
func (s *CriSigner) Sign(k bccsp.Key, digest []byte, opts bccsp.SignerOpts) ([]byte, error) {
142+
revocationSecretKey, ok := k.(*revocationSecretKey)
143+
if !ok {
144+
return nil, errors.New("invalid key, expected *revocationSecretKey")
145+
}
146+
criOpts, ok := opts.(*bccsp.IdemixCRISignerOpts)
147+
if !ok {
148+
return nil, errors.New("invalid options, expected *IdemixCRISignerOpts")
149+
}
150+
if len(digest) != 0 {
151+
return nil, errors.New("invalid digest, it must be empty")
152+
}
153+
154+
return s.Revocation.Sign(
155+
revocationSecretKey.privKey,
156+
criOpts.UnrevokedHandles,
157+
criOpts.Epoch,
158+
criOpts.RevocationAlgorithm,
159+
)
160+
}
161+
162+
type CriVerifier struct {
163+
Revocation Revocation
164+
}
165+
166+
func (v *CriVerifier) Verify(k bccsp.Key, signature, digest []byte, opts bccsp.SignerOpts) (bool, error) {
167+
revocationPublicKey, ok := k.(*revocationPublicKey)
168+
if !ok {
169+
return false, errors.New("invalid key, expected *revocationPublicKey")
170+
}
171+
criOpts, ok := opts.(*bccsp.IdemixCRISignerOpts)
172+
if !ok {
173+
return false, errors.New("invalid options, expected *IdemixCRISignerOpts")
174+
}
175+
if len(digest) != 0 {
176+
return false, errors.New("invalid digest, it must be empty")
177+
}
178+
if len(signature) == 0 {
179+
return false, errors.New("invalid signature, it must not be empty")
180+
}
181+
182+
err := v.Revocation.Verify(
183+
revocationPublicKey.pubKey,
184+
signature,
185+
criOpts.Epoch,
186+
criOpts.RevocationAlgorithm,
187+
)
188+
if err != nil {
189+
return false, err
190+
}
191+
192+
return true, nil
193+
}

0 commit comments

Comments
 (0)