From 61a1a6c0b146aa3f909babbf149982e6d548fba9 Mon Sep 17 00:00:00 2001 From: "David I. Lehn" Date: Wed, 29 Nov 2023 21:23:35 -0500 Subject: [PATCH 01/13] Add roundtrip example. --- CHANGELOG.md | 5 +++ examples/rt.js | 120 +++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 3 ++ 3 files changed, 128 insertions(+) create mode 100644 examples/rt.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 2906d27a..51c1e6be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # @digitalbazaar/vc ChangeLog +## 7.0.1 - 2024-xx-xx + +### Added +- Example roundtrip issue/verify script. + ## 7.0.0 - 2024-08-01 ### Added diff --git a/examples/rt.js b/examples/rt.js new file mode 100644 index 00000000..060f3b31 --- /dev/null +++ b/examples/rt.js @@ -0,0 +1,120 @@ +/*! + * Copyright (c) 2019-2023 Digital Bazaar, Inc. All rights reserved. + */ + +// Example round trip. +// - generate example ECDSA did:key +// - setup 'ecdsa-rdfc-2019 DataIntegrityProof +// - setup document loader +// - sign credential +// - verify credential + +import * as EcdsaMultikey from '@digitalbazaar/ecdsa-multikey'; +import {cryptosuite as ecdsaRdfc2019Cryptosuite} from + '@digitalbazaar/ecdsa-rdfc-2019-cryptosuite'; +//import * as vc from '@digitalbazaar/vc'; +import * as vc from '../lib/index.js'; +import {DataIntegrityProof} from '@digitalbazaar/data-integrity'; +import {driver} from '@digitalbazaar/did-method-key'; + +// document loader support +import {securityLoader} from '@digitalbazaar/security-document-loader'; + +//import secCtx from '@digitalbazaar/security-context'; +import diCtx from '@digitalbazaar/data-integrity-context'; + +const loader = securityLoader(); +//loader.addStatic( +// secCtx.SECURITY_CONTEXT_V2_URL, +// secCtx.contexts.get(secCtx.SECURITY_CONTEXT_V2_URL) +//); +loader.addStatic(diCtx.CONTEXT_URL, diCtx.CONTEXT); +// example static context +loader.addStatic( + 'https://example.com/ex/v1', + /* eslint-disable quotes, quote-props, max-len */ + { + "@context": { + "ExampleCredential": "https://example.com/ex#Example", + "example": "https://example.com/ex#example" + } + } + /* eslint-enable quotes, quote-props, max-len */ +); + +const documentLoader = loader.build(); + +async function main({credential, documentLoader}) { + // generate example ecdsa keypair + const didKeyDriverMultikey = driver(); + + didKeyDriverMultikey.use({ + multibaseMultikeyHeader: 'zDna', + fromMultibase: EcdsaMultikey.from + }); + + const ecdsaKeyPair = await EcdsaMultikey.generate({curve: 'P-256'}); + + const { + didDocument, keyPairs, methodFor + } = await didKeyDriverMultikey.fromKeyPair({ + verificationKeyPair: ecdsaKeyPair + }); + ecdsaKeyPair.id = didDocument.assertionMethod[0]; + ecdsaKeyPair.controller = didDocument.id; + + // setup ecdsa-rdfc-2019 suite + const suite = new DataIntegrityProof({ + signer: ecdsaKeyPair.signer(), + // date: '2023-01-01T01:01:01Z', + cryptosuite: ecdsaRdfc2019Cryptosuite + }); + + // setup documentLoader + + // sign credential + const verifiableCredential = await vc.issue({ + credential, + suite, + documentLoader + }); + // verify signed credential + const verifyResult = await vc.verifyCredential({ + credential: verifiableCredential, + suite, + documentLoader + }); + + console.log('INPUT CREDENTIAL:'); + console.log(JSON.stringify(credential, null, 2)); + console.log('SIGNED CREDENTIAL:'); + console.log(JSON.stringify(verifiableCredential, null, 2)); + console.log('VERIFY RESULT:'); + console.log(verifyResult); +} + +// sample unsigned credential +const credential = +// Use plain JSON style for data +/* eslint-disable quotes, quote-props, max-len */ +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://example.com/ex/v1" + ], + "id": "https://example.com/credentials/1872", + "type": ["VerifiableCredential", "ExampleCredential"], + "issuer": "https://example.edu/issuers/565049", + "issuanceDate": "2010-01-01T19:23:24Z", + "credentialSubject": { + "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", + "example": "Example Data" + } +} +/* eslint-enable quotes, quote-props, max-len */ +; + +await main({ + credential, + documentLoader +}); diff --git a/package.json b/package.json index 349b6f62..b271a1f4 100644 --- a/package.json +++ b/package.json @@ -39,12 +39,15 @@ "@digitalbazaar/credentials-examples-context": "^1.0.0", "@digitalbazaar/data-integrity": "^2.2.0", "@digitalbazaar/data-integrity-context": "^2.0.1", + "@digitalbazaar/did-method-key": "^5.1.0", "@digitalbazaar/ecdsa-multikey": "^1.7.0", + "@digitalbazaar/ecdsa-rdfc-2019-cryptosuite": "^1.0.1", "@digitalbazaar/ecdsa-sd-2023-cryptosuite": "^3.2.1", "@digitalbazaar/ed25519-signature-2018": "^4.0.0", "@digitalbazaar/ed25519-verification-key-2018": "^4.0.0", "@digitalbazaar/multikey-context": "^2.0.1", "@digitalbazaar/odrl-context": "^1.0.0", + "@digitalbazaar/security-document-loader": "^2.0.0", "c8": "^10.1.2", "chai": "^4.5.0", "cross-env": "^7.0.3", From bbdaffa2247c44c2207ee1a54cffd1a363f39cf8 Mon Sep 17 00:00:00 2001 From: "David I. Lehn" Date: Wed, 29 Nov 2023 21:51:28 -0500 Subject: [PATCH 02/13] Example updates. - Use verify suite. - Add multikey resolver. --- examples/rt.js | 32 +++++++++++++++++++++----------- package.json | 1 + 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/examples/rt.js b/examples/rt.js index 060f3b31..c72eda8c 100644 --- a/examples/rt.js +++ b/examples/rt.js @@ -17,7 +17,8 @@ import * as vc from '../lib/index.js'; import {DataIntegrityProof} from '@digitalbazaar/data-integrity'; import {driver} from '@digitalbazaar/did-method-key'; -// document loader support +// setup document loader +import {CachedResolver} from '@digitalbazaar/did-io'; import {securityLoader} from '@digitalbazaar/security-document-loader'; //import secCtx from '@digitalbazaar/security-context'; @@ -41,17 +42,20 @@ loader.addStatic( } /* eslint-enable quotes, quote-props, max-len */ ); +const resolver = new CachedResolver(); +const didKeyDriverMultikey = driver(); + +didKeyDriverMultikey.use({ + multibaseMultikeyHeader: 'zDna', + fromMultibase: EcdsaMultikey.from +}); +resolver.use(didKeyDriverMultikey); +loader.setDidResolver(resolver); const documentLoader = loader.build(); async function main({credential, documentLoader}) { // generate example ecdsa keypair - const didKeyDriverMultikey = driver(); - - didKeyDriverMultikey.use({ - multibaseMultikeyHeader: 'zDna', - fromMultibase: EcdsaMultikey.from - }); const ecdsaKeyPair = await EcdsaMultikey.generate({curve: 'P-256'}); @@ -63,8 +67,8 @@ async function main({credential, documentLoader}) { ecdsaKeyPair.id = didDocument.assertionMethod[0]; ecdsaKeyPair.controller = didDocument.id; - // setup ecdsa-rdfc-2019 suite - const suite = new DataIntegrityProof({ + // setup ecdsa-rdfc-2019 signing suite + const signingSuite = new DataIntegrityProof({ signer: ecdsaKeyPair.signer(), // date: '2023-01-01T01:01:01Z', cryptosuite: ecdsaRdfc2019Cryptosuite @@ -75,13 +79,19 @@ async function main({credential, documentLoader}) { // sign credential const verifiableCredential = await vc.issue({ credential, - suite, + suite: signingSuite, documentLoader }); + + // setup ecdsa-rdfc-2019 verifying suite + const verifyingSuite = new DataIntegrityProof({ + cryptosuite: ecdsaRdfc2019Cryptosuite + }); + // verify signed credential const verifyResult = await vc.verifyCredential({ credential: verifiableCredential, - suite, + suite: verifyingSuite, documentLoader }); diff --git a/package.json b/package.json index b271a1f4..39187a70 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "@digitalbazaar/credentials-examples-context": "^1.0.0", "@digitalbazaar/data-integrity": "^2.2.0", "@digitalbazaar/data-integrity-context": "^2.0.1", + "@digitalbazaar/did-io": "^2.0.0", "@digitalbazaar/did-method-key": "^5.1.0", "@digitalbazaar/ecdsa-multikey": "^1.7.0", "@digitalbazaar/ecdsa-rdfc-2019-cryptosuite": "^1.0.1", From c7d174eebc7b5f9e61a057b769c42efdaa94a83c Mon Sep 17 00:00:00 2001 From: Dave Longley Date: Wed, 29 Nov 2023 21:58:24 -0500 Subject: [PATCH 03/13] Ensure VC issuer matches key controller. --- examples/rt.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/rt.js b/examples/rt.js index c72eda8c..b92485a9 100644 --- a/examples/rt.js +++ b/examples/rt.js @@ -67,6 +67,9 @@ async function main({credential, documentLoader}) { ecdsaKeyPair.id = didDocument.assertionMethod[0]; ecdsaKeyPair.controller = didDocument.id; + // ensure issuer matches key controller + credential.issuer = ecdsaKeyPair.controller; + // setup ecdsa-rdfc-2019 signing suite const signingSuite = new DataIntegrityProof({ signer: ecdsaKeyPair.signer(), @@ -100,7 +103,7 @@ async function main({credential, documentLoader}) { console.log('SIGNED CREDENTIAL:'); console.log(JSON.stringify(verifiableCredential, null, 2)); console.log('VERIFY RESULT:'); - console.log(verifyResult); + console.log(JSON.stringify(verifyResult, null, 2)); } // sample unsigned credential From c6e16c8f18be5b0b7a8921e4c0e5dc1f69f9bc3b Mon Sep 17 00:00:00 2001 From: "David I. Lehn" Date: Mon, 12 Aug 2024 15:00:03 -0400 Subject: [PATCH 04/13] Update example dependencies. --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 39187a70..ce2742d9 100644 --- a/package.json +++ b/package.json @@ -40,15 +40,15 @@ "@digitalbazaar/data-integrity": "^2.2.0", "@digitalbazaar/data-integrity-context": "^2.0.1", "@digitalbazaar/did-io": "^2.0.0", - "@digitalbazaar/did-method-key": "^5.1.0", + "@digitalbazaar/did-method-key": "^5.2.0", "@digitalbazaar/ecdsa-multikey": "^1.7.0", - "@digitalbazaar/ecdsa-rdfc-2019-cryptosuite": "^1.0.1", + "@digitalbazaar/ecdsa-rdfc-2019-cryptosuite": "^1.1.0", "@digitalbazaar/ecdsa-sd-2023-cryptosuite": "^3.2.1", "@digitalbazaar/ed25519-signature-2018": "^4.0.0", "@digitalbazaar/ed25519-verification-key-2018": "^4.0.0", "@digitalbazaar/multikey-context": "^2.0.1", "@digitalbazaar/odrl-context": "^1.0.0", - "@digitalbazaar/security-document-loader": "^2.0.0", + "@digitalbazaar/security-document-loader": "^3.0.0", "c8": "^10.1.2", "chai": "^4.5.0", "cross-env": "^7.0.3", From 4019c7f9958a48a3ff977be388c7d4792e37f29e Mon Sep 17 00:00:00 2001 From: "David I. Lehn" Date: Mon, 12 Aug 2024 15:02:34 -0400 Subject: [PATCH 05/13] Update loader usage. --- examples/rt.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/examples/rt.js b/examples/rt.js index b92485a9..da4d7eeb 100644 --- a/examples/rt.js +++ b/examples/rt.js @@ -21,15 +21,12 @@ import {driver} from '@digitalbazaar/did-method-key'; import {CachedResolver} from '@digitalbazaar/did-io'; import {securityLoader} from '@digitalbazaar/security-document-loader'; -//import secCtx from '@digitalbazaar/security-context'; -import diCtx from '@digitalbazaar/data-integrity-context'; +//import {contexts as secContexts} from '@digitalbazaar/security-context'; +import {contexts as diContexts} from '@digitalbazaar/data-integrity-context'; const loader = securityLoader(); -//loader.addStatic( -// secCtx.SECURITY_CONTEXT_V2_URL, -// secCtx.contexts.get(secCtx.SECURITY_CONTEXT_V2_URL) -//); -loader.addStatic(diCtx.CONTEXT_URL, diCtx.CONTEXT); +//loader.addDocuments({documents: secContexts}); +loader.addDocuments({documents: diContexts}); // example static context loader.addStatic( 'https://example.com/ex/v1', From 9cd329034360f6dde951157405c46514e95360e1 Mon Sep 17 00:00:00 2001 From: "David I. Lehn" Date: Mon, 12 Aug 2024 15:02:45 -0400 Subject: [PATCH 06/13] Fix lint issue. --- examples/rt.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/rt.js b/examples/rt.js index da4d7eeb..8c0815d5 100644 --- a/examples/rt.js +++ b/examples/rt.js @@ -57,7 +57,7 @@ async function main({credential, documentLoader}) { const ecdsaKeyPair = await EcdsaMultikey.generate({curve: 'P-256'}); const { - didDocument, keyPairs, methodFor + didDocument/*, keyPairs, methodFor*/ } = await didKeyDriverMultikey.fromKeyPair({ verificationKeyPair: ecdsaKeyPair }); From e02e347aa5bd4a940e08cc80d8f782dd81f6808e Mon Sep 17 00:00:00 2001 From: "David I. Lehn" Date: Tue, 13 Aug 2024 14:52:24 -0400 Subject: [PATCH 07/13] Update copyright date. Co-authored-by: Dave Longley --- examples/rt.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/rt.js b/examples/rt.js index 8c0815d5..1ef6690b 100644 --- a/examples/rt.js +++ b/examples/rt.js @@ -1,5 +1,5 @@ /*! - * Copyright (c) 2019-2023 Digital Bazaar, Inc. All rights reserved. + * Copyright (c) 2019-2024 Digital Bazaar, Inc. All rights reserved. */ // Example round trip. From ead6fce5d4476bcd650821eebb9f8024178aa19b Mon Sep 17 00:00:00 2001 From: "David I. Lehn" Date: Wed, 14 Aug 2024 00:10:02 -0400 Subject: [PATCH 08/13] Add VP support to example. - Adding VP support to futher expand the example. - Using did:key for VC and did:web for VP to add variety. - Print out logging as we go. - Print readable first stack trace if there are verify errors. --- examples/rt.js | 162 +++++++++++++++++++++++++++++++++++++++---------- package.json | 1 + 2 files changed, 132 insertions(+), 31 deletions(-) diff --git a/examples/rt.js b/examples/rt.js index 1ef6690b..dba38d9d 100644 --- a/examples/rt.js +++ b/examples/rt.js @@ -3,19 +3,28 @@ */ // Example round trip. -// - generate example ECDSA did:key +// - generate example ECDSA did:key for VC // - setup 'ecdsa-rdfc-2019 DataIntegrityProof -// - setup document loader -// - sign credential +// - setup document loader including did:key and did:web resolvers +// - sign credential with did:key // - verify credential +// - generate example ECDSA did:web doc for VP +// - create presentation +// - sign presentation with did:web +// - verify presentation +import * as DidKey from '@digitalbazaar/did-method-key'; +import * as DidWeb from '@digitalbazaar/did-method-web'; import * as EcdsaMultikey from '@digitalbazaar/ecdsa-multikey'; -import {cryptosuite as ecdsaRdfc2019Cryptosuite} from - '@digitalbazaar/ecdsa-rdfc-2019-cryptosuite'; +import { + cryptosuite as ecdsaRdfc2019Cryptosuite +} from '@digitalbazaar/ecdsa-rdfc-2019-cryptosuite'; //import * as vc from '@digitalbazaar/vc'; import * as vc from '../lib/index.js'; import {DataIntegrityProof} from '@digitalbazaar/data-integrity'; -import {driver} from '@digitalbazaar/did-method-key'; +//import { +// Ed25519VerificationKey2020 +//} from '@digitalbazaar/ed25519-verification-key-2020'; // setup document loader import {CachedResolver} from '@digitalbazaar/did-io'; @@ -24,6 +33,7 @@ import {securityLoader} from '@digitalbazaar/security-document-loader'; //import {contexts as secContexts} from '@digitalbazaar/security-context'; import {contexts as diContexts} from '@digitalbazaar/data-integrity-context'; +// setup documentLoader const loader = securityLoader(); //loader.addDocuments({documents: secContexts}); loader.addDocuments({documents: diContexts}); @@ -40,67 +50,158 @@ loader.addStatic( /* eslint-enable quotes, quote-props, max-len */ ); const resolver = new CachedResolver(); -const didKeyDriverMultikey = driver(); +const didKeyDriverMultikey = DidKey.driver(); +const didWebDriver = DidWeb.driver(); didKeyDriverMultikey.use({ multibaseMultikeyHeader: 'zDna', fromMultibase: EcdsaMultikey.from }); +didWebDriver.use({ + multibaseMultikeyHeader: 'zDna', + fromMultibase: EcdsaMultikey.from + //name: 'Ed25519', + //handler: Ed25519VerificationKey2020, + //multibaseMultikeyHeader: 'z6Mk', + //fromMultibase: Ed25519VerificationKey2020.from +}); resolver.use(didKeyDriverMultikey); +resolver.use(didWebDriver); loader.setDidResolver(resolver); const documentLoader = loader.build(); async function main({credential, documentLoader}) { - // generate example ecdsa keypair + console.log('CREDENTIAL:'); + console.log(JSON.stringify(credential, null, 2)); - const ecdsaKeyPair = await EcdsaMultikey.generate({curve: 'P-256'}); + // generate example ecdsa keypair for VC + const vcEcdsaKeyPair = await EcdsaMultikey.generate({curve: 'P-256'}); const { - didDocument/*, keyPairs, methodFor*/ + didDocument: vcDidDocument/*, keyPairs, methodFor*/ } = await didKeyDriverMultikey.fromKeyPair({ - verificationKeyPair: ecdsaKeyPair + verificationKeyPair: vcEcdsaKeyPair }); - ecdsaKeyPair.id = didDocument.assertionMethod[0]; - ecdsaKeyPair.controller = didDocument.id; + vcEcdsaKeyPair.id = vcDidDocument.assertionMethod[0]; + vcEcdsaKeyPair.controller = vcDidDocument.id; // ensure issuer matches key controller - credential.issuer = ecdsaKeyPair.controller; + credential.issuer = vcEcdsaKeyPair.controller; // setup ecdsa-rdfc-2019 signing suite - const signingSuite = new DataIntegrityProof({ - signer: ecdsaKeyPair.signer(), + const vcSigningSuite = new DataIntegrityProof({ + signer: vcEcdsaKeyPair.signer(), // date: '2023-01-01T01:01:01Z', cryptosuite: ecdsaRdfc2019Cryptosuite }); - // setup documentLoader - // sign credential const verifiableCredential = await vc.issue({ credential, - suite: signingSuite, + suite: vcSigningSuite, documentLoader }); - // setup ecdsa-rdfc-2019 verifying suite - const verifyingSuite = new DataIntegrityProof({ + console.log('SIGNED CREDENTIAL:'); + console.log(JSON.stringify(verifiableCredential, null, 2)); + + // setup VC ecdsa-rdfc-2019 verifying suite + const vcVerifyingSuite = new DataIntegrityProof({ cryptosuite: ecdsaRdfc2019Cryptosuite }); // verify signed credential - const verifyResult = await vc.verifyCredential({ + const verifyCredentialResult = await vc.verifyCredential({ credential: verifiableCredential, - suite: verifyingSuite, + suite: vcVerifyingSuite, documentLoader }); - console.log('INPUT CREDENTIAL:'); - console.log(JSON.stringify(credential, null, 2)); - console.log('SIGNED CREDENTIAL:'); - console.log(JSON.stringify(verifiableCredential, null, 2)); - console.log('VERIFY RESULT:'); - console.log(JSON.stringify(verifyResult, null, 2)); + console.log('VERIFY CREDENTIAL RESULT:'); + console.log(JSON.stringify(verifyCredentialResult, null, 2)); + if(verifyCredentialResult.error) { + console.log('VP ERROR STACK:', + verifyCredentialResult.error.errors[0].stack); + } + + // setup example for did:web + //const VP_DID = 'did:web:example.org:issuer:123'; + const VP_DID_URL = 'https://example.org/issuer/123'; + //const VP_DID_DOC_URL = VP_DID_URL + '/did.json'; + + // generate example ed25519 keypair for VP signer + const vpEcdsaKeyPair = await EcdsaMultikey.generate({curve: 'P-256'}); + const { + didDocument: vpDidDocument, methodFor: vpMethodFor + } = await didWebDriver.fromKeyPair({ + url: VP_DID_URL, + verificationKeyPair: vpEcdsaKeyPair + }); + const didWebKey = vpMethodFor({purpose: 'assertionMethod'}); + vcEcdsaKeyPair.id = didWebKey.id; + vcEcdsaKeyPair.controller = vpDidDocument.id; + // setup VP ecdsa-rdfc-2019 signing suite + const vpSigningSuite = new DataIntegrityProof({ + signer: vcEcdsaKeyPair.signer(), + // date: '2023-01-01T01:01:01Z', + cryptosuite: ecdsaRdfc2019Cryptosuite + }); + + // add static verification method result + // FIXME + // The document loader usually would send did:web URLs to did-method-web + // which would fetch the DID Document and calculate the result for this from + // the fragment. Adding a static version here directly to avoid network + // request for this example. This is fragile and for this example only. + // Ideally did-method-web driver would support a document loader like + // interface that could handle VP_DID or VP_DID_DOC_URL. + const vpDidVm = structuredClone(vpDidDocument.verificationMethod[0]); + vpDidVm['@context'] = 'https://w3id.org/security/multikey/v1'; + loader.addStatic(vpDidVm.id, vpDidVm); + + // presentation challenge + const challenge = 'abc123'; + + // presentation holder + const holder = 'did:web:example.com:holder:456'; + + const presentation = await vc.createPresentation({ + verifiableCredential, + holder + }); + + console.log('PRESENTATION:'); + console.log(JSON.stringify(presentation, null, 2)); + + // sign presentation + // note this adds the proof to the input presentation + const vp = await vc.signPresentation({ + presentation, suite: vpSigningSuite, challenge, documentLoader + }); + + console.log('SIGNED PRESENTATION:'); + console.log(JSON.stringify(vp, null, 2)); + + // setup VP ecdsa-rdfc-2019 verifying suite + const vpVerifyingSuite = new DataIntegrityProof({ + cryptosuite: ecdsaRdfc2019Cryptosuite + }); + + // verify signed presentation + const verifyPresentationResult = await vc.verify({ + presentation: vp, + challenge, + suite: vpVerifyingSuite, + documentLoader + }); + + console.log('VERIFY PRESENTATION RESULT:'); + console.log(JSON.stringify(verifyPresentationResult, null, 2)); + if(verifyPresentationResult.error) { + console.log('VP ERROR STACK:', + verifyPresentationResult.error.errors[0].stack); + } } // sample unsigned credential @@ -121,8 +222,7 @@ const credential = "example": "Example Data" } } -/* eslint-enable quotes, quote-props, max-len */ -; +/* eslint-enable quotes, quote-props, max-len */; await main({ credential, diff --git a/package.json b/package.json index ce2742d9..0c388443 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "@digitalbazaar/data-integrity-context": "^2.0.1", "@digitalbazaar/did-io": "^2.0.0", "@digitalbazaar/did-method-key": "^5.2.0", + "@digitalbazaar/did-method-web": "^1.0.1", "@digitalbazaar/ecdsa-multikey": "^1.7.0", "@digitalbazaar/ecdsa-rdfc-2019-cryptosuite": "^1.1.0", "@digitalbazaar/ecdsa-sd-2023-cryptosuite": "^3.2.1", From 3ab6f6d9afb3b88f2e06b460fc005061ae80c3e8 Mon Sep 17 00:00:00 2001 From: "David I. Lehn" Date: Wed, 14 Aug 2024 01:46:41 -0400 Subject: [PATCH 09/13] Order imports. --- examples/rt.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/rt.js b/examples/rt.js index dba38d9d..ebaa4802 100644 --- a/examples/rt.js +++ b/examples/rt.js @@ -21,13 +21,11 @@ import { } from '@digitalbazaar/ecdsa-rdfc-2019-cryptosuite'; //import * as vc from '@digitalbazaar/vc'; import * as vc from '../lib/index.js'; +import {CachedResolver} from '@digitalbazaar/did-io'; import {DataIntegrityProof} from '@digitalbazaar/data-integrity'; //import { // Ed25519VerificationKey2020 //} from '@digitalbazaar/ed25519-verification-key-2020'; - -// setup document loader -import {CachedResolver} from '@digitalbazaar/did-io'; import {securityLoader} from '@digitalbazaar/security-document-loader'; //import {contexts as secContexts} from '@digitalbazaar/security-context'; From 368be0fc2289f5276ccae17ee91120b71ac32ab2 Mon Sep 17 00:00:00 2001 From: "David I. Lehn" Date: Wed, 14 Aug 2024 01:46:55 -0400 Subject: [PATCH 10/13] Fix typo. --- examples/rt.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/rt.js b/examples/rt.js index ebaa4802..4cd67ab1 100644 --- a/examples/rt.js +++ b/examples/rt.js @@ -141,7 +141,7 @@ async function main({credential, documentLoader}) { vcEcdsaKeyPair.controller = vpDidDocument.id; // setup VP ecdsa-rdfc-2019 signing suite const vpSigningSuite = new DataIntegrityProof({ - signer: vcEcdsaKeyPair.signer(), + signer: vpEcdsaKeyPair.signer(), // date: '2023-01-01T01:01:01Z', cryptosuite: ecdsaRdfc2019Cryptosuite }); From 62c6081a91861f9884c0447ce46d7d29e757982a Mon Sep 17 00:00:00 2001 From: "David I. Lehn" Date: Wed, 14 Aug 2024 02:14:01 -0400 Subject: [PATCH 11/13] Fixes. - Add static DID Document to loader. - Fix typos. --- examples/rt.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/examples/rt.js b/examples/rt.js index 4cd67ab1..08442f4b 100644 --- a/examples/rt.js +++ b/examples/rt.js @@ -124,7 +124,7 @@ async function main({credential, documentLoader}) { } // setup example for did:web - //const VP_DID = 'did:web:example.org:issuer:123'; + const VP_DID = 'did:web:example.org:issuer:123'; const VP_DID_URL = 'https://example.org/issuer/123'; //const VP_DID_DOC_URL = VP_DID_URL + '/did.json'; @@ -137,8 +137,8 @@ async function main({credential, documentLoader}) { verificationKeyPair: vpEcdsaKeyPair }); const didWebKey = vpMethodFor({purpose: 'assertionMethod'}); - vcEcdsaKeyPair.id = didWebKey.id; - vcEcdsaKeyPair.controller = vpDidDocument.id; + vpEcdsaKeyPair.id = didWebKey.id; + vpEcdsaKeyPair.controller = vpDidDocument.id; // setup VP ecdsa-rdfc-2019 signing suite const vpSigningSuite = new DataIntegrityProof({ signer: vpEcdsaKeyPair.signer(), @@ -146,6 +146,10 @@ async function main({credential, documentLoader}) { cryptosuite: ecdsaRdfc2019Cryptosuite }); + // add static resources + loader.addStatic(VP_DID, vpDidDocument); + //loader.addStatic(VP_DID_DOC_URL, vpDidDocument); + // add static verification method result // FIXME // The document loader usually would send did:web URLs to did-method-web From 6362466dfce8675c783df5a4a4524af2bf26f4df Mon Sep 17 00:00:00 2001 From: "David I. Lehn" Date: Wed, 14 Aug 2024 13:39:32 -0400 Subject: [PATCH 12/13] Fixes and updates. - Use P-256 for VC and P-384 for VP for variety. - Add P-384 support to did:web driver. - Use 'authentication' method from VP did:web document. --- examples/rt.js | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/examples/rt.js b/examples/rt.js index 08442f4b..53f0e4cf 100644 --- a/examples/rt.js +++ b/examples/rt.js @@ -3,12 +3,12 @@ */ // Example round trip. -// - generate example ECDSA did:key for VC +// - generate example ECDSA P-256 did:key for VC // - setup 'ecdsa-rdfc-2019 DataIntegrityProof // - setup document loader including did:key and did:web resolvers // - sign credential with did:key // - verify credential -// - generate example ECDSA did:web doc for VP +// - generate example ECDSA P-384 did:web doc for VP // - create presentation // - sign presentation with did:web // - verify presentation @@ -55,13 +55,21 @@ didKeyDriverMultikey.use({ multibaseMultikeyHeader: 'zDna', fromMultibase: EcdsaMultikey.from }); +//didWebDriver.use({ +// name: 'Ed25519', +// handler: Ed25519VerificationKey2020, +// multibaseMultikeyHeader: 'z6Mk', +// fromMultibase: Ed25519VerificationKey2020.from +//}); +// P-256 didWebDriver.use({ multibaseMultikeyHeader: 'zDna', fromMultibase: EcdsaMultikey.from - //name: 'Ed25519', - //handler: Ed25519VerificationKey2020, - //multibaseMultikeyHeader: 'z6Mk', - //fromMultibase: Ed25519VerificationKey2020.from +}); +// P-384 +didWebDriver.use({ + multibaseMultikeyHeader: 'z82L', + fromMultibase: EcdsaMultikey.from }); resolver.use(didKeyDriverMultikey); resolver.use(didWebDriver); @@ -73,7 +81,7 @@ async function main({credential, documentLoader}) { console.log('CREDENTIAL:'); console.log(JSON.stringify(credential, null, 2)); - // generate example ecdsa keypair for VC + // generate example keypair for VC signer const vcEcdsaKeyPair = await EcdsaMultikey.generate({curve: 'P-256'}); const { @@ -128,15 +136,15 @@ async function main({credential, documentLoader}) { const VP_DID_URL = 'https://example.org/issuer/123'; //const VP_DID_DOC_URL = VP_DID_URL + '/did.json'; - // generate example ed25519 keypair for VP signer - const vpEcdsaKeyPair = await EcdsaMultikey.generate({curve: 'P-256'}); + // generate example keypair for VP signer + const vpEcdsaKeyPair = await EcdsaMultikey.generate({curve: 'P-384'}); const { didDocument: vpDidDocument, methodFor: vpMethodFor } = await didWebDriver.fromKeyPair({ url: VP_DID_URL, verificationKeyPair: vpEcdsaKeyPair }); - const didWebKey = vpMethodFor({purpose: 'assertionMethod'}); + const didWebKey = vpMethodFor({purpose: 'authentication'}); vpEcdsaKeyPair.id = didWebKey.id; vpEcdsaKeyPair.controller = vpDidDocument.id; // setup VP ecdsa-rdfc-2019 signing suite From 2673e516a7d8ae60b10a9445e599b23f07a79591 Mon Sep 17 00:00:00 2001 From: "David I. Lehn" Date: Wed, 14 Aug 2024 14:42:09 -0400 Subject: [PATCH 13/13] Update VP params. - Add optional domain for example. - Formatting. --- examples/rt.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/examples/rt.js b/examples/rt.js index 53f0e4cf..7387cbaa 100644 --- a/examples/rt.js +++ b/examples/rt.js @@ -170,11 +170,12 @@ async function main({credential, documentLoader}) { vpDidVm['@context'] = 'https://w3id.org/security/multikey/v1'; loader.addStatic(vpDidVm.id, vpDidVm); - // presentation challenge - const challenge = 'abc123'; - // presentation holder const holder = 'did:web:example.com:holder:456'; + // presentation challenge - required for authentication proof purpose + const challenge = 'abc123'; + // preentation domain - optional in this use case + const domain = 'https://example.com/'; const presentation = await vc.createPresentation({ verifiableCredential, @@ -187,7 +188,11 @@ async function main({credential, documentLoader}) { // sign presentation // note this adds the proof to the input presentation const vp = await vc.signPresentation({ - presentation, suite: vpSigningSuite, challenge, documentLoader + presentation, + suite: vpSigningSuite, + challenge, + domain, + documentLoader }); console.log('SIGNED PRESENTATION:');