@digitalbazaar/vc 6.2.0 → 6.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +149 -10
- package/lib/index.js +7 -3
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@ the following:
|
|
|
48
48
|
|
|
49
49
|
## Install
|
|
50
50
|
|
|
51
|
-
- Browsers and Node.js
|
|
51
|
+
- Browsers and Node.js 18+ are supported.
|
|
52
52
|
|
|
53
53
|
To install from NPM:
|
|
54
54
|
|
|
@@ -122,15 +122,18 @@ Pre-requisites:
|
|
|
122
122
|
|
|
123
123
|
* You have a private key (with id and controller) and corresponding suite
|
|
124
124
|
* You have are using a cryptosuite that supports selective disclosure, such
|
|
125
|
-
as `ecdsa-sd-2023`
|
|
125
|
+
as `ecdsa-sd-2023` or `bbs-2023`
|
|
126
126
|
* If you're using a custom `@context`, make sure it's resolvable
|
|
127
127
|
* (Recommended) You have a strategy for where to publish your Controller
|
|
128
128
|
Document and Public Key
|
|
129
129
|
|
|
130
|
+
Issuing using `ecdsa-sd-2023`:
|
|
131
|
+
|
|
130
132
|
```js
|
|
131
|
-
import * as
|
|
133
|
+
import * as EcdsaMultikey from '@digitalbazaar/ecdsa-multikey';
|
|
132
134
|
import * as ecdsaSd2023Cryptosuite from
|
|
133
135
|
'@digitalbazaar/ecdsa-sd-2023-cryptosuite';
|
|
136
|
+
import * as vc from '@digitalbazaar/vc';
|
|
134
137
|
import {DataIntegrityProof} from '@digitalbazaar/data-integrity';
|
|
135
138
|
|
|
136
139
|
const ecdsaKeyPair = await EcdsaMultikey.generate({
|
|
@@ -139,6 +142,18 @@ const ecdsaKeyPair = await EcdsaMultikey.generate({
|
|
|
139
142
|
controller: 'https://example.edu/issuers/565049'
|
|
140
143
|
});
|
|
141
144
|
|
|
145
|
+
// sample exported key pair
|
|
146
|
+
/*
|
|
147
|
+
{
|
|
148
|
+
"@context": "https://w3id.org/security/multikey/v1",
|
|
149
|
+
"id": "https://example.edu/issuers/keys/2",
|
|
150
|
+
"type": "Multikey",
|
|
151
|
+
"controller": "https://example.edu/issuers/565049",
|
|
152
|
+
"publicKeyMultibase": "zDnaeWJjGpXnQAbEpRur3kSWFapGZbwGnFCkzyhiq7nDeXXrM",
|
|
153
|
+
"secretKeyMultibase": "z42trzSpncjWFaB9cKE2Gg5hxtbuAQa5mVJgGwjrugHMacdM"
|
|
154
|
+
}
|
|
155
|
+
*/
|
|
156
|
+
|
|
142
157
|
// sample unsigned credential
|
|
143
158
|
const credential = {
|
|
144
159
|
"@context": [
|
|
@@ -176,6 +191,68 @@ const signedVC = await vc.issue({credential, suite, documentLoader});
|
|
|
176
191
|
console.log(JSON.stringify(signedVC, null, 2));
|
|
177
192
|
```
|
|
178
193
|
|
|
194
|
+
Issuing using `bbs-2023`:
|
|
195
|
+
|
|
196
|
+
```js
|
|
197
|
+
import * as bbs2023Cryptosuite from '@digitalbazaar/bbs-2023-cryptosuite';
|
|
198
|
+
import * as bls12381Multikey from '@digitalbazaar/bls12-381-multikey';
|
|
199
|
+
import * as vc from '@digitalbazaar/vc';
|
|
200
|
+
import {DataIntegrityProof} from '@digitalbazaar/data-integrity';
|
|
201
|
+
|
|
202
|
+
const bbsKeyPair = await bls12381Multikey.generate({
|
|
203
|
+
algorithm: 'BBS-BLS12-381-SHA-256';
|
|
204
|
+
id: 'https://example.edu/issuers/keys/3',
|
|
205
|
+
controller: 'https://example.edu/issuers/565049'
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
// sample exported key pair
|
|
209
|
+
/*
|
|
210
|
+
{
|
|
211
|
+
"@context": "https://w3id.org/security/multikey/v1",
|
|
212
|
+
"id": "https://example.edu/issuers/keys/3",
|
|
213
|
+
"type": "Multikey",
|
|
214
|
+
"controller": "https://example.edu/issuers/565049",
|
|
215
|
+
"publicKeyMultibase": "zUC72jQrt2BfyE57AVgHgThKCsH6HNo85X9SLNpAJaHb42cNDXhsRWL2KkrFtaiztPbbZjfDVQnQQMw2nMqAPUHnaQ3xEr7kUmcnBgv7S2wQSbRbr7mqsP153nU7yMh3ZN4ZryL",
|
|
216
|
+
"secretKeyMultibase": "z488y1niFCWnaV2i86q1raaa7qwBWZ6WTLeS1W1PrsbcsoNg"
|
|
217
|
+
}
|
|
218
|
+
*/
|
|
219
|
+
|
|
220
|
+
// sample unsigned credential
|
|
221
|
+
const credential = {
|
|
222
|
+
"@context": [
|
|
223
|
+
"https://www.w3.org/2018/credentials/v1",
|
|
224
|
+
"https://www.w3.org/2018/credentials/examples/v1"
|
|
225
|
+
],
|
|
226
|
+
// omit `id` to enable unlinkable disclosure
|
|
227
|
+
"type": ["VerifiableCredential", "AlumniCredential"],
|
|
228
|
+
"issuer": "https://example.edu/issuers/565049",
|
|
229
|
+
// use less precise date that is shared by a sufficiently large group
|
|
230
|
+
// of VCs to enable unlinkable disclosure
|
|
231
|
+
"issuanceDate": "2010-01-01T01:00:00Z",
|
|
232
|
+
"credentialSubject": {
|
|
233
|
+
// omit `id` to enable unlinkable disclosure
|
|
234
|
+
"alumniOf": "Example University"
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
// setup bbs-2023 suite for signing unlinkable selective disclosure VCs
|
|
239
|
+
const suite = new DataIntegrityProof({
|
|
240
|
+
signer: bbsKeyPair.signer(),
|
|
241
|
+
cryptosuite: createSignCryptosuite({
|
|
242
|
+
// require the `issuer` and `issuanceDate` fields to always be disclosed
|
|
243
|
+
// by the holder (presenter)
|
|
244
|
+
mandatoryPointers: [
|
|
245
|
+
'/issuanceDate',
|
|
246
|
+
'/issuer'
|
|
247
|
+
]
|
|
248
|
+
})
|
|
249
|
+
});
|
|
250
|
+
// note: do not include a proof ID to enable unlinkable selective disclosure
|
|
251
|
+
|
|
252
|
+
const signedVC = await vc.issue({credential, suite, documentLoader});
|
|
253
|
+
console.log(JSON.stringify(signedVC, null, 2));
|
|
254
|
+
```
|
|
255
|
+
|
|
179
256
|
### Deriving a Selective Disclosure Verifiable Credential
|
|
180
257
|
|
|
181
258
|
Note: This step is performed as a holder of a verifiable credential, not as
|
|
@@ -184,13 +261,16 @@ an issuer.
|
|
|
184
261
|
Pre-requisites:
|
|
185
262
|
|
|
186
263
|
* You have a verifiable credential that was issued using a cryptosuite that
|
|
187
|
-
supports selective disclosure, such as `ecdsa-sd-2023`
|
|
264
|
+
supports selective disclosure, such as `ecdsa-sd-2023` or `bbs-2023`
|
|
188
265
|
* If you're using a custom `@context`, make sure it's resolvable
|
|
189
266
|
|
|
267
|
+
Deriving using `ecdsa-sd-2023`:
|
|
268
|
+
|
|
190
269
|
```js
|
|
191
|
-
import * as
|
|
270
|
+
import * as EcdsaMultikey from '@digitalbazaar/ecdsa-multikey';
|
|
192
271
|
import * as ecdsaSd2023Cryptosuite from
|
|
193
272
|
'@digitalbazaar/ecdsa-sd-2023-cryptosuite';
|
|
273
|
+
import * as vc from '@digitalbazaar/vc';
|
|
194
274
|
import {DataIntegrityProof} from '@digitalbazaar/data-integrity';
|
|
195
275
|
|
|
196
276
|
const {
|
|
@@ -199,8 +279,8 @@ const {
|
|
|
199
279
|
createVerifyCryptosuite
|
|
200
280
|
} = ecdsaSd2023Cryptosuite;
|
|
201
281
|
|
|
202
|
-
// sample
|
|
203
|
-
const
|
|
282
|
+
// sample VC
|
|
283
|
+
const verifiableCredential = {
|
|
204
284
|
"@context": [
|
|
205
285
|
"https://www.w3.org/2018/credentials/v1",
|
|
206
286
|
"https://www.w3.org/2018/credentials/examples/v1",
|
|
@@ -218,13 +298,13 @@ const credential = {
|
|
|
218
298
|
"alumniOf": "<span lang=\"en\">Example University</span>"
|
|
219
299
|
},
|
|
220
300
|
"proof": {
|
|
221
|
-
"id": "urn:uuid:
|
|
301
|
+
"id": "urn:uuid:318d9dce-bc7b-40b9-a956-c9160bf910db",
|
|
222
302
|
"type": "DataIntegrityProof",
|
|
223
|
-
"created": "
|
|
303
|
+
"created": "2024-01-12T21:53:11Z",
|
|
224
304
|
"verificationMethod": "https://example.edu/issuers/keys/2",
|
|
225
305
|
"cryptosuite": "ecdsa-sd-2023",
|
|
226
306
|
"proofPurpose": "assertionMethod",
|
|
227
|
-
"proofValue": "
|
|
307
|
+
"proofValue": "u2V0AhVhAsl6PQKYE15R0O5Qd267ntwHGNH6JRvZ1y8A-fTCQLUoupP8SCZzzmyc0a1AnabHEVKhpHtYV8j9Kapp-fHFBtFgjgCQCIMn2L1R7D5VPnNn_2foxdj8qvsuUTGFqA34YBkguzCpYILfJ-qNQpn6_dJGpkG24FynqbHpnzoHWVJc2kiLqEKHRglhAUmZtstR9MOLrZjcR8J303MXFvRiE6J3bbaPT1_I9-6578-Wj-eydv2TEGBq_dmsjxsOh4_2Va0etw8CXXMAzaVhA9fr7_Sl9D67AfvLhkJTZ0uJCAXcbL2MaS-DmoC7K-ABxroL1_wj119J8yTMlazxzYBwYkihrdp4ZWJZxraX9tIJtL2lzc3VhbmNlRGF0ZWcvaXNzdWVy"
|
|
228
308
|
}
|
|
229
309
|
};
|
|
230
310
|
|
|
@@ -250,6 +330,65 @@ const derivedVC = await vc.derive({
|
|
|
250
330
|
console.log(JSON.stringify(derivedVC, null, 2));
|
|
251
331
|
```
|
|
252
332
|
|
|
333
|
+
Deriving using `bbs-2023`:
|
|
334
|
+
|
|
335
|
+
```js
|
|
336
|
+
import * as bbs2023Cryptosuite from '@digitalbazaar/bbs-2023-cryptosuite';
|
|
337
|
+
import * as bls12381Multikey from '@digitalbazaar/bls12-381-multikey';
|
|
338
|
+
import * as vc from '@digitalbazaar/vc';
|
|
339
|
+
import {DataIntegrityProof} from '@digitalbazaar/data-integrity';
|
|
340
|
+
|
|
341
|
+
const {
|
|
342
|
+
createDiscloseCryptosuite,
|
|
343
|
+
createSignCryptosuite,
|
|
344
|
+
createVerifyCryptosuite
|
|
345
|
+
} = bbs2023Cryptosuite;
|
|
346
|
+
|
|
347
|
+
// sample VC
|
|
348
|
+
const verifiableCredential = {
|
|
349
|
+
"@context": [
|
|
350
|
+
"https://www.w3.org/2018/credentials/v1",
|
|
351
|
+
"https://www.w3.org/2018/credentials/examples/v1",
|
|
352
|
+
"https://w3id.org/security/data-integrity/v2"
|
|
353
|
+
],
|
|
354
|
+
"type": [
|
|
355
|
+
"VerifiableCredential",
|
|
356
|
+
"AlumniCredential"
|
|
357
|
+
],
|
|
358
|
+
"issuer": "https://example.edu/issuers/565049",
|
|
359
|
+
"issuanceDate": "2010-01-01T01:00:00Z",
|
|
360
|
+
"credentialSubject": {
|
|
361
|
+
"alumniOf": "<span lang=\"en\">Example University</span>"
|
|
362
|
+
},
|
|
363
|
+
"proof": {
|
|
364
|
+
"type": "DataIntegrityProof",
|
|
365
|
+
"verificationMethod": "https://example.edu/issuers/keys/3",
|
|
366
|
+
"cryptosuite": "bbs-2023",
|
|
367
|
+
"proofPurpose": "assertionMethod",
|
|
368
|
+
"proofValue": "u2V0ChVhQp1smqO-Qmc-1KpNkShjevTeylTdVlpH_RNXeJ_cNniErWPbEWILvsoH5mYjnun5ibZHq0m7BEIaLv8sfMtLfcmgPj6tbAFwDWvEcbRWg7CFYQGWqCAnvTpL_Aao3aVCg5svdzFuvKqnvneA0UwaN0lagvGpWT7fCDGgcYPyNPKaCX94Xo06aTcSwOXgyGUbtN1xYYIU6t5wv20lVdESfzkYOFXTxIZa1HSBAZYWDyEgQ3A3ajzWX5qeFc3cwmnnrGUfJYwawgGLQAY3vBi3LTM2i3jCOPvxCEJALPIjK4tEmWb6uFjT4PWLlIEeTtYj_0yEv91ggsm9vw1PPlK6q8wQiw2i2joZ-OKkvHz7rDSxPYfmQNrqCbS9pc3N1YW5jZURhdGVnL2lzc3Vlcg"
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
// note no `signer` needed; the selective disclosure credential will be
|
|
373
|
+
// derived from the base proof already provided by the issuer
|
|
374
|
+
const suite = new DataIntegrityProof({
|
|
375
|
+
cryptosuite: createDiscloseCryptosuite({
|
|
376
|
+
// selectively disclose the entire credential subject; different JSON
|
|
377
|
+
// pointers could be provided to selectively disclose different information;
|
|
378
|
+
// the issuer will have mandatory fields that will be automatically
|
|
379
|
+
// disclosed such as the `issuer` and `issuanceDate` fields
|
|
380
|
+
selectivePointers: [
|
|
381
|
+
'/credentialSubject'
|
|
382
|
+
]
|
|
383
|
+
})
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
const derivedVC = await vc.derive({
|
|
387
|
+
verifiableCredential, suite, documentLoader
|
|
388
|
+
});
|
|
389
|
+
console.log(JSON.stringify(derivedVC, null, 2));
|
|
390
|
+
```
|
|
391
|
+
|
|
253
392
|
### Creating a Verifiable Presentation
|
|
254
393
|
|
|
255
394
|
Pre-requisites:
|
package/lib/index.js
CHANGED
|
@@ -167,7 +167,8 @@ export async function derive({
|
|
|
167
167
|
documentLoader = defaultDocumentLoader
|
|
168
168
|
} = {}) {
|
|
169
169
|
if(!verifiableCredential) {
|
|
170
|
-
throw new TypeError(
|
|
170
|
+
throw new TypeError(
|
|
171
|
+
'"verifiableCredential" parameter is required for deriving.');
|
|
171
172
|
}
|
|
172
173
|
if(!suite) {
|
|
173
174
|
throw new TypeError('"suite" parameter is required for deriving.');
|
|
@@ -654,10 +655,13 @@ export function _checkCredential({
|
|
|
654
655
|
}
|
|
655
656
|
|
|
656
657
|
if('credentialStatus' in credential) {
|
|
657
|
-
|
|
658
|
+
const {credentialStatus} = credential;
|
|
659
|
+
if(Array.isArray(credentialStatus) ?
|
|
660
|
+
credentialStatus.some(cs => !cs.id) : !credentialStatus.id) {
|
|
658
661
|
throw new Error('"credentialStatus" must include an id.');
|
|
659
662
|
}
|
|
660
|
-
if(Array.isArray(
|
|
663
|
+
if(Array.isArray(credentialStatus) ?
|
|
664
|
+
credentialStatus.some(cs => !cs.type) : !credentialStatus.type) {
|
|
661
665
|
throw new Error('"credentialStatus" must include a type.');
|
|
662
666
|
}
|
|
663
667
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@digitalbazaar/vc",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.3.0",
|
|
4
4
|
"description": "Verifiable Credentials JavaScript library.",
|
|
5
5
|
"homepage": "https://github.com/digitalbazaar/vc",
|
|
6
6
|
"author": {
|
|
@@ -33,6 +33,8 @@
|
|
|
33
33
|
"jsonld-signatures": "^11.2.1"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
+
"@digitalbazaar/bbs-2023-cryptosuite": "^1.0.0",
|
|
37
|
+
"@digitalbazaar/bls12-381-multikey": "^1.1.1",
|
|
36
38
|
"@digitalbazaar/credentials-examples-context": "^1.0.0",
|
|
37
39
|
"@digitalbazaar/data-integrity": "^2.0.0",
|
|
38
40
|
"@digitalbazaar/data-integrity-context": "^2.0.0",
|
|
@@ -72,7 +74,7 @@
|
|
|
72
74
|
]
|
|
73
75
|
},
|
|
74
76
|
"engines": {
|
|
75
|
-
"node": ">=
|
|
77
|
+
"node": ">=18"
|
|
76
78
|
},
|
|
77
79
|
"keywords": [
|
|
78
80
|
"JSON",
|