Skip to content
This repository has been archived by the owner on Oct 15, 2024. It is now read-only.

Commit

Permalink
feat: allow the use of publicKeyJwk to derive and verify proof (#145)
Browse files Browse the repository at this point in the history
  • Loading branch information
chiechelski authored Aug 5, 2021
1 parent 3000f3c commit 0cec1f1
Show file tree
Hide file tree
Showing 15 changed files with 338 additions and 16 deletions.
16 changes: 10 additions & 6 deletions .github/workflows/any-pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,18 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [11.x, 12.x, 13.x, 14.x, 15.x, 16.x]
node-version: [10.x, 11.x, 12.x, 13.x, 14.x, 15.x, 16.x]
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: yarn install --frozen-lockfile
- run: yarn lint
- run: yarn build
- run: yarn test:node --coverage
- run: yarn test:wasm --coverage
- name: Run tests
run: |
yarn install --frozen-lockfile
yarn lint
yarn build
yarn test:node --coverage
yarn test:wasm --coverage
# skip node-version 10 but including on node-version list due to a github actions issue
if: matrix.node-version != '10.x'
82 changes: 82 additions & 0 deletions __tests__/__fixtures__/contexts/jws.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
{
"@context": {
"privateKeyJwk": {
"@id": "https://w3id.org/security#privateKeyJwk",
"@type": "@json"
},
"JsonWebKey2020": {
"@id": "https://w3id.org/security#JsonWebKey2020",
"@context": {
"@protected": true,
"id": "@id",
"type": "@type",
"publicKeyJwk": {
"@id": "https://w3id.org/security#publicKeyJwk",
"@type": "@json"
}
}
},
"JsonWebSignature2020": {
"@id": "https://w3id.org/security#JsonWebSignature2020",
"@context": {
"@protected": true,

"id": "@id",
"type": "@type",

"challenge": "https://w3id.org/security#challenge",
"created": {
"@id": "http://purl.org/dc/terms/created",
"@type": "http://www.w3.org/2001/XMLSchema#dateTime"
},
"domain": "https://w3id.org/security#domain",
"expires": {
"@id": "https://w3id.org/security#expiration",
"@type": "http://www.w3.org/2001/XMLSchema#dateTime"
},
"jws": "https://w3id.org/security#jws",
"nonce": "https://w3id.org/security#nonce",
"proofPurpose": {
"@id": "https://w3id.org/security#proofPurpose",
"@type": "@vocab",
"@context": {
"@protected": true,

"id": "@id",
"type": "@type",

"assertionMethod": {
"@id": "https://w3id.org/security#assertionMethod",
"@type": "@id",
"@container": "@set"
},
"authentication": {
"@id": "https://w3id.org/security#authenticationMethod",
"@type": "@id",
"@container": "@set"
},
"capabilityInvocation": {
"@id": "https://w3id.org/security#capabilityInvocationMethod",
"@type": "@id",
"@container": "@set"
},
"capabilityDelegation": {
"@id": "https://w3id.org/security#capabilityDelegationMethod",
"@type": "@id",
"@container": "@set"
},
"keyAgreement": {
"@id": "https://w3id.org/security#keyAgreementMethod",
"@type": "@id",
"@container": "@set"
}
}
},
"verificationMethod": {
"@id": "https://w3id.org/security#verificationMethod",
"@type": "@id"
}
}
}
}
}
6 changes: 6 additions & 0 deletions __tests__/__fixtures__/customDocumentLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,27 @@ import credentialContext from "./contexts/credential_vocab.json";
import odrlContext from "./contexts/odrl.json";
import securityV3 from "./contexts/v3_unstable.json";
import bbsContext from "./contexts/bbs.json";
import jwsContext from "./contexts/jws.json";
import vcExampleContext from "./contexts/vc_example_vocab.json";
import schemaOrg from "./contexts/schemaOrg.json";
import exampleDidKey from "./data/did_example_489398593_test.json";
import exampleDidDoc from "./data/did_example_489398593.json";
import exampleDidb34Key from "./data/did_example_b34ca6cd37bbf23_test.json";
import exampleDidb34Doc from "./data/did_example_b34ca6cd37bbf23.json";
import exampleDid826Key from "./data/did_example_82612387612873_test.json";
import exampleDid826Doc from "./data/did_example_82612387612873.json";

export const documents: any = {
"https://w3id.org/security/v3-unstable": securityV3,
"https://www.w3id.org/security/v3-unstable": securityV3,
"https://www.w3.org/2018/credentials/examples/v1": vcExampleContext,
"https://www.w3.org/2018/credentials/v1": credentialContext,
"https://www.w3.org/ns/odrl.jsonld": odrlContext,
"https://w3id.org/security/suites/jws-2020/v1": jwsContext,
"did:example:489398593#test": exampleDidKey,
"did:example:489398593": exampleDidDoc,
"did:example:82612387612873#test": exampleDid826Key,
"did:example:82612387612873": exampleDid826Doc,
"did:example:b34ca6cd37bbf23#test": exampleDidb34Key,
"did:example:b34ca6cd37bbf23": exampleDidb34Doc,
"https://w3id.org/citizenship/v1": citizenVocab,
Expand Down
5 changes: 5 additions & 0 deletions __tests__/__fixtures__/data/did_example_82612387612873.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"@context": "https://w3id.org/security/v2",
"id": "did:example:82612387612873",
"assertionMethod": ["did:example:82612387612873#test"]
}
14 changes: 14 additions & 0 deletions __tests__/__fixtures__/data/did_example_82612387612873_test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"@context": [
"https://w3id.org/security/v2",
"https://w3id.org/security/suites/jws-2020/v1"
],
"id": "did:example:82612387612873#test",
"type": "JsonWebKey2020",
"controller": "did:example:82612387612873",
"publicKeyJwk": {
"kty": "OKP",
"crv": "Bls12381G2",
"x": "h_rkcTKXXzRbOPr9UxSfegCbid2U_cVNXQUaKeGF7UhwrMJFP70uMH0VQ9-3-_2zDPAAjflsdeLkOXW3-ShktLxuPy8UlXSNgKNmkfb-rrj-FRwbs13pv_WsIf-eV66-"
}
}
36 changes: 36 additions & 0 deletions __tests__/__fixtures__/data/test_signed_vc_jwk.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://w3id.org/citizenship/v1",
"https://w3id.org/security/v3-unstable"
],
"id": "https://issuer.oidp.uscis.gov/credentials/83627465",
"type": ["VerifiableCredential", "PermanentResidentCard"],
"issuer": "did:example:82612387612873",
"identifier": "83627465",
"name": "Permanent Resident Card",
"description": "Government of Example Permanent Resident Card.",
"issuanceDate": "2019-12-03T12:19:52Z",
"expirationDate": "2029-12-03T12:19:52Z",
"credentialSubject": {
"id": "did:example:b34ca6cd37bbf23",
"type": ["PermanentResident", "Person"],
"givenName": "JOHN",
"familyName": "SMITH",
"gender": "Male",
"image": "data:image/png;base64,iVBORw0KGgokJggg==",
"residentSince": "2015-01-01",
"lprCategory": "C09",
"lprNumber": "999-999-999",
"commuterClassification": "C1",
"birthCountry": "Bahamas",
"birthDate": "1958-07-17"
},
"proof": {
"type": "BbsBlsSignature2020",
"created": "2021-08-05T03:19:13Z",
"proofPurpose": "assertionMethod",
"proofValue": "t7+Py6v7sYXMGQR6Mxgf9SyEb0NnckqOSM9xMz4WAT1A6uVV0L+Kk8ClUoyWqBsTC7OxzJAbkUx05V2ZXY3EUnZFWmPjgl5/lVsGd/iSJrAauewJgcXPJTQOp8paallZkw9rY3vuwjJ75jtEwPRxGA==",
"verificationMethod": "did:example:82612387612873#test"
}
}
24 changes: 24 additions & 0 deletions __tests__/__fixtures__/data/test_vc_reveal_document_jwk.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://w3id.org/citizenship/v1",
"https://w3id.org/security/v3-unstable"
],
"id": "https://issuer.oidp.uscis.gov/credentials/83627465",
"type": ["VerifiableCredential", "PermanentResidentCard"],
"@explicit": true,
"issuer": "did:example:489398593",
"identifier": "83627465",
"name": "Permanent Resident Card",
"description": "Government of Example Permanent Resident Card.",
"issuanceDate": "2019-12-03T12:19:52Z",
"expirationDate": "2029-12-03T12:19:52Z",
"credentialSubject": {
"id": "did:example:b34ca6cd37bbf23",
"type": ["PermanentResident", "Person"],
"@explicit": true,
"givenName": "JOHN",
"familyName": "SMITH",
"gender": "Male"
}
}
4 changes: 4 additions & 0 deletions __tests__/__fixtures__/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ import testPartialProofDocument from "./data/test_partial_proof_document.json";
import testBadPartialProofDocument from "./data/test_bad_partial_proof_document.json";
import testVcDocument from "./data/test_vc.json";
import testSignedVcDocument from "./data/test_signed_vc.json";
import testSignedVcDocumentJwk from "./data/test_signed_vc_jwk.json";
import testRevealVcDocument from "./data/test_vc_reveal_document.json";
import testRevealVcDocumentJwk from "./data/test_vc_reveal_document_jwk.json";
import testPartialVcProof from "./data/test_partial_proof_vc_document.json";
import testRevealAllDocument from "./data/test_reveal_all_document.json";
import testNestedRevealDocument from "./data/test_nested_reveal_document.json";
Expand All @@ -45,6 +47,7 @@ export {
exampleEd25519KeyPair,
testDocument,
testRevealDocument,
testRevealVcDocumentJwk,
testSignedDocument,
testSignedDocumentMultiProofs,
testSignedDocumentMultiDifProofs,
Expand All @@ -54,6 +57,7 @@ export {
testRevealAllDocument,
testPartialVcProof,
testSignedVcDocument,
testSignedVcDocumentJwk,
testRevealVcDocument,
testPartialProofDocument,
testBadPartialProofDocument,
Expand Down
30 changes: 29 additions & 1 deletion __tests__/deriveProof.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ import {
testSignedDocumentEd25519,
testNestedRevealDocument,
testNestedRevealFullDocument,
testSignedNestedVcDocument
testSignedNestedVcDocument,
testSignedVcDocumentJwk,
testRevealVcDocumentJwk
} from "./__fixtures__";

import { BbsBlsSignatureProof2020, deriveProof } from "../src/index";
Expand Down Expand Up @@ -122,6 +124,32 @@ describe("BbsBlsSignatureProof2020", () => {
expect(result.credentialSubject.degree.name).toBeDefined();
});

it("should derive proof and verify using jsonld-signatures library", async () => {
const derivedProof = await deriveProof(
testSignedVcDocumentJwk,
testRevealVcDocumentJwk,
{
suite: new BbsBlsSignatureProof2020(),
documentLoader: customLoader
}
);

// testing if derive result includes less fields
expect(
Object.keys(testSignedVcDocumentJwk.credentialSubject).length
).toEqual(12);
expect(Object.keys(derivedProof.credentialSubject).length).toEqual(5);

// verifying proof is valid
const derivedProofVerified = await jsigs.verify(derivedProof, {
suite: new BbsBlsSignatureProof2020(),
purpose: new jsigs.purposes.AssertionProofPurpose(),
documentLoader: customLoader
});

expect(derivedProofVerified.verified).toBeTruthy();
});

it("should derive proofs from a nested document with a nested frame with selectively revealed properties", async () => {
const result = await deriveProof(
testSignedNestedVcDocument,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
},
"dependencies": {
"@mattrglobal/bbs-signatures": "0.6.0",
"@mattrglobal/bls12381-key-pair": "0.6.0",
"@mattrglobal/bls12381-key-pair": "0.7.0",
"@stablelib/random": "1.0.0",
"bs58": "4.0.1",
"jsonld": "3.1.0",
Expand Down
21 changes: 17 additions & 4 deletions src/BbsBlsSignatureProof2020.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { suites, SECURITY_CONTEXT_URL } from "jsonld-signatures";
import { blsCreateProof, blsVerifyProof } from "@mattrglobal/bbs-signatures";
import {
DeriveProofOptions,
DidDocumentPublicKey,
VerifyProofOptions,
CreateVerifyDataOptions,
CanonizeOptions
Expand Down Expand Up @@ -201,7 +202,9 @@ export class BbsBlsSignatureProof2020 extends suites.LinkedDataProof {
});

// Construct a key pair class from the returned verification method
const key = await this.LDKeyClass.from(verificationMethod);
const key = verificationMethod.publicKeyJwk
? await this.LDKeyClass.fromJwk(verificationMethod)
: await this.LDKeyClass.from(verificationMethod);

// Compute the proof
const outputProof = await blsCreateProof({
Expand Down Expand Up @@ -269,7 +272,10 @@ export class BbsBlsSignatureProof2020 extends suites.LinkedDataProof {
expansionMap
});

const key = await this.LDKeyClass.from(verificationMethod);
// Construct a key pair class from the returned verification method
const key = verificationMethod.publicKeyJwk
? await this.LDKeyClass.fromJwk(verificationMethod)
: await this.LDKeyClass.from(verificationMethod);

// Verify the proof
const verified = await blsVerifyProof({
Expand Down Expand Up @@ -386,7 +392,10 @@ export class BbsBlsSignatureProof2020 extends suites.LinkedDataProof {
* @param documentLoader {function}
* @param expansionMap {function}
*/
async getVerificationMethod({ proof, documentLoader }: any): Promise<object> {
async getVerificationMethod({
proof,
documentLoader
}: any): Promise<DidDocumentPublicKey> {
let { verificationMethod } = proof;

if (typeof verificationMethod === "object") {
Expand All @@ -401,7 +410,11 @@ export class BbsBlsSignatureProof2020 extends suites.LinkedDataProof {
const result = await jsonld.frame(
verificationMethod,
{
"@context": SECURITY_CONTEXT_URL,
// adding jws-2020 context to allow publicKeyJwk
"@context": [
"https://w3id.org/security/v2",
"https://w3id.org/security/suites/jws-2020/v1"
],
"@embed": "@always",
id: verificationMethod
},
Expand Down
Loading

0 comments on commit 0cec1f1

Please sign in to comment.