|
7 | 7 | generators,
|
8 | 8 | issueCloned
|
9 | 9 | } from 'data-integrity-test-suite-assertion';
|
| 10 | +import crypto from 'node:crypto'; |
10 | 11 | import {getMultiKey} from '../vc-generator/key-gen.js';
|
11 | 12 | import {getSuites} from './helpers.js';
|
12 | 13 |
|
@@ -328,5 +329,74 @@ function invalidHashProxy({
|
328 | 329 | if(typeof suite !== 'object') {
|
329 | 330 | return suite;
|
330 | 331 | }
|
| 332 | + if(suite._cryptosuite) { |
| 333 | + if(suiteName !== 'ecdsa-rdfc-2019') { |
| 334 | + throw new Error(`Unsupported suite ${suiteName}`); |
| 335 | + } |
| 336 | + suite._cryptosuite = new Proxy(suite._cryptosuite, { |
| 337 | + get(target, prop) { |
| 338 | + if(prop === 'createVerifyData') { |
| 339 | + return async function({ |
| 340 | + cryptosuite, document, proof, |
| 341 | + documentLoader, dataIntegrityProof |
| 342 | + } = {}) { |
| 343 | + const algorithm = 'SHA-512'; |
| 344 | + |
| 345 | + const c14nOptions = { |
| 346 | + documentLoader, |
| 347 | + safe: true, |
| 348 | + base: null, |
| 349 | + skipExpansion: false, |
| 350 | + messageDigestAlgorithm: algorithm |
| 351 | + }; |
331 | 352 |
|
| 353 | + // await both c14n proof hash and c14n document hash |
| 354 | + const [proofHash, docHash] = await Promise.all([ |
| 355 | + // canonize and hash proof |
| 356 | + _canonizeProof(proof, { |
| 357 | + document, cryptosuite, dataIntegrityProof, c14nOptions |
| 358 | + }).then(c14nProofOptions => sha512({ |
| 359 | + algorithm, |
| 360 | + string: c14nProofOptions |
| 361 | + })), |
| 362 | + // canonize and hash document |
| 363 | + cryptosuite.canonize(document, c14nOptions).then( |
| 364 | + c14nDocument => sha512({algorithm, string: c14nDocument})) |
| 365 | + ]); |
| 366 | + // concatenate hash of c14n proof options and hash of c14n document |
| 367 | + return _concat(proofHash, docHash); |
| 368 | + }; |
| 369 | + } |
| 370 | + return Reflect.get(...arguments); |
| 371 | + } |
| 372 | + }); |
| 373 | + } |
| 374 | + return suite; |
| 375 | +} |
| 376 | + |
| 377 | +function _concat(b1, b2) { |
| 378 | + const rval = new Uint8Array(b1.length + b2.length); |
| 379 | + rval.set(b1, 0); |
| 380 | + rval.set(b2, b1.length); |
| 381 | + return rval; |
| 382 | +} |
| 383 | + |
| 384 | +export async function sha512({string}) { |
| 385 | + return new Uint8Array(crypto.createHash('sha512').update(string).digest()); |
332 | 386 | }
|
| 387 | + |
| 388 | +async function _canonizeProof(proof, { |
| 389 | + document, cryptosuite, dataIntegrityProof, c14nOptions |
| 390 | +}) { |
| 391 | + // `proofValue` must not be included in the proof options |
| 392 | + proof = { |
| 393 | + '@context': document['@context'], |
| 394 | + ...proof |
| 395 | + }; |
| 396 | + dataIntegrityProof.ensureSuiteContext({ |
| 397 | + document: proof, addSuiteContext: true |
| 398 | + }); |
| 399 | + delete proof.proofValue; |
| 400 | + return cryptosuite.canonize(proof, c14nOptions); |
| 401 | +} |
| 402 | + |
0 commit comments