From 545d114a712e78b6795bea378c867f911662592c Mon Sep 17 00:00:00 2001 From: gabe Date: Tue, 25 Jun 2024 21:58:52 -0700 Subject: [PATCH 1/5] some progress --- index.html | 35 ++++++++++++++++++++++++++++++++++- src/jose.js | 18 +++++++----------- src/sd-jwt.js | 13 ++++++------- 3 files changed, 47 insertions(+), 19 deletions(-) diff --git a/index.html b/index.html index 927f62e..76a3cf5 100644 --- a/index.html +++ b/index.html @@ -80,7 +80,40 @@

Basic Example

} } } - + +
+{
+  // set the context, which establishes the special terms we will be using.
+  "@context": [
+    "https://www.w3.org/ns/credentials/v2",
+    "https://www.w3.org/ns/credentials/examples/v2"
+  ],
+  // specify the identifier for the presentation
+  "id": "http://example.edu/presentations/1872",
+  // the presentation type, which declare what data to expect in the presentation
+  "type": "VerifiablePresentation",
+  // when the presentation was issued
+  "validFrom": "2010-01-01T19:23:24Z",
+  // credentials in the presentation
+  "verifiableCredential": [
+    {
+      "@context": "https://www.w3.org/ns/credentials/v2",
+      "id": "data:application/vc-ld+cose;base64url,UXpWalYuLi5STWpV",
+      "type": "EnvelopedVerifiableCredential"
+    },
+    {
+      "@context": "https://www.w3.org/ns/credentials/v2",
+      "id": "data:application/vc-ld+jwt;eyVjV...RMjU",
+      "type": "EnvelopedVerifiableCredential"
+    },
+    {
+      "@context": "https://www.w3.org/ns/credentials/v2",
+      "id": "data:application/vc-ld+sd-jwt;eyVjV...RMjU",
+      "type": "EnvelopedVerifiableCredential"
+    }
+  ]
+}
+  
diff --git a/src/jose.js b/src/jose.js index b4401f0..c12ce1a 100644 --- a/src/jose.js +++ b/src/jose.js @@ -10,14 +10,11 @@ import * as jose from 'jose'; const getCredential = async ( privateKey, byteSigner, - messageType, messageJson ) => { - let oldMessageType = (messageType === 'application/vc+jwt') - ? 'application/vc+ld+json+jwt' : 'application/vp+ld+json+jwt'; return issuer({ alg: privateKey.alg, - type: oldMessageType, + type: 'application/vc+ld+json+jwt', signer: byteSigner, }).issue({ claimset: new TextEncoder().encode(JSON.stringify(messageJson, null, 2)), @@ -27,7 +24,6 @@ const getCredential = async ( const getPresentation = async ( privateKey, byteSigner, - messageType, message ) => { const disclosures = (message.verifiableCredential || []).map(enveloped => { @@ -44,7 +40,7 @@ const getPresentation = async ( }); return holder({ alg: privateKey.alg, - type: messageType, + type: 'application/vp+ld+json+jwt', }).issue({ signer: byteSigner, presentation: message, @@ -75,11 +71,11 @@ const getBinaryMessage = async (privateKey, messageType, messageJson) => { }, }; switch(messageType) { - case 'application/vc+jwt': { - return getCredential(privateKey, byteSigner, messageType, messageJson); + case 'application/vc-ld+jwt': { + return getCredential(privateKey, byteSigner, messageJson); } - case 'application/vp+jwt': { - return getPresentation(privateKey, byteSigner, messageType, messageJson); + case 'application/vp-ld+jwt': { + return getPresentation(privateKey, byteSigner, messageJson); } default: { throw new Error('Unknown message type'); @@ -91,7 +87,7 @@ export const getJoseExample = async (privateKey, messageJson) => { const type = Array.isArray(messageJson.type) ? messageJson.type : [messageJson.type]; const messageType = type.includes('VerifiableCredential') ? - 'application/vc+jwt' : 'application/vp+jwt'; + 'application/vc-ld+jwt' : 'application/vp-ld+jwt'; const message = await getBinaryMessage(privateKey, messageType, messageJson); const messageEncoded = new TextDecoder().decode(message); const decodedHeader = jose.decodeProtectedHeader(messageEncoded); diff --git a/src/sd-jwt.js b/src/sd-jwt.js index 82c8d40..9292b3f 100644 --- a/src/sd-jwt.js +++ b/src/sd-jwt.js @@ -80,9 +80,8 @@ const getCredential = async ( messageType, messageJson, ) => { - let oldMessageType = (messageType === 'application/vc+sd-jwt') - ? 'application/vc+ld+json+sd-jwt' : 'application/vp+ld+json+sd-jwt'; - + const oldMessageType = (messageType === 'application/vc-ld+sd-jwt') ? + 'application/vc+ld+json+sd-jwt' : 'application/vp+ld+json+sd-jwt'; return issuer({ alg: privateKey.alg, type: oldMessageType, @@ -98,7 +97,7 @@ const getPresentation = async ( messageType, messageJson, ) => { - const mediaType = 'application/vc+sd-jwt'; + const mediaType = 'application/vp-ld+sd-jwt'; return getCredential(privateKey, byteSigner, mediaType, messageJson); }; @@ -119,10 +118,10 @@ export const getBinaryMessage = async ( }, }; switch(messageType) { - case 'application/vc+sd-jwt': { + case 'application/vc-ld+sd-jwt': { return getCredential(privateKey, byteSigner, messageType, messageJson); } - case 'application/vp+sd-jwt': { + case 'application/vp-ld+sd-jwt': { return getPresentation(privateKey, byteSigner, messageType, messageJson); } default: { @@ -140,7 +139,7 @@ export const getSdJwtExample = async ( const type = Array.isArray(messageJson.type) ? messageJson.type : [messageJson.type]; const messageType = type.includes('VerifiableCredential') ? - 'application/vc+sd-jwt' : 'application/vp+sd-jwt'; + 'application/vc-ld+sd-jwt' : 'application/vp-ld+sd-jwt'; const binaryMessage = await getBinaryMessage(privateKey, messageType, messageJson); const message = new TextDecoder().decode(binaryMessage); From bfecdda92c78fea259b6dcda46748f6a7b3193fa Mon Sep 17 00:00:00 2001 From: gabe Date: Tue, 25 Jun 2024 22:01:25 -0700 Subject: [PATCH 2/5] fix cose --- src/cose.js | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/cose.js b/src/cose.js index bb21a49..0c3a9d7 100644 --- a/src/cose.js +++ b/src/cose.js @@ -11,15 +11,11 @@ function buf2hex(buffer) { const getCredential = async ( privateKey, byteSigner, - messageType, messageJson, ) => { - let oldMessageType = (messageType === 'application/vc+cose') - ? 'application/vc+ld+json+cose' : 'application/vp+ld+json+cose'; - return issuer({ alg: privateKey.alg, - type: oldMessageType, + type: 'application/vc+ld+json+cose', signer: byteSigner, }).issue({ claimset: new TextEncoder().encode(JSON.stringify(messageJson, null, 2)), @@ -29,7 +25,6 @@ const getCredential = async ( const getPresentation = async ( privateKey, byteSigner, - messageType, message, ) => { const disclosures = (message.verifiableCredential || []).map(enveloped => { @@ -45,11 +40,9 @@ const getPresentation = async ( credential: content, }; }); - let oldMessageType = (messageType === 'application/vc+cose') - ? 'application/vc+ld+json+cose' : 'application/vp+ld+json+cose'; return holder({ alg: privateKey.alg, - type: oldMessageType, + type: 'application/vp+ld+json+cose', }).issue({ signer: byteSigner, presentation: message, @@ -73,11 +66,11 @@ const getBinaryMessage = async (privateKey, messageType, messageJson) => { }, }; switch(messageType) { - case 'application/vc+cose': { - return getCredential(privateKey, byteSigner, messageType, messageJson); + case 'application/vc-ld+cose': { + return getCredential(privateKey, byteSigner, messageJson); } - case 'application/vp+cose': { - return getPresentation(privateKey, byteSigner, messageType, messageJson); + case 'application/vp-ld+cose': { + return getPresentation(privateKey, byteSigner, messageJson); } default: { throw new Error('Unknown message type'); @@ -89,7 +82,7 @@ export const getCoseExample = async (privateKey, messageJson) => { const type = Array.isArray(messageJson.type) ? messageJson.type : [messageJson.type]; const messageType = type.includes('VerifiableCredential') ? - 'application/vc+cose' : 'application/vp+cose'; + 'application/vc-ld+cose' : 'application/vp-ld+cose'; const message = await getBinaryMessage(privateKey, messageType, messageJson); const messageHex = buf2hex(message); const messageBuffer = Buffer.from(messageHex, 'hex'); From a8f9907bafcd13214ccf1862cbd1739f955950fe Mon Sep 17 00:00:00 2001 From: gabe Date: Tue, 25 Jun 2024 22:13:03 -0700 Subject: [PATCH 3/5] fix sd jwt --- index.js | 10 +++++----- src/sd-jwt.js | 40 ++++++++++++---------------------------- 2 files changed, 17 insertions(+), 33 deletions(-) diff --git a/index.js b/index.js index 175517f..afb8214 100644 --- a/index.js +++ b/index.js @@ -2,7 +2,7 @@ import * as bbs2023Cryptosuite from '@digitalbazaar/bbs-2023-cryptosuite'; import * as Bls12381Multikey from '@digitalbazaar/bls12-381-multikey'; import * as EcdsaMultikey from '@digitalbazaar/ecdsa-multikey'; import * as ecdsaRdfc2019Cryptosuite from - '@digitalbazaar/ecdsa-rdfc-2019-cryptosuite'; + '@digitalbazaar/ecdsa-rdfc-2019-cryptosuite'; import * as ecdsaSd2023Cryptosuite from '@digitalbazaar/ecdsa-sd-2023-cryptosuite'; import * as Ed25519Multikey from '@digitalbazaar/ed25519-multikey'; @@ -21,9 +21,9 @@ import {DataIntegrityProof} from '@digitalbazaar/data-integrity'; import ed25519Context from 'ed25519-signature-2020-context'; import {Ed25519Signature2020} from '@digitalbazaar/ed25519-signature-2020'; import {Ed25519VerificationKey2020} from - '@digitalbazaar/ed25519-verification-key-2020'; + '@digitalbazaar/ed25519-verification-key-2020'; import {cryptosuite as eddsaRdfc2022CryptoSuite} from - '@digitalbazaar/eddsa-rdfc-2022-cryptosuite'; + '@digitalbazaar/eddsa-rdfc-2022-cryptosuite'; import examples2Context from './contexts/credentials/examples/v2'; import {getCoseExample} from './src/cose'; import {getJoseExample} from './src/jose'; @@ -617,10 +617,10 @@ async function createVcExamples() { verifiableCredentialProof = await attachProof({credential, suite}); const mediaType = (verifiableCredentialProof.type.includes('VerifiablePresentation')) - ? 'application/vp' : 'application/vc'; + ? 'application/vp' : 'application/vc'; return `

${mediaType}

${JSON.stringify(verifiableCredentialProof, null, 2)
-            .match(/.{1,75}/g).join('\n')}
`; + .match(/.{1,75}/g).join('\n')}`; } catch(e) { console.error( 'respec-vc error: Failed to attach proof to Verifiable Credential.', diff --git a/src/sd-jwt.js b/src/sd-jwt.js index 9292b3f..daee9ca 100644 --- a/src/sd-jwt.js +++ b/src/sd-jwt.js @@ -74,32 +74,16 @@ export const generateIssuerClaims = example => { .replace(/type:/g, '!sd type:'); }; -const getCredential = async ( - privateKey, - byteSigner, - messageType, - messageJson, -) => { - const oldMessageType = (messageType === 'application/vc-ld+sd-jwt') ? - 'application/vc+ld+json+sd-jwt' : 'application/vp+ld+json+sd-jwt'; - return issuer({ - alg: privateKey.alg, - type: oldMessageType, - signer: byteSigner, - }).issue({ - claimset: new TextEncoder().encode(generateIssuerClaims(messageJson)), - }); -}; - -const getPresentation = async ( - privateKey, - byteSigner, - messageType, - messageJson, -) => { - const mediaType = 'application/vp-ld+sd-jwt'; - return getCredential(privateKey, byteSigner, mediaType, messageJson); -}; +const getCredential = + async (privateKey, byteSigner, messageJson) => { + return issuer({ + alg: privateKey.alg, + type: 'application/vc+ld+json+sd-jwt', + signer: byteSigner, + }).issue({ + claimset: new TextEncoder().encode(generateIssuerClaims(messageJson)), + }); + }; export const getBinaryMessage = async ( privateKey, @@ -119,10 +103,10 @@ export const getBinaryMessage = async ( }; switch(messageType) { case 'application/vc-ld+sd-jwt': { - return getCredential(privateKey, byteSigner, messageType, messageJson); + return getCredential(privateKey, byteSigner, messageJson); } case 'application/vp-ld+sd-jwt': { - return getPresentation(privateKey, byteSigner, messageType, messageJson); + return getCredential(privateKey, byteSigner, messageJson); } default: { throw new Error('Unknown message type'); From 6d2168942f8f7f407f40734ec7a9a65e9e71df3d Mon Sep 17 00:00:00 2001 From: gabe Date: Tue, 25 Jun 2024 22:15:40 -0700 Subject: [PATCH 4/5] fix lint --- index.html | 18 +++++++++--------- index.js | 5 +++-- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/index.html b/index.html index 76a3cf5..9f9d248 100644 --- a/index.html +++ b/index.html @@ -162,47 +162,47 @@

File Hash Examples

  • raw (`openssl dgst -sha256`): + data-hash-format="openssl dgst -sha256">
  • digestSRI (sha2-256 base64pad): + data-hash-format="sri sha2-256">
  • digestSRI (sha2-384 base64pad): + data-hash-format="sri sha2-384">
  • digestMultibase (sha2-256 base16): + data-hash-format="multihash sha2-256 base16">
  • digestMultibase (sha2-256 base58btc): + data-hash-format="multihash sha2-256 base58btc">
  • digestMultibase (sha2-256 base64-url-nopad): + data-hash-format="multihash sha2-256">
  • digestMultibase (sha2-384 base64-url-nopad): + data-hash-format="multihash sha2-384">
  • digestMultibase (sha3-256 base64-url-nopad): + data-hash-format="multihash sha3-256">
  • digestMultibase (sha3-384 base64-url-nopad): + data-hash-format="multihash sha3-384">
  • diff --git a/index.js b/index.js index afb8214..4f723ee 100644 --- a/index.js +++ b/index.js @@ -616,8 +616,9 @@ async function createVcExamples() { try { verifiableCredentialProof = await attachProof({credential, suite}); const mediaType = - (verifiableCredentialProof.type.includes('VerifiablePresentation')) - ? 'application/vp' : 'application/vc'; + (verifiableCredentialProof.type + .includes('VerifiablePresentation')) ? + 'application/vp' : 'application/vc'; return `

    ${mediaType}

    ${JSON.stringify(verifiableCredentialProof, null, 2)
         .match(/.{1,75}/g).join('\n')}
    `; From 4b0b90b4b0dbf7c50a424d4d62c4e9d422a47d19 Mon Sep 17 00:00:00 2001 From: gabe Date: Tue, 25 Jun 2024 22:16:57 -0700 Subject: [PATCH 5/5] more lints --- index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 4f723ee..57a9f35 100644 --- a/index.js +++ b/index.js @@ -2,7 +2,7 @@ import * as bbs2023Cryptosuite from '@digitalbazaar/bbs-2023-cryptosuite'; import * as Bls12381Multikey from '@digitalbazaar/bls12-381-multikey'; import * as EcdsaMultikey from '@digitalbazaar/ecdsa-multikey'; import * as ecdsaRdfc2019Cryptosuite from - '@digitalbazaar/ecdsa-rdfc-2019-cryptosuite'; + '@digitalbazaar/ecdsa-rdfc-2019-cryptosuite'; import * as ecdsaSd2023Cryptosuite from '@digitalbazaar/ecdsa-sd-2023-cryptosuite'; import * as Ed25519Multikey from '@digitalbazaar/ed25519-multikey'; @@ -21,9 +21,9 @@ import {DataIntegrityProof} from '@digitalbazaar/data-integrity'; import ed25519Context from 'ed25519-signature-2020-context'; import {Ed25519Signature2020} from '@digitalbazaar/ed25519-signature-2020'; import {Ed25519VerificationKey2020} from - '@digitalbazaar/ed25519-verification-key-2020'; + '@digitalbazaar/ed25519-verification-key-2020'; import {cryptosuite as eddsaRdfc2022CryptoSuite} from - '@digitalbazaar/eddsa-rdfc-2022-cryptosuite'; + '@digitalbazaar/eddsa-rdfc-2022-cryptosuite'; import examples2Context from './contexts/credentials/examples/v2'; import {getCoseExample} from './src/cose'; import {getJoseExample} from './src/jose';