Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,12 @@
"base58-universal": "^2.0.0",
"base64url-universal": "^2.0.0",
"chai": "^4.3.7",
"chai-string": "^1.5.0",
"data-integrity-test-suite-assertion": "github:w3c-ccg/data-integrity-test-suite-assertion",
"jsonld-document-loader": "^2.0.0",
"json-canon": "^1.0.1",
"klona": "^2.0.6",
"multibase": "^4.0.6",
"mocha": "^10.2.0",
"uuid": "^9.0.0",
"varint": "^6.0.0",
Expand Down
4 changes: 2 additions & 2 deletions tests/30-rdfc-interop.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
import chai from 'chai';
import {createInitialVc} from './helpers.js';
import {endpoints} from 'vc-test-suite-implementations';
import {getSuiteConfig} from './test-config.js';
import {secureCredential} from './helpers.js';
import {verificationSuccess} from './assertions.js';

const {
Expand Down Expand Up @@ -81,7 +81,7 @@ const {
}
let issuedVc;
before(async function() {
issuedVc = await createInitialVc({
issuedVc = await secureCredential({
issuer: issuerEndpoint,
vc: credentials.interop[vcVersion].document,
vcVersion
Expand Down
4 changes: 2 additions & 2 deletions tests/40-sd-create.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/
import * as ecdsaSd2023Cryptosuite
from '@digitalbazaar/ecdsa-sd-2023-cryptosuite';
import {createInitialVc, endpointCheck} from './helpers.js';
import {endpointCheck, secureCredential} from './helpers.js';
import {
shouldBeBs58,
shouldBeBs64UrlNoPad,
Expand Down Expand Up @@ -51,7 +51,7 @@ describe('ecdsa-sd-2023 (create)', function() {
let proofs;
const verificationMethodDocuments = [];
before(async function() {
issuedVc = await createInitialVc({
issuedVc = await secureCredential({
issuer,
vc: credentials.create[vcVersion].document,
mandatoryPointers:
Expand Down
4 changes: 2 additions & 2 deletions tests/60-sd-interop.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Copyright 2023 Digital Bazaar, Inc.
* SPDX-License-Identifier: BSD-3-Clause
*/
import {createDisclosedVc, createInitialVc} from './helpers.js';
import {createDisclosedVc, secureCredential} from './helpers.js';
import chai from 'chai';
import {endpoints} from 'vc-test-suite-implementations';
import {getSuiteConfig} from './test-config.js';
Expand Down Expand Up @@ -83,7 +83,7 @@ const {
}
let disclosedCredential;
before(async function() {
const issuedVc = await createInitialVc({
const issuedVc = await secureCredential({
issuer: issuerEndpoint,
vc: credentials.interop[vcVersion].document,
mandatoryPointers: credentials.interop[vcVersion].mandatoryPointers,
Expand Down
248 changes: 248 additions & 0 deletions tests/90-algorithms-jcs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
/*!
* Copyright 2024 Digital Bazaar, Inc.
* SPDX-License-Identifier: BSD-3-Clause
*/
import {
assertAllUtf8,
assertDataIntegrityProof
} from './assertions.js';
import {
generateCredential,
isValidDatetime,
proofExists,
secureCredential,
setupReportableTestSuite,
setupRow,
verifyError,
verifySuccess
} from './helpers.js';
import canonicalize from 'json-canon';
import chai from 'chai';
import {ecdsaJcsVectors} from './vectors.js';
import {endpoints} from 'vc-test-suite-implementations';
import {expect} from 'chai';

const should = chai.should();

const cryptosuites = [
'ecdsa-jcs-2019',
];

const {match: issuers} = endpoints.filterByTag({
tags: cryptosuites,
property: 'issuers'
});

const {match: verifiers} = endpoints.filterByTag({
tags: cryptosuites,
property: 'verifiers'
});

describe('Algorithms - Create Proof (ecdsa-jcs-2019)', function() {
setupReportableTestSuite(this);
this.implemented = [...issuers.keys()];
for(const [columnId, {endpoints}] of issuers) {
describe(columnId, function() {
const [issuer] = endpoints;
let securedCredential;
before(async function() {
securedCredential = await secureCredential(
{issuer, vc: generateCredential()});
});
beforeEach(setupRow);
it('A data integrity proof (map), or an error, is produced as output.',
async function() {
this.test.link = 'https://www.w3.org/TR/vc-di-ecdsa/#create-proof-ecdsa-jcs-2019';
const proof = proofExists(securedCredential);
assertDataIntegrityProof(proof, 'ecdsa-jcs-2019');
// Since we are not sending proof options, we only do a positive test
});
it('If unsecuredDocument.@context is present, ' +
'set proof.@context to unsecuredDocument.@context.',
async function() {
this.test.link = 'https://www.w3.org/TR/vc-di-ecdsa/#create-proof-ecdsa-jcs-2019';
// NOTE, for backwards compatibility reason, this step is not mandatory
// This feature is designed to be used with proof sets/chains,
// when adding new context in subsequent proofs
const proof = proofExists(securedCredential);
should.exist(proof['@context'],
'Expected proof to have context.');
canonicalize(proof['@context']).should.equal(
canonicalize(securedCredential['@context']),
'Expected proof context to match document context.'
);
});
it('Let proof.proofValue be a base58-btc-encoded ' +
'Multibase value of the proofBytes.',
async function() {
this.test.link = 'https://www.w3.org/TR/vc-di-ecdsa/#create-proof-ecdsa-jcs-2019';
// Shallow multibase test
// TODO try decoding
const proof = proofExists(securedCredential);
should.exist(proof.proofValue,
'Expected proof to have proofValue.');
expect(proof.proofValue.startsWith('z')).to.be.true;
});
});
}
});

describe('Algorithms - Verify Proof (ecdsa-jcs-2019)', function() {
setupReportableTestSuite(this);
for(const [columnId, {endpoints}] of verifiers) {
describe(columnId, function() {
const [verifier] = endpoints;
beforeEach(setupRow);
it('The following algorithm specifies how to verify a ' +
'data integrity proof given an secured data document. ' +
'Required inputs are an secured data document (map securedDocument). ' +
'This algorithm returns a verification result.',
async function() {
this.test.link = 'https://www.w3.org/TR/vc-di-ecdsa/#verify-proof-ecdsa-rdfc-2019';
for(const curve of verifier.settings.supportedEcdsaKeyTypes) {
// Send a valid VC and an invalid VC to the verifier
// Check for success/error on response
const testVector = structuredClone(ecdsaJcsVectors[curve]);
await verifySuccess(verifier, testVector);

// Slice the proof
testVector.proof.proofValue =
testVector.proof.proofValue.slice(0, -1);
await verifyError(verifier, testVector);
// TODO, create a verifyProblemDetails function
}
});
});
}
});

describe('Algorithms - Transformation (ecdsa-jcs-2019)', function() {
setupReportableTestSuite(this);
this.implemented = [...issuers.keys()];
for(const [columnId, {endpoints}] of issuers) {
describe(columnId, function() {
const [issuer] = endpoints;
let securedCredential;
before(async function() {
securedCredential = await secureCredential(
{issuer, vc: generateCredential()});
});
beforeEach(setupRow);
it('The transformation options MUST contain a type identifier ' +
'for the cryptographic suite (type) and a cryptosuite identifier ' +
'(cryptosuite).',
async function() {
this.test.link = 'https://www.w3.org/TR/vc-di-ecdsa/#transformation-ecdsa-jcs-2019';
const proof = proofExists(securedCredential);
should.exist(proof.type,
'Expected a type identifier on the proof.');
should.exist(proof.cryptosuite,
'Expected a cryptosuite identifier on the proof.');
});
it('Whenever this algorithm encodes strings, ' +
'it MUST use UTF-8 encoding.',
async function() {
this.test.link = 'https://www.w3.org/TR/vc-di-ecdsa/#transformation-ecdsa-jcs-2019';
const proof = proofExists(securedCredential);
assertAllUtf8(proof);
});
it('If options.type is not set to the string DataIntegrityProof or ' +
'options.cryptosuite is not set to the string ecdsa-jcs-2019, ' +
'an error MUST be raised and SHOULD convey an error type ' +
'of PROOF_TRANSFORMATION_ERROR.',
async function() {
this.test.link = 'https://www.w3.org/TR/vc-di-ecdsa/#transformation-ecdsa-jcs-2019';
const proof = proofExists(securedCredential);
should.exist(proof.type,
'Expected a type identifier on the proof.');
should.exist(proof.cryptosuite,
'Expected a cryptosuite identifier on the proof.');
proof.type.should.equal('DataIntegrityProof',
'Expected DataIntegrityProof type.');
proof.cryptosuite.should.equal('ecdsa-jcs-2019',
'Expected ecdsa-jcs-2019 cryptosuite.');
});
});
}
});

describe('Algorithms - Proof Configuration (ecdsa-jcs-2019)', function() {
setupReportableTestSuite(this);
this.implemented = [...issuers.keys()];
for(const [columnId, {endpoints}] of issuers) {
describe(columnId, function() {
const [issuer] = endpoints;
let securedCredential;
before(async function() {
securedCredential = await secureCredential(
{issuer, vc: generateCredential()});
});
beforeEach(setupRow);
it('The proof options MUST contain a type identifier for the ' +
'cryptographic suite (type) and MUST contain a cryptosuite ' +
'identifier (cryptosuite).',
async function() {
this.test.link = 'https://www.w3.org/TR/vc-di-ecdsa/#proof-configuration-ecdsa-jcs-2019';
const proof = proofExists(securedCredential);
should.exist(proof.type,
'Expected a type identifier on the proof.');
should.exist(proof.cryptosuite,
'Expected a cryptosuite identifier on the proof.');
});
it('If proofConfig.type is not set to DataIntegrityProof ' +
'and/or proofConfig.cryptosuite is not set to ecdsa-jcs-2019, ' +
'an error MUST be raised and SHOULD convey an error type ' +
'of PROOF_GENERATION_ERROR.',
async function() {
this.test.link = 'https://www.w3.org/TR/vc-di-ecdsa/#proof-configuration-ecdsa-jcs-2019';
const proof = proofExists(securedCredential);
should.exist(proof.type,
'Expected a type identifier on the proof.');
should.exist(proof.cryptosuite,
'Expected a cryptosuite identifier on the proof.');
proof.type.should.equal('DataIntegrityProof',
'Expected DataIntegrityProof type.');
proof.cryptosuite.should.equal('ecdsa-jcs-2019',
'Expected ecdsa-jcs-2019 cryptosuite.');
});
it('If proofConfig.created is set and if the value is not a ' +
'valid [XMLSCHEMA11-2] datetime, an error MUST be raised and ' +
'SHOULD convey an error type of PROOF_GENERATION_ERROR.',
async function() {
this.test.link = 'https://www.w3.org/TR/vc-di-ecdsa/#proof-configuration-ecdsa-jcs-2019';
const proof = proofExists(securedCredential);
if(proof?.created) {
isValidDatetime(proof.created).should.equal(
true,
'Expected created value to be a valid datetime string.'
);
}
});
});
}
});

describe('Algorithms - Proof Serialization (ecdsa-jcs-2019)', function() {
setupReportableTestSuite(this);
this.implemented = [...issuers.keys()];
for(const [columnId, {endpoints}] of issuers) {
describe(columnId, function() {
const [issuer] = endpoints;
let securedCredential;
before(async function() {
securedCredential = await secureCredential(
{issuer, vc: generateCredential()});
});
beforeEach(setupRow);
it('The proof options MUST contain a type identifier for the ' +
'cryptographic suite (type) and MAY contain a cryptosuite identifier ' +
'(cryptosuite).',
async function() {
this.test.link = 'https://www.w3.org/TR/vc-di-ecdsa/#proof-serialization-ecdsa-jcs-2019';
const proof = proofExists(securedCredential);
should.exist(proof.type,
'Expected a type identifier on the proof.');
});
});
}
});
Loading