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

Commit

Permalink
feat: adds support for providing a proofDocument with multiple proofs
Browse files Browse the repository at this point in the history
see issue #79 for details
  • Loading branch information
kdenhartog-mattr committed Oct 5, 2020
1 parent 38747e6 commit f402494
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 9 deletions.
81 changes: 80 additions & 1 deletion __tests__/deriveProof.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,16 @@ import {
testSignedDocument,
customLoader,
testSignedVcDocument,
testRevealVcDocument
testRevealVcDocument,
testSignedDocumentMultiProofs,
testSignedDocumentMultiDifProofs,
testSignedDocumentEd25519
} from "./__fixtures__";

import { BbsBlsSignatureProof2020, deriveProof } from "../src/index";

import jsigs from "jsonld-signatures";

describe("BbsBlsSignatureProof2020", () => {
it("should derive proof", async () => {
const result = await deriveProof(testSignedDocument, testRevealDocument, {
Expand Down Expand Up @@ -49,4 +54,78 @@ describe("BbsBlsSignatureProof2020", () => {
);
expect(result).toBeDefined();
});

it("should derive proofs from a document featuring multiple supporting proofs", async () => {
const result = await deriveProof(
testSignedDocumentMultiProofs,
testRevealDocument,
{
suite: new BbsBlsSignatureProof2020(),
documentLoader: customLoader
}
);
expect(result).toBeDefined();
expect(result.proof.length).toBe(2);
});

it("should derive proofs from a document featuring multiple different proofs with at least 1 supporting proof", async () => {
const result = await deriveProof(
testSignedDocumentMultiDifProofs,
testRevealDocument,
{
suite: new BbsBlsSignatureProof2020(),
documentLoader: customLoader
}
);
expect(result).toBeDefined();

// this returns a document with only a single proof so it should be an object rather than an array
expect(Array.isArray(result.proof)).toBe(false);
});

it("should derive proofs from multiple proof documents and be able to verify them using jsonld-signatures library", async () => {
const result = await deriveProof(
testSignedDocumentMultiProofs,
testRevealDocument,
{
suite: new BbsBlsSignatureProof2020(),
documentLoader: customLoader,
skipProofCompaction: false
}
);

const derivedProofVerified = await jsigs.verify(result, {
suite: new BbsBlsSignatureProof2020(),
purpose: new jsigs.purposes.AssertionProofPurpose(),
documentLoader: customLoader
});

expect(result).toBeDefined();
expect(result.proof.length).toBe(2);
expect(derivedProofVerified.verified).toBeTruthy();
});

it("should throw an error when proofDocument is the wrong type", async () => {
await expect(
deriveProof(
[testSignedDocument, testSignedDocument],
testRevealDocument,
{
suite: new BbsBlsSignatureProof2020(),
documentLoader: customLoader
}
)
).rejects.toThrowError("proofDocument should be an object not an array.");
});

it("should throw an error when proofDocument doesn't include a BBSBlsSignatureProof2020", async () => {
await expect(
deriveProof(testSignedDocumentEd25519, testRevealDocument, {
suite: new BbsBlsSignatureProof2020(),
documentLoader: customLoader
})
).rejects.toThrowError(
"There were not any BBSBlsSignatureProof2020 proofs provided that can be used to derive a proof."
);
});
});
58 changes: 50 additions & 8 deletions src/deriveProof.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,36 +34,69 @@ export const deriveProof = async (
throw new TypeError('"options.suite" is required.');
}

if (Array.isArray(proofDocument)) {
throw new TypeError("proofDocument should be an object not an array.");
}

const { proofs, document } = await getProofs({
document: proofDocument,
proofType: suite.supportedDeriveProofType,
documentLoader,
expansionMap
});

const result = await suite.deriveProof({
if (proofs.length === 0) {
throw new Error(
"There were not any BBSBlsSignatureProof2020 proofs provided that can be used to derive a proof."
);
}
let derivedProof;

derivedProof = await suite.deriveProof({
document,
proof: proofs[0],
revealDocument,
documentLoader,
expansionMap
});

if (proofs.length > 1) {
// convert the proof property value from object ot array of objects
derivedProof = { ...derivedProof, proof: [derivedProof.proof] };

// drop the first proof because it's already been processed
proofs.splice(0, 1);

// add all the additional proofs to the derivedProof document
for (const proof of proofs) {
const additionalDerivedProofValue = await suite.deriveProof({
document,
proof,
revealDocument,
documentLoader,
expansionMap
});
derivedProof.proof.push(additionalDerivedProofValue.proof);
}
}

if (!skipProofCompaction) {
/* eslint-disable prefer-const */
let expandedProof: any = {
[SECURITY_PROOF_URL]: { "@graph": result.proof }
[SECURITY_PROOF_URL]: {
"@graph": derivedProof.proof
}
};

// account for type-scoped `proof` definition by getting document types
const { types, alias } = await getTypeInfo(result.document, {
const { types, alias } = await getTypeInfo(derivedProof.document, {
documentLoader,
expansionMap
});

expandedProof["@type"] = types;

const ctx = jsonld.getValues(result.document, "@context");
const ctx = jsonld.getValues(derivedProof.document, "@context");

const compactProof = await jsonld.compact(expandedProof, ctx, {
documentLoader,
Expand All @@ -74,13 +107,22 @@ export const deriveProof = async (
delete compactProof[alias];
delete compactProof["@context"];

/**
* removes the @included tag when multiple proofs exist because the
* @included tag messes up the canonicalized bytes leading to a bad
* signature that won't verify.
**/
if (compactProof.proof["@included"]) {
compactProof.proof = compactProof.proof["@included"];
}

// add proof to document
const key = Object.keys(compactProof)[0];
jsonld.addValue(result.document, key, compactProof[key]);
jsonld.addValue(derivedProof.document, key, compactProof[key]);
} else {
delete result.proof["@context"];
jsonld.addValue(result.document, "proof", result.proof);
delete derivedProof.proof["@context"];
jsonld.addValue(derivedProof.document, "proof", derivedProof.proof);
}

return result.document;
return derivedProof.document;
};

0 comments on commit f402494

Please sign in to comment.