trust_tasks_proof 0.1.2 copy "trust_tasks_proof: ^0.1.2" to clipboard
trust_tasks_proof: ^0.1.2 copied to clipboard

W3C Data Integrity proofs for Trust Tasks: a ProofVerifier for package:trust_tasks and the signer that produces what it verifies, on ssi.

trust_tasks_proof #

W3C Data Integrity proofs for Trust Tasks: a ProofVerifier for package:trust_tasks, and the signer that produces what it verifies, built on Affinidi's package:ssi.

trust_tasks declares the ProofVerifier seam and implements no cryptosuite, so that it can stay dependency-free. This package is the implementation to put behind it when you want one that already works — the Dart counterpart of the Rust trust-tasks-proof crate. Each verifies what the other signs; for the same Ed25519 key, document and created, the two produce the same proofValue byte for byte.

dart pub add trust_tasks trust_tasks_proof

Requires Dart 3.6 or later.

Verifying inside the §7.2 pipeline #

import 'package:trust_tasks/trust_tasks.dart';
import 'package:trust_tasks_proof/trust_tasks_proof.dart';

final outcome = await consumeInbound(
  proofPolicy: ProofPolicy.verify(DataIntegrityProofVerifier.forDidKey()),
  // transport, spec, doc, handler, ... as usual
);

A document whose proof fails is rejected with proofInvalid, and nothing about why reaches the peer (SPEC §12.4). To log the reason, call verifyDetailed yourself; it returns a ProofVerification whose failure is one of malformedProof, issuerMismatch, unsupportedCryptosuite or signatureInvalid — the same taxonomy as the Rust crate.

See example/main.dart for a document signed by the Rust library, verified and then tampered with.

What is checked #

  1. The proof is a DataIntegrityProof with a non-empty cryptosuite, verificationMethod, proofPurpose and proofValue.
  2. The cryptosuite is one this verifier accepts.
  3. created, when present, is a dateTimeStamp — ending in Z or an explicit offset — and no more than clockSkew (60 seconds by default) in the future. An offset-less timestamp is refused rather than guessed at: VC Data Integrity §2.1 says to read it as UTC, and DateTime.parse would read it as local time.
  4. The proof is bound to the document's issuer. A valid signature proves only that some key signed. The DID part of verificationMethod (before #) must equal issuer exactly, with no normalization (SPEC §4.8), or the document is refused as issuerMismatch. Without this, anyone could sign with their own key while claiming to be someone else.
  5. The signature verifies over the document minus its proof, using the key the issuer's DID resolves to.

The verifier never mutates the document it is given and never throws for a bad one.

Resolving keys #

Constructor Resolves I/O
DataIntegrityProofVerifier.forDidKey() did:key only; every other method fails none
DataIntegrityProofVerifier.withResolver(resolver) whatever resolver does — e.g. ssi's UniversalDIDResolver for did:web, did:peer and did:webvh the resolver's

Resolution runs on input from a peer that has not been authenticated yet. If you accept did:web, prefer a resolver that caches and bounds its fetches.

Cryptosuites #

Cryptosuite
eddsa-jcs-2022 ✓
ecdsa-jcs-2019 ✓ P-256. P-384 too, but the Rust crate (through affinidi-data-integrity 0.7.11) accepts only P-256 for this suite, so use P-256 when a Rust peer must verify
eddsa-rdfc-2022, ecdsa-rdfc-2019 — a Trust Task document has no JSON-LD @context, so there is nothing for RDF canonicalization to expand
ML-DSA suites — see below

Pass cryptosuites: to either constructor to accept a subset.

Why no ML-DSA #

package:ssi's ML-DSA verifiers exist only in ssi 4. This package accepts ssi >=3.9.6 <5.0.0 so that it can share a dependency graph with package:didcomm, which pins ssi 3. The ssi APIs used here are identical in both majors, and the test suite runs against each.

Signing #

final signed = await signTrustTask(doc, signer); // signer: an ssi DidSigner

signTrustTask returns a copy of the document with a proof over everything else in it, replacing any proof already there. It refuses — with a SignException — to sign a document that could never verify: one with no issuer, or whose issuer is not the DID of the signer's verification method.

The cryptosuite follows from the key: eddsa-jcs-2022 for Ed25519, ecdsa-jcs-2019 for P-256 and P-384. created is written in UTC with a Z.

It builds the proof itself instead of calling ssi's generators. Before ssi 4.3.0 those wrote created with no zone designator, which this verifier and the Rust one both refuse, and this package still supports ssi 3.9.

License #

Apache-2.0.

0
likes
160
points
146
downloads

Documentation

Documentation
API reference

Publisher

verified publishertrusttasks.org

Weekly Downloads

W3C Data Integrity proofs for Trust Tasks: a ProofVerifier for package:trust_tasks and the signer that produces what it verifies, on ssi.

Repository (GitHub)
View/report issues
Contributing

License

Apache-2.0 (license)

Dependencies

crypto, ssi, trust_tasks

More

Packages that depend on trust_tasks_proof