Ninja Pumpkin Mutants

    @digitalcredentials/sign-and-verify-core
    TypeScript icon, indicating that this package has built-in type declarations

    2.1.0 • Public • Published

    sign-and-verify-core

    Signing and verification of Verifiable Credentials and Verifiable Presentations using an unlocked DID Document.

    Usage

    Install the npm package:

    npm i @digitalcredentials/sign-and-verify-core
    OR
    yarn add @digitalcredentials/sign-and-verify-core
    

    and then use that issuer...

    Generating a new key pair

    You can use the sample keypair that comes with sign-and-verify (unlockedDID), but eventually you'll want to generate your own key pair, which you can do thusly:

    const {Ed25519VerificationKey2020} = require('@digitalbazaar/ed25519-verification-key-2020');
    const generate = async function() {
        const edKeyPair = await Ed25519VerificationKey2020.generate({controller: 'did:web:credentials.mcmaster.ca'})
        const keys = await edKeyPair.export({publicKey: true, privateKey: true});
        console.log(JSON.stringify(keys, null, 2))
    }
    generate()

    You can run this on the command line in an npm package with the @digitalbazaar/ed25519-verification-key-2020 library installed.

    This produces a key pair, which should look something like this:

    {
      id: 'did:web:credentials.mcmaster.ca#z6MkfcpjR3X7xJja2atED1E6meTTUjjTmKf7E2Kq2JFHK1Xp',
      type: 'Ed25519VerificationKey2020',
      controller: 'did:web:credentials.mcmaster.ca',
      publicKeyMultibase: 'z6MkfcpjR3X7xJja2atED1E6meTTUjjTmKf7E2Kq2JFHK1Xp',
      privateKeyMultibase: 'zruzggrR7q9cHFrzVmk7kHvDwo9vdtCQtXoUebGBDYYz3A6CdnLub4CYYMaKLB6X6LQTCix7m2tEJbYbUWjTN5yX8ZY'
    }
    

    Put it into the DID document to get something like this:

    {
    	"@context": [
    		"https://www.w3.org/ns/did/v1",
    		"https://w3id.org/security/suites/ed25519-2020/v1"
    	],
    	"id": "did:web:digitalcredentials.mcmaster.ca",
    	"assertionMethod": [{
      		"id": "did:web:credentials.mcmaster.ca#z6MkfcpjR3X7xJja2atED1E6meTTUjjTmKf7E2Kq2JFHK1Xp",
      		"type": "Ed25519VerificationKey2020",
      		"controller": "did:web:credentials.mcmaster.ca",
      		"publicKeyMultibase": "z6MkfcpjR3X7xJja2atED1E6meTTUjjTmKf7E2Kq2JFHK1Xp",
      		"privateKeyMultibase": "zruzggrR7q9cHFrzVmk7kHvDwo9vdtCQtXoUebGBDYYz3A6CdnLub4CYYMaKLB6X6LQTCix7m2tEJbYbUWjTN5yX8ZY"
    	}]
    }

    Save this somewhere. The Examples section explains how to use it.

    NOTE: IMPORTANT! IMPORTANT! This DID Document contains the private key and so should NEVER be posted publicly (and should be kept secure as appropriate for your security requirements.) This so-called 'unlocked' DID Document is only meant to be used locally with this library (because the library needs the private key to sign with). If you do end up wanting to post the DID publicly (like at the DID:WEB .well-known URI, e.g., http://credentials.mcmaster.ca/.well-known/did.json), first remove the private key, and post the rest:

    {
    	"@context": [
    		"https://www.w3.org/ns/did/v1",
    		"https://w3id.org/security/suites/ed25519-2020/v1"
    	],
    	"id": "did:web:digitalcredentials.mcmaster.ca",
    	"assertionMethod": [{
      		"id": "did:web:credentials.mcmaster.ca#z6MkfcpjR3X7xJja2atED1E6meTTUjjTmKf7E2Kq2JFHK1Xp",
      		"type": "Ed25519VerificationKey2020",
      		"controller": "did:web:credentials.mcmaster.ca",
      		"publicKeyMultibase": "z6MkfcpjR3X7xJja2atED1E6meTTUjjTmKf7E2Kq2JFHK1Xp"
    	}]
    }

    Examples

    You can see a lot of this in tests - we just reproduce/re-organize it here to make it easier to understand if you are new to javascript, or to testing, or really just want to see the important parts without distractions.

    NOTE: where we say 'presentation', we mean a Verifiable Presentation

    NOTE: where we say 'credential', we mean a Verifiable Credential

    You'll need an unlocked DID document with which to sign (like this one: unlockedDID or generate your own as explained above).

    import {createIssuer} from sign-and-verify-core;
    
    // Load your unlocked DID from wherever you like.  For example, from the file system (if say you copied 
    // data/unlocked-did:key.json from this repo to your project):
    
    const unlockedDidDocument = JSON.parse(readFileSync("data/unlocked-did:key.json").toString("ascii"));
    
    // create the issuer, passing in the unlocked DID document
    const { sign, requestDemoCredential, verify, signPresentation, createAndSignPresentation, verifyPresentation } = createIssuer(unlockedDidDocument)
    
    const sampleUnsignedCredential = {
    	"@context": [
        "https://www.w3.org/2018/credentials/v1", 
        "https://www.w3.org/2018/credentials/examples/v1", 
        "https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json"
      ],
    	"id": "http://example.gov/credentials/3732",
    	"type": ["VerifiableCredential", "UniversityDegreeCredential"],
    	"issuer": "did:web:digitalcredentials.github.io",
    	"issuanceDate": "2020-03-10T04:24:12.164Z",
    	"credentialSubject": {
    		"id": "did:example:abcdef",
    		"degree": {
    			"type": "BachelorDegree",
    			"name": "Bachelor of Science and Arts"
    		}
    	}
    } 
    
    const sampleSignedCredential = {
    	"@context": [
        "https://www.w3.org/2018/credentials/v1", 
        "https://www.w3.org/2018/credentials/examples/v1", 
        "https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json"
      ],
    	"id": "http://example.gov/credentials/3732",
    	"type": ["VerifiableCredential", "UniversityDegreeCredential"],
    	"issuer": "did:web:digitalcredentials.github.io",
    	"issuanceDate": "2020-03-10T04:24:12.164Z",
    	"credentialSubject": {
    		"id": "did:example:me",
    		"degree": {
    			"type": "BachelorDegree",
    			"name": "Bachelor of Science and Arts"
    		}
    	},
    	"proof": {
    		"type": "JsonWebSignature2020",
    		"created": "2020-11-12T23:56:27.928Z",
    		"jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..2DppQ4Euf9PUX6NrFPyJwHKPmeAqNWAC6UH8kiFNbsoiinebPpwdortHe-bLzDOQ_W7MQD5nqOnNN8JIVGarAA",
    		"proofPurpose": "assertionMethod",
    		"verificationMethod": "did:web:digitalcredentials.github.io#96K4BSIWAkhcclKssb8yTWMQSz4QzPWBy-JsAFlwoIs"
    	}
    }
    
    const sampleUnsignedPresentation = {
      '@context': [
        'https://www.w3.org/2018/credentials/v1',
        'https://www.w3.org/2018/credentials/examples/v1',
        'https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json'
      ],
      type: [ 'VerifiablePresentation' ],
      id: '456',
      holder: 'did:web:digitalcredentials.github.io'
    }
    
    
    const sampleSignedPresentation = {
    	"@context": [
        "https://www.w3.org/2018/credentials/v1", 
        "https://www.w3.org/2018/credentials/examples/v1", 
        "https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json"
      ],
    	"type": ["VerifiablePresentation"],
    	"id": "456",
    	"holder": "did:web:digitalcredentials.github.io",
    	"proof": {
    		"type": "JsonWebSignature2020",
    		"created": "2020-11-12T22:00:33.393Z",
    		"challenge": "123",
    		"jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..nuQE1vdLcf0YJSI_ojCdOpkQ53Amf4admAfA1eds9ONz9iskp5NBHqoz_YpzyRPxRvj4zblDDAhR524Dn4BtBA",
    		"proofPurpose": "authentication",
    		"verificationMethod": "did:web:digitalcredentials.github.io#96K4BSIWAkhcclKssb8yTWMQSz4QzPWBy-JsAFlwoIs"
    	}
    }
    
    // NOTE that the property passed in through credentialOptions is called the verificationMethod, 
    // but for this demo, which uses an [unlockedDID](data/unlocked-did:key.json) 
    // it also identifies the signing key with which to sign credentials, I think just because the 
    // the private key is packaged in together with the public key
    const credentialOptions = {
      "verificationMethod": "did:web:digitalcredentials.github.io#96K4BSIWAkhcclKssb8yTWMQSz4QzPWBy-JsAFlwoIs",
    }
    // same as above for credentials, but also with a 'challenge':
    const presentationOptions = {...credentialOptions, "challenge": "123"}
    
    /* CREDENTIAL EXAMPLES */
    
    // sign a credential
    const result = sign(sampleUnsignedCredential, credentialOptions)
    
    // verify a credential
    const result = verify(sampleSignedCredential, credentialOptions)
    
    // Request a demo credential, providing a signed presentation to prove DID ownership (control)
    const result = requestDemoCredential(sampleSignedPresentation)
    
    
    // Request a demo credential - without providing a full presentation to prove DID ownership.
    // Instead, simply provide an object with a holder property where we'd expect one in a presentation,
    // so kind of like a presentation stripped down to just the holder property.
    const minimalPresentation = { holder: "did:example:me" }
    const shouldSkipVerification = true
    const result = requestDemoCredential(minimalPresentation, shouldSkipVerification)
    
    /* PRESENTATION EXAMPLES */
    
    // sign a provided but as yet unsigned presentation
    const result = signPresentation(sampleUnsignedPresentation, presentationOptions)
    
    // verify a presentation
    // Note:  for fun and profit, you could also verify the signed presentation returned 
    // from the 'signPresentation' step above
    const result = verifyPresentation(sampleSignedPresentation, presentationOptions)
    
    const presentationId = '456'
    const holderDID = 'did:example:me';
    // construct and sign a presentation that wraps a given signed credential
    const result = createAndSignPresentation(sampleSignedCredential, presentationId, holderDID, presentationOptions);
    
    // construct and sign a presentation, without providing an associated credential (hence the null argument)
    const result = createAndSignPresentation(null, presentationId, holderDID, presentationOptions);

    References

    You should be familiar with the W3C Verifiable Credentials Data Model. Two key concepts are:

    Development

    To make changes to the package:

    Install

    npm run install
    

    Build

    npm run build
    

    Test

    npm run test
    

    Publish to NPM

    npm publish --access public
    

    Before publishing, do make sure you are logged into npm on the command line, e.g., with

    npm adduser
    

    Note that npm publish --access public will trigger the prepublishOnly script to first run the build

    Keywords

    none

    Install

    npm i @digitalcredentials/sign-and-verify-core

    DownloadsWeekly Downloads

    15

    Version

    2.1.0

    License

    MIT

    Unpacked Size

    118 kB

    Total Files

    65

    Last publish

    Collaborators

    • codenamedmitri
    • kimhd
    • uligall
    • alexander.muehle
    • stuartf
    • jchartrand
    • kiliankae