@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.
Files changed (3) hide show
  1. package/README.md +149 -10
  2. package/lib/index.js +7 -3
  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 14+ are supported.
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 vc from '@digitalbazaar/vc';
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 vc from '@digitalbazaar/vc';
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 signed credential
203
- const credential = {
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:2ef8c7ce-a4da-44b4-ba7f-3d43eaf1e50c",
301
+ "id": "urn:uuid:318d9dce-bc7b-40b9-a956-c9160bf910db",
222
302
  "type": "DataIntegrityProof",
223
- "created": "2023-11-13T22:58:06Z",
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": "u2V0AhVhAtYPKUQxwULXzMdsAfqtipsiX6YEPURYSBFYxoFY-v0vCPyAs1Ckyy61Wtk3xZWyBGNaEr3w0wQiJHHd5B9uR-1gjgCQCVtFPMk-ECi0CJFYv_GTjCChf8St0FQjuExTAnwP0-ipYIOHSun3YqabOfNe2DYFkHBTZa0Csf1a7YUDW8hhsOHqTglhA8aqnyanT-Ybo2-aHBTcI-UmHX0iluGb2IxoHLLhQoOPm2rDW0eB04Fa2Dh6WMKoOl_Bz3wZZDGQ31XoGrQvgIlhAo8qspvC-QQ-xI3KADiA12sO5LRsZ7hl9ozoJEECVsDOKlxWd-dhices5b2ZQIiiRE9XxxJx8YuwCMoD2bRLbOIJtL2lzc3VhbmNlRGF0ZWcvaXNzdWVy"
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('"credential" parameter is required for deriving.');
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
- if(Array.isArray(credential.credentialStatus) ? credential.credentialStatus.some(cs => !cs.id) : !credential.credentialStatus.id) {
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(credential.credentialStatus) ? credential.credentialStatus.some(cs => !cs.type) : !credential.credentialStatus.type) {
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.2.0",
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": ">=14"
77
+ "node": ">=18"
76
78
  },
77
79
  "keywords": [
78
80
  "JSON",