Skip to content

Commit

Permalink
add eddsa signing
Browse files Browse the repository at this point in the history
  • Loading branch information
jchartrand committed Jan 15, 2025
1 parent 4b11d28 commit c340eb8
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 22 deletions.
68 changes: 57 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@
},
"dependencies": {
"@digitalbazaar/cborld": "^7.1.2",
"@digitalbazaar/data-integrity": "^2.5.0",
"@digitalbazaar/did-method-key": "^5.2.0",
"@digitalbazaar/ed25519-multikey": "^1.3.0",
"@digitalbazaar/ed25519-signature-2020": "^5.4.0",
"@digitalbazaar/ed25519-verification-key-2020": "^4.1.0",
"@digitalbazaar/eddsa-rdfc-2022-cryptosuite": "^1.2.0",
"@digitalbazaar/vc": "^7.0.0",
"@digitalcredentials/security-document-loader": "^6.0.0",
"@interop/did-web-resolver": "^5.0.0",
Expand Down
3 changes: 2 additions & 1 deletion src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export async function build() {

app.post('/instance/:instanceId/credentials/sign', async (req, res, next) => {
try {
var suite = req.query.suite ?? 'ed25519'
const instanceId = req.params.instanceId //the issuer instance/tenant with which to sign
const unSignedVC = req.body
if (!req.body || !Object.keys(req.body).length) {
Expand All @@ -52,7 +53,7 @@ export async function build() {
'A verifiable credential must be provided in the body.'
)
}
const signedVC = await issue(unSignedVC, instanceId)
const signedVC = await issue(unSignedVC, instanceId, suite)
return res.json(signedVC)
} catch (e) {
// catch the async errors and pass them to the error logger and handler
Expand Down
45 changes: 35 additions & 10 deletions src/issue.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { Ed25519Signature2020 } from '@digitalbazaar/ed25519-signature-2020'
import { Ed25519VerificationKey2020 } from '@digitalbazaar/ed25519-verification-key-2020'

import * as Ed25519Multikey from '@digitalbazaar/ed25519-multikey'
import { DataIntegrityProof } from '@digitalbazaar/data-integrity'
import { cryptosuite as eddsaRdfc2022CryptoSuite } from '@digitalbazaar/eddsa-rdfc-2022-cryptosuite'

import { CryptoLD } from 'crypto-ld'
import { driver as keyDriver } from '@digitalbazaar/did-method-key'
import { driver as webDriver } from '@interop/did-web-resolver'
Expand All @@ -8,7 +13,7 @@ import { getTenantSeed } from './config.js'
import SigningException from './SigningException.js'
import { issue as signVC } from '@digitalbazaar/vc'

let ISSUER_INSTANCES = {}
let ISSUER_INSTANCES = { eddsa2022: {}, ed25519: {} }
const documentLoader = securityLoader().build()

// Crypto library for linked data
Expand All @@ -26,29 +31,30 @@ didKeyDriver.use({

/* FOR TESTING */
export const clearIssuerInstances = () => {
ISSUER_INSTANCES = {}
ISSUER_INSTANCES = { eddsa2022: {}, ed25519: {} }
}

const getIssuerInstance = async (instanceId) => {
if (!ISSUER_INSTANCES[instanceId]) {
const getIssuerInstance = async (instanceId, suite) => {
if (!ISSUER_INSTANCES[suite][instanceId]) {
const config = await getTenantSeed(instanceId)
if (!config?.didSeed)
throw new SigningException(404, "Tenant doesn't exist.")
const { didSeed, didMethod, didUrl } = config
ISSUER_INSTANCES[instanceId] = await buildIssuerInstance(
ISSUER_INSTANCES[suite][instanceId] = await buildIssuerInstance(
didSeed,
didMethod,
didUrl
didUrl,
suite
)
}
return ISSUER_INSTANCES[instanceId]
return ISSUER_INSTANCES[suite][instanceId]
}

const issue = async (unsignedVerifiableCredential, instanceId) => {
const issue = async (unsignedVerifiableCredential, instanceId, suite) => {
const {
issuerInstance,
didDocument: { id: issuerId }
} = await getIssuerInstance(instanceId)
} = await getIssuerInstance(instanceId, suite)
addIssuerId(unsignedVerifiableCredential, issuerId)
const signedVerifiableCredential = await issuerInstance.issueCredential({
credential: unsignedVerifiableCredential
Expand Down Expand Up @@ -79,13 +85,32 @@ const addIssuerId = (credential, issuerId) => {
}
}

const buildIssuerInstance = async (seed, method, url) => {
const buildIssuerInstance = async (seed, method, url, suite) => {
const { didDocument, key } = await getSigningMaterial({ seed, method, url })
if (suite === 'eddsa2022') {
return await buildEddsa2022IssuerInstance(didDocument, key)
} else {
return await buildEd255192020IssuerInstance(didDocument, key)
}
}

const buildEd255192020IssuerInstance = async (didDocument, key) => {
const signingSuite = new Ed25519Signature2020({ key })
const issuerInstance = new IssuerInstance({ documentLoader, signingSuite })
return { issuerInstance, didDocument }
}

const buildEddsa2022IssuerInstance = async (didDocument, key) => {
// convert Ed25519VerificationKey2020 key to Ed25519Multikey key
const ed25519Multikey = await Ed25519Multikey.from(key)
const signingSuite = new DataIntegrityProof({
signer: ed25519Multikey.signer(),
cryptosuite: eddsaRdfc2022CryptoSuite
})
const issuerInstance = new IssuerInstance({ documentLoader, signingSuite })
return { issuerInstance, didDocument }
}

export async function getSigningMaterial({ method, seed, url }) {
let did, key
if (method === 'web') {
Expand Down

0 comments on commit c340eb8

Please sign in to comment.