identity: SD-JWT interoperability measured in both directions with @sd-jwt/core 0.23.0 and jose 6.2.12 (ML-DSA-65 included), nested _sd_alg refused, the SD-JWT VC profile (draft-19, dc+sd-jwt, vct, Token Status List offline); conformance: SD-JWT and SD-JWT VC enrolled (213 rules, 13 verifiers, 553 vectors)

This commit is contained in:
Aere Network 2026-10-18 11:07:27 +03:00
parent fab02f7952
commit e1bb4e25d8
109 changed files with 9823 additions and 175 deletions

View File

@ -21,8 +21,8 @@ notarization command of the verification layer and for the agents' x402 wallet (
| [`market-settlement/`](market-settlement/) | the dispute and settlement rail of a verifiable infrastructure market, measured end to end on testnet 28001: an order with its reward in escrow and a provider bond, the result committed on chain with its execution envelope notarized under a post-quantum certified anchor, a challenge window in which anyone disputes with a recomputed result and a bond, an arbiter that can only route the escrow (with a permissionless 14-day timeout), deadline reclaims, and an AIP-23 settlement receipt; a pure judge over the job's timeline that checks deadlines, the window, who resolved, the payout, the replay and the proof |
| [`verifiable-data/`](verifiable-data/) | a dataset whose every answer is checkable against a short commitment without the data: RFC 9162 commitments per version (append-only, consistency proofs), equality and range queries proven correct AND complete (contiguous run of a sorted index plus its two neighbours), hash-based selective disclosure of fields, availability sampling against the serving endpoint, and the version's AIP-23 envelope notarized and read back under a post-quantum certified anchor; not zero knowledge, and says so |
| [`ai-trust/`](ai-trust/) | the trust chain of an AI result: the agent's identity (agents/), the model artifact's attestation, the host's runtime record (verify-layer/), the policy and signed ledger, the Proof of AI envelope and the chain as witness, joined in one bundle whose verifier checks only the links between them |
| [`conformance/`](conformance/) | a conformance suite for the AIP-23 proof kinds: one verdict form over the verifiers published here (four levels: integrity, authenticity, anchoring, finality; each passed, failed or not measured, with the named rule), 181 rules of eleven verifiers read from their code (the presentation verifier of identity/ and the device verifier of device-identity/ among them since 2026-10-05), 422 vectors derived from the producers and from evidence recorded on testnet 28001 (each invalid one is one operation away from one that is not, or one change at its producer, and must be refused for exactly its named rules), and a runner that scores any implementation given as a command, in any language; a second implementation in Python covers 6 of the 181 rules. Not a certification and not an audit |
| [`identity/`](identity/) | post-quantum credentials: an issuer signs claims (hybrid Ed25519 + ML-DSA-65, both required), the holder shows only the claims it picks (selective disclosure in the manner of SD-JWT, RFC 9901, in a format of its own), bound to the verifier's audience and nonce; delegation to a phone, an agent or a ten-minute session key that can only narrow; revocation and an issuer status list in the manner of W3C Bitstring Status List; all checked offline from the files; and compliance without surveillance: a verifier's policy (issuers, required claims) judged on a presentation, recorded as an AIP-23 envelope that carries no personal data; and the Travel Rule between VASPs, the IVMS101 data sealed for the receiving VASP with a hybrid X25519 + ML-KEM-768 key encapsulation, signed, bound to the transfer and acknowledged; and the same credentials as standard SD-JWT (IETF RFC 9901): issued with the issuer's Ed25519 key (EdDSA) or its ML-DSA-65 key, presented with a key binding JWT, and verified against the RFC's own example vectors (`identity-cli.mjs verify-sdjwt`, behind Aere Cloud's POST /v1/identity/sd-jwt/verify) |
| [`conformance/`](conformance/) | a conformance suite for the AIP-23 proof kinds: one verdict form over the verifiers published here (four levels: integrity, authenticity, anchoring, finality; each passed, failed or not measured, with the named rule), 213 rules of thirteen verifiers read from their code (the presentation verifier of identity/ and the device verifier of device-identity/ among them since 2026-10-05, the SD-JWT and SD-JWT VC verifiers since 2026-10-18), 553 vectors derived from the producers and from evidence recorded on testnet 28001 (each invalid one is one operation away from one that is not, or one change at its producer, and must be refused for exactly its named rules), and a runner that scores any implementation given as a command, in any language; a second implementation in Python covers 6 of the 213 rules. Not a certification and not an audit |
| [`identity/`](identity/) | post-quantum credentials: an issuer signs claims (hybrid Ed25519 + ML-DSA-65, both required), the holder shows only the claims it picks (selective disclosure in the manner of SD-JWT, RFC 9901, in a format of its own), bound to the verifier's audience and nonce; delegation to a phone, an agent or a ten-minute session key that can only narrow; revocation and an issuer status list in the manner of W3C Bitstring Status List; all checked offline from the files; and compliance without surveillance: a verifier's policy (issuers, required claims) judged on a presentation, recorded as an AIP-23 envelope that carries no personal data; and the Travel Rule between VASPs, the IVMS101 data sealed for the receiving VASP with a hybrid X25519 + ML-KEM-768 key encapsulation, signed, bound to the transfer and acknowledged; and the same credentials as standard SD-JWT (IETF RFC 9901): issued with the issuer's Ed25519 key (EdDSA) or its ML-DSA-65 key, presented with a key binding JWT, and verified against the RFC's own example vectors and, since 2026-10-18, interoperable in both directions with a foreign library (@sd-jwt/core 0.23.0 with jose 6.2.12, ML-DSA-65 included; `interop/`), plus the SD-JWT VC profile (draft-ietf-oauth-sd-jwt-vc-19, `dc+sd-jwt`, `vct`, a Token Status List judged offline) (`identity-cli.mjs verify-sdjwt`, behind Aere Cloud's POST /v1/identity/sd-jwt/verify, and `verify-sdjwt-vc`) |
| [`device-identity/`](device-identity/) | what a machine is, as a chain of signed statements checked offline: the manufacturer's credential for the device key (the manufacturer and the owners sign hybrid, Ed25519 + ML-DSA-65, both required; the device key is ML-DSA-65), a firmware release with a floor and retractions (a rolled-back or retracted firmware is refused), ownership by transfers each signed by the owner before, the current owner's authorization, a status registry in which the manufacturer's retirement is final and an owner's lasts as long as its ownership (after a sale the records of the previous owner are named and not applied: a seller could date one before the sale after it; a retirement by an owner that survives a sale needs a witness of time that is not built), and the device's fresh attestation to the verifier's nonce, with an AIP-23 envelope that can be notarized and read back under a post-quantum certified anchor; one verifier makes every check it can reach, names every rule that refused and says VALID, PARTIAL (what it was not handed, or could not read) or INVALID. The device key is a software key: no TPM, secure element or TEE is used or checked, and the README says what that leaves open |
| [`exposure-report/`](exposure-report/) | classifies Bitcoin and Ethereum addresses by whether their public key is already readable from chain data, in three declared modes (offline, by address or script type only; through your own Electrum server, Esplora index, Bitcoin Core or Ethereum JSON-RPC, one declared target; through a third-party provider only with written consent, recorded in the report), with exactly two labels ("exposed (on-chain evidence)", "no on-chain evidence of exposure") and "unmeasured" when the reading did not happen, the evidence named for each address, and a dated report (JSON, Markdown, an AIP-23 `compliance` envelope that binds the JSON). It records what was readable on the date of the report: it does not protect, move or recover any coins, it does not change what a spend reveals, and it says nothing about the future. The one component with npm dependencies (`@noble/hashes`, `@noble/curves` 1.x: `npm install --ignore-scripts` in its directory) |
@ -44,14 +44,14 @@ test, counts as a failure of the control. Results measured on 2026-09-29 (Node.j
| proof-kinds | 24/24 with the same verifier (`AERE_VERIFY_PROOF=... node proba-proof-kinds.mjs`) | six negative controls inside the test |
| readiness | 6/6 (`node proba-adrese-private.mjs`: the private-address rules, and a local listener no scan may touch) | the rate limit and the queue bound are tested where the service runs, not here (its README says so) |
| control-plane | planner 44/44 (2026-10-18: a key agreement or a client-side TLS configured by the application itself is not routed to the TLS gateway; a self-signed trust anchor is blocked, not "automatic through PKI"; test code is LOW with its own scope), command line 10/10, execution 30/30 on real products started locally, remediation 33/33 on real TLS servers (all five server profiles measured end to end on 2026-10-18: nginx, Apache, HAProxy, Node, Go), compliance report 30/30 (with the AIP-23 verifier; test-code findings are counted apart and are not "exposed today"), console 8/8; the console viewer in a real Chromium, phone and desktop, 26/26 (`node proba-consola-web.mjs`, measured 2026-09-30; needs `playwright-core` and a Chromium, otherwise it exits 2) | remediation 7/7, compliance report 3/3 in this repository; viewer 8/8 (`node control-negativ-consola-web.mjs`) |
| identity | 46/46 (`node proba-identity.mjs`, with the AIP-23 verifier for its envelope test; without it that test is reported as skipped and the exit code is 2), compliance 15/15 (`node proba-conformitate.mjs`), Travel Rule 19/19 (`node proba-travel-rule.mjs`), SD-JWT 23/23 (`node proba-sdjwt.mjs`, the RFC 9901 vectors included), measured 2026-10-05 | 53/53 (`node control-negativ-identity.mjs`); compliance 14/14 (`node control-negativ-conformitate.mjs`); Travel Rule 19/19 (`node control-negativ-travel-rule.mjs`); SD-JWT 29/29 (`node control-negativ-sdjwt.mjs`) |
| identity | 46/46 (`node proba-identity.mjs`, with the AIP-23 verifier for its envelope test; without it that test is reported as skipped and the exit code is 2), compliance 15/15 (`node proba-conformitate.mjs`), Travel Rule 19/19 (`node proba-travel-rule.mjs`), SD-JWT 25/25 (`node proba-sdjwt.mjs`, the RFC 9901 vectors and fixtures derived from @sd-jwt/core 0.23.0 included), SD-JWT VC 10/10 (`node proba-sdjwt-vc.mjs`); interoperability with @sd-jwt/core and jose in both directions 26/26 and 28/28 (`interop/`, with those libraries installed in a folder you name; otherwise reported unmeasured), measured 2026-10-18 | 53/53 (`node control-negativ-identity.mjs`); compliance 14/14 (`node control-negativ-conformitate.mjs`); Travel Rule 19/19 (`node control-negativ-travel-rule.mjs`); SD-JWT 31/31 (`node control-negativ-sdjwt.mjs`); SD-JWT VC 16/16 (`node control-negativ-sdjwt-vc.mjs`) |
| agents | policy 27/27 with the AIP-23 verifier (without it 25 run, 2 are reported as skipped and the exit code is 2), ledger 54/54 on 2026-10-05, approval and revocation 39/39, the chain as witness 26/26 without a network and 7/7 on testnet 28001 on 2026-09-30 (`proba-agent-ancora-testnet.mjs`, needs a funded testnet key and the AIP-23 verifier), command line 23/23 through files and processes only (on Linux and macOS one more test checks the key file mode; not measured here); x402 wallet 25/25, 2-of-2 co-signing 16/16 and payment verifier 14/14 without a network; on the public testnet 28001, 9/9 with the wallet key and 13/13 with the 2-of-2 contract wallet (`agents/x402/proba-x402-testnet.mjs`, `agents/x402/proba-cosign-testnet.mjs`, each needs a funded testnet key); the contract's artifact recompiles byte for byte with solc 0.8.23 (`node x402/recompileaza-contract.mjs --solc <solc>`) | 26/26 (`node control-negativ-aprobare.mjs`); the chain as witness 11/11 (`node control-negativ-ancora.mjs`); x402 30/30 (`node x402/control-negativ-wallet.mjs`); the contract's own tests (7) and their negative control (4/4) run in the Aere Network contracts project, not in this repository |
| proof-of-ai | 6/6 with the AIP-23 verifier (`AERE_VERIFY_PROOF=... node proba-proof-of-ai.mjs`); without it the probe reports NEMASURAT and exits 2 | one negative control inside the test (an envelope touched after its hash: INVALID) |
| payments | 23/23 without a chain (`node proba-risc.mjs`: the verdicts under a policy, the reproducible verdict hash, a receipt verified, nine forged ones refused by name, a malformed payment refused by name); 9/9 on testnet 28001 on 2026-10-02 (`AERE_TESTNET_KEY_FILE=... AERE_ETHERS_DIR=... node proba-plata-28001.mjs`: a payment allowed, paid, its receipt notarized and read back with finality PASSED, the public reader VALID; a payment above the limit refused with nothing sent; the fourth in the window refused; a forged receipt and a loosened policy INVALID) | 10/10 (`node proba-risc.mjs --control-negativ`: form, asset, counterparty, rate, per-payment limit, window, linkage, USD arithmetic, verdict reproduction, chain facts, each planted out on a copy and each forged fixture then accepted) |
| market-settlement | 20/20 on testnet 28001 on 2026-10-02 (`AERE_TESTNET_KEY_FILE=... AERE_ETHERS_DIR=... node proba-piata-28001.mjs`: five scenarios on AereComputeMarketV3 deployed from the committed artifact, every refusal by its named custom error, the provider's notarized envelope read back under a post-quantum certified anchor); the judge on the recorded timelines 26/26 without a chain (`node proba-judecata.mjs`: seven honest readings VALID, eighteen forged or malformed ones INVALID for their named reason, the settlement receipt) | 10/10 (`node proba-judecata.mjs --control-negativ`: form, completeness of the timeline, posting, deadline, window, arbiter, payout, result bytes, replay, proof, each planted out on a copy and each forged fixture then accepted) |
| verifiable-data | 23/23 with the AIP-23 verifier (`AERE_VERIFY_PROOF=... node proba-verifiable-data.mjs`: honest answers VALID, ten forged or malformed ones INVALID for their named reason, availability sampling on a local server; the envelope row is NEMASURAT without the verifier, exit 2); the two chain rows of `--viu` measured on testnet 28001 on 2026-10-02 (a version notarized with a test key and read back under a post-quantum certified anchor; evidence in `dovezi/`) | 5/5 (`node proba-verifiable-data.mjs --control-negativ`: field commitment, index order, completeness, consistency, sampling, each planted out on a copy and each forged fixture then accepted) |
| ai-trust | 16/16 with the AIP-23 verifier, measured 2026-10-05 (`AERE_VERIFY_PROOF=... node proba-lant-de-incredere.mjs`: the whole chain on a committed fixture, then thirteen bundles broken on purpose, each refused for its named reason, among them an agent with a classical key and an audit head signed with one); without the verifier it exits 2 | 11/11 (`node proba-lant-de-incredere.mjs --control-negativ`) |
| conformance | 12/12 on 2026-10-14 with the AIP-23 verifier as served (fetched and installed in an empty folder), Python 3 and testnet 28001 read (`AERE_VERIFY_PROOF=... node proba-conformance.mjs --online`: the rules and the vectors are what the code derives, every rule has a vector, every invalid vector is one operation from its base or one declared change at its producer, the published verifiers pass 467/467, an independent Python implementation passes the 62 it claims and the other 405 are reported not covered, 96,757 malformed inputs and 183 malformed envelope files each get a verdict); without `--online` the nine chain vectors are reported unmeasured and the exit code is 2 | 263/263 on 2026-10-14: 181/181 rules (`node proba-conformance.mjs --control-negativ --online`: each rule planted out of its verifier in a copy; the vectors that expect it, and only they, must fail), then 76/76 conditions of the device verifier's compound checks, each planted out alone (exactly the vectors written for it must fail), then six controls of the instruments |
| conformance | 12/12 on 2026-10-18 with the AIP-23 verifier as served (fetched and installed in an empty folder), Python 3 and testnet 28001 read (`AERE_VERIFY_PROOF=... node proba-conformance.mjs --online`: the rules and the vectors are what the code derives, every rule has a vector, every invalid vector is one operation from its base or one declared change at its producer, the published verifiers pass 553/553, an independent Python implementation passes the 62 it claims and the other 491 are reported not covered, 97,966 malformed inputs and 183 malformed envelope files each get a verdict); without `--online` the nine chain vectors are reported unmeasured and the exit code is 2 | 295/295 on 2026-10-18: 213/213 rules (`node proba-conformance.mjs --control-negativ --online`: each rule planted out of its verifier in a copy; the vectors that expect it, and only they, must fail), then 76/76 conditions of the device verifier's compound checks, each planted out alone (exactly the vectors written for it must fail), then six controls of the instruments |
| device-identity | 372/372 with the AIP-23 verifier, measured 2026-10-14 (`AERE_VERIFY_PROOF=... node proba-device.mjs`: fifty-four bundles that must be VALID; seventy-seven with something not brought, not read or not readable, each PARTIAL for its named causes; two hundred and four attack rows, each refused for exactly its named rules, among them a clone with another key, a rolled-back or retracted firmware (also when the release is left out of the bundle), a previous owner that still signs, an owner's retirement written under no ownership head, a replayed attestation, an attestation dated ahead of the verifier's clock, a manufacturer the verifier does not trust, a retirement, a classical key under the ML-DSA-65 name, a signature in another base64 text, a day that does not exist; 804 damaged bundles each given a verdict; the command line through files only; the evidence recorded on testnet 28001 judged again offline); the chain as witness 10/10 on testnet 28001 on 2026-10-05, before the repairs of that day (`proba-device-ancora-testnet.mjs`, needs a funded testnet key and the AIP-23 verifier; not run again since: the bundles and readings it recorded give the same verdicts under the verifier of now) | 220/220 (`node control-negativ-device.mjs`: the untouched copy green; each of the 47 rules taken out of a copy, the rows that expect it, and only they, go red; 172 more plantings, most of them one condition of a compound check taken out alone, each with its rows) |
| exposure-report | 164 passed and 1 `NEMASURAT` of 165 rows in the AERE development tree on 2026-10-14 (`node proba-expunere.mjs`: codec checks with real public vectors, mode 1 and mode 2 through four mock targets that serve recorded responses, the network guard's proof that in modes 1 and 2 nothing leaves the machine, the language gate, the AIP-23 `compliance` envelopes judged by the reference verifier; the `NEMASURAT` row is mode 3 against a real provider, which would send addresses to a third party); in this copy, after `npm install --ignore-scripts` in its directory: 153 passed, 0 red, 0 broken, 12 `NEMASURAT` with the reason (the rows compared with the AIP-23 verifier, the anchor verifier's RLP encoder and MPT walker and the shield's header pins, none of which is in this repository: with `AERE_PROOF_PROTOCOL_VERIFY`, `AERE_VERIFY_PROOF` and `AERE_EXPUNERE_PINI` naming them the rows run, 162 passed and 3 `NEMASURAT`; the scan of the directory for names from the AERE host inventory; the git-ignore row outside a git tree); the exit code is 0 unless a row is red or broken | inside the test, 2026-10-14: each rule has its reverse planting in a copy of the tool (a foreign provider planted on each network path is caught, a label planted in the language gate is refused, each classification rule taken out turns its row red, a `@noble/curves` 2.x planted first is passed over and alone is named as missing), and the recorded fixtures are judged against their declared date |
@ -62,4 +62,4 @@ interface, command line and data (`definePolicy`, `verifyLedger`, `approve`, ...
## Licence
MIT, see [LICENSE](LICENSE). Files: 743 (pq-gateway 9, pq-kms 10, pq-pki 6, crypto-inventory 73, verify-layer 12, proof-kinds 3, control-plane 27, agents 39, identity 15, proof-of-ai 3, ai-trust 6, verifiable-data 7, market-settlement 9, payments 8, conformance 479, device-identity 11, exposure-report 18, readiness 4).
MIT, see [LICENSE](LICENSE). Files: 838 (pq-gateway 9, pq-kms 10, pq-pki 6, crypto-inventory 73, verify-layer 12, proof-kinds 3, control-plane 27, agents 39, identity 24, proof-of-ai 3, ai-trust 6, verifiable-data 7, market-settlement 9, payments 8, conformance 565, device-identity 11, exposure-report 18, readiness 4).

View File

@ -42,9 +42,10 @@ verdict (`vectori/payment-receipt/company-p1-28001.valid.json`).
## What is enrolled
`REGULI.json` is derived from the code (`node deriva-reguli.mjs --verifica`): 181 rules of 11 verifiers, 15 artifact kinds. By level:
142 rules are reported at `integrity`, 36 at `authenticity`, 3 at `anchoring` (one of them, `envelope.finality`, is reported at
`anchoring` or at `finality` by the place that refused).
`REGULI.json` is derived from the code (`node deriva-reguli.mjs --verifica`): 213 rules of 13 verifiers, 17 artifact kinds (since
2026-10-18; 181 rules of 11 verifiers, 15 kinds before the SD-JWT verifiers were enrolled). By level: 170 rules are reported at
`integrity`, 40 at `authenticity`, 3 at `anchoring` (one of them, `envelope.finality`, is reported at `anchoring` or at `finality` by
the place that refused).
| artifact kind | judged by | rules |
|---|---|---|
@ -59,6 +60,8 @@ verdict (`vectori/payment-receipt/company-p1-28001.valid.json`).
| `agent-ledger` (an agent's signed ledger under its policy) | `agents/agent-ledger.mjs` | 16: `agents.ledger-form`, `.policy`, `.other-policy`, `.session`, `.key`, `.identity`, `.anchor`, `.seq`, `.chain`, `.body`, `.signature`, `.hash`, `.time`, `.revocation`, `.approvals`, `.decision` |
| `identity-presentation` (a credential shown by its holder or by the last delegate of a chain, judged with what the verifier brings: its audience, its nonce, its clock, the issuers it trusts, the status lists and the revocations it was handed) | `identity/identity.mjs` | 37: `identity.form`, `.issuer-id`, `.holder-id`, `.credential-signature`, `.issuer-trusted`, `.credential-window`, `.status-list`, `.credential-revoked`, `.sd-distinct`, `.disclosure-readable`, `.disclosure-signed`, `.disclosure-once`, `.disclosure-plain`, `.claim-name`, `.binding-credential`, `.binding-disclosures`, `.binding-delegations`, `.presenter`, `.presentation-signature`, `.audience`, `.nonce`, `.freshness`, `.chain-length`, `.delegation-form`, `.delegation-ids`, `.delegation-from`, `.delegation-parent`, `.delegation-signature`, `.delegation-scope`, `.delegation-window`, `.delegation-depth`, `.delegation-narrows`, `.delegation-credential`, `.delegation-claims`, `.delegation-audience`, `.delegation-revoked`, `.unreadable` |
| `device-bundle` (the chain of a device: the manufacturer's credential for the device key, a firmware release, the ownership transfers, the owner's authorization, the device's attestation and its AIP-23 envelope, judged with what the verifier brings: its clock, nonce and audience, the manufacturers it trusts, the recall lists, firmware policies and status records it read, its own reading of the notarized envelope) | `device-identity/device.mjs` | 47: `device.form`, `.manufacture-form`, `.manufacturer-id`, `.manufacture-holder`, `.manufacture-signature`, `.manufacturer-trusted`, `.manufacture-window`, `.manufacture-status-list`, `.manufacture-revoked`, `.device-key`, `.device-id`, `.firmware-form`, `.firmware-signer`, `.firmware-signature`, `.firmware-model`, `.firmware-retracted`, `.firmware-rollback`, `.firmware-software`, `.chain-length`, `.transfer-form`, `.transfer-device`, `.transfer-ids`, `.transfer-from`, `.transfer-prev`, `.transfer-signature`, `.transfer-time`, `.authorization-form`, `.authorization-device`, `.authorization-owner`, `.authorization-ownership`, `.authorization-signature`, `.authorization-window`, `.authorization-action`, `.status-retired`, `.status-suspended`, `.attestation-form`, `.attestation-key`, `.attestation-device`, `.attestation-signature`, `.audience`, `.nonce`, `.freshness`, `.attestation-firmware`, `.attestation-ownership`, `.witness-envelope`, `.witness-time`, `.unreadable` |
| `sdjwt-presentation` (an SD-JWT of IETF RFC 9901, as issued or with its Key Binding JWT, judged with what the verifier brings: the issuer key it chose, a public JWK, never one taken from the token; its clock; its audience and nonce; the issuer and the explicit type it expects; whether it requires key binding and `exp`) | `identity/sdjwt.mjs` (enrolled 2026-10-18) | 23: `sdjwt.form`, `.alg`, `.typ`, `.crit`, `.key`, `.signature`, `.issuer`, `.sd-alg`, `.disclosure-form`, `.disclosure-twice`, `.digest-twice`, `.disclosure-name`, `.claim-conflict`, `.unreferenced`, `.time`, `.kb-context`, `.kb-required`, `.kb-cnf`, `.kb-claims`, `.kb-audience`, `.kb-nonce`, `.kb-freshness`, `.kb-sd-hash` |
| `sdjwt-vc-presentation` (an SD-JWT VC of `draft-ietf-oauth-sd-jwt-vc`, judged as the SD-JWT above plus the profile: the credential type the verifier expects, and the Token Status List it fetched for the `status` the credential names) | `identity/sdjwt-vc.mjs` (enrolled 2026-10-18) | 9 of its own, on top of the 23 of `sdjwt`: `sdjwtvc.vct-expected`, `.vct`, `.vct-mismatch`, `.disclosed-protected`, `.form`, `.status-list`, `.status-index`, `.status-revoked`, `.status-unjudged` |
A module verifier exports the list of rules it can name (`REGULI`; its helper throws on any other) and marks its rules in one of two
ways, both read by the derivation: a marker on every check of a rule (nine modules), or the rule named at every call of the
@ -88,15 +91,21 @@ adapter writes them in the reason of the integrity level, and the vectors compar
So `vectori/device-bundle/resold-after-retirement.valid.json` is `VALID` here, and a verifier that drops the naming still passes it; that the
naming is there is measured by the device component's own probe, not by this suite.
**Not enrolled**, counted in the same file: three verifiers of the identity component that sit beside the enrolled one or on top of
it: SD-JWT (26 calls of its refusal helper), Travel Rule (20 places that add a reason) and compliance (3). Their refusals are texts,
not rule ids. Their own probes and negative controls stay what checks them.
The SD-JWT verifier and the SD-JWT VC profile (enrolled 2026-10-18) stop at their first refusal and name its rule: an integrity refusal
leaves the authenticity level `NOT_MEASURED` (`not-reached`), an authenticity refusal leaves integrity so. A VC presentation whose
`status` the verifier waived (`requireStatus: false`) and did not judge is `PARTIAL` (`claim-not-checked`), like a credential whose
status list was not read. The profile imports `sdjwt.mjs` from its real file, so a planted copy of `sdjwt.mjs` is reached only through
the artifact `sdjwt-presentation`: no `sdjwt-vc-presentation` vector expects a rule of `sdjwt` (they all exercise them).
**Not enrolled**, counted in the same file: two verifiers of the identity component that sit on top of the enrolled ones: Travel Rule
(20 places that add a reason) and compliance (3). Their refusals are texts, not rule ids. Their own probes and negative controls stay
what checks them.
## The vectors
`vectori/` holds 467 vectors (458 offline, 9 that read testnet 28001; 19 MB, since every device and identity vector carries its ML-DSA-65 keys and signatures), listed with their digests in `vectori/INDEX.json`:
`vectori/` holds 553 vectors (544 offline, 9 that read testnet 28001; 20 MB, since every device and identity vector carries its ML-DSA-65 keys and signatures), listed with their digests in `vectori/INDEX.json`:
envelope 64, payment-risk 11, payment-receipt 10, market-timeline 26, dataset 22, ai-trust-bundle 24, audit-log 19, audit-inclusion
10, audit-consistency 4, agent-ledger 18, identity-presentation 65, device-bundle 194. By expected verdict: 64 `VALID`, 66 `PARTIAL`, 337 `INVALID`. None is typed by hand
10, audit-consistency 4, agent-ledger 18, identity-presentation 65, device-bundle 194, sdjwt-presentation 54, sdjwt-vc-presentation 32. By expected verdict: 81 `VALID`, 68 `PARTIAL`, 404 `INVALID`. None is typed by hand
(`node genereaza-vectori.mjs --verifica` regenerates them and compares byte for byte):
- the 16 AIP-23 kinds come from their producers on fixed inputs (the same envelopes as the published AIP-23 kind vectors); the audit
@ -118,13 +127,22 @@ envelope 64, payment-risk 11, payment-receipt 10, market-timeline 26, dataset 22
image and its Proof of Software attestation are the fixtures of the device component; `--proaspat --refa device` makes this one
source anew when the producers of the device component change, and every other vector stays byte for byte); an envelope with
random content that nobody notarized; a dataset of 16 records with random salts; and the transaction of the recorded receipt read
from the chain (two read calls).
from the chain (two read calls); since 2026-10-18 also an SD-JWT and an SD-JWT VC issued with AERE keys (an issuer, a holder, a
stranger: three hybrid key pairs each, made and discarded), presented to one verifier, the VC's Status List Tokens (clean, revoked,
suspended, 8 bits, for another uri, expired, by a stranger, typed JWT, without `iat`, too short, ML-DSA-65) and the forged siblings
only a key holder can make (a key binding JWT by a stranger or without its nonce, a digest signed twice, a nested `_sd_alg`, a
disclosure named `_sd`, a claim named `__proto__`, an algorithm confusion, a `status` behind a disclosure, and so on);
- the SD-JWT vectors have two more sources that are fixed text: the example of RFC 9901 Section 5 with the key of its Appendix A.5
(`identity/fixturi-rfc9901.json`), and the tokens of `@sd-jwt/core` 0.23.0 and `@sd-jwt/sd-jwt-vc` 0.23.0 with the status lists of
`@owf/token-status-list` 0.5.0 (`identity/interop/fixturi-interop-*.json`), which the identity component derived from those
libraries' real output on 2026-10-18, with their public test keys.
An `INVALID` vector names its `base` and its `mutation`: **one operation** (set, remove or add at one JSON path) applied to the input
of a vector that is not invalid, and it must be refused for exactly the rules in `expected.failed`, not merely refused: 221 of the
337 are made this way. Where the rule sits under a hash or a signature, one place is not reachable (changing an amount under the
of a vector that is not invalid, and it must be refused for exactly the rules in `expected.failed`, not merely refused: 249 of the
404 are made this way. Where the rule sits under a hash or a signature, one place is not reachable (changing an amount under the
instruction hash trips the binding first; a false decision in a ledger must still be signed by the agent; a disclosure the issuer never signed must still be signed for by
the holder; an authorization by a previous owner must still be signed by that owner): the other 116 are made at
the holder; an authorization by a previous owner must still be signed by that owner; a digest repeated in an SD-JWT must still be
signed by its issuer, a key binding JWT for another audience by its holder): the other 155 are made at
the producer, the commitments above the change recomputed with the published formulas, and every path that moved is declared
(`mutation.changed`). Eleven vectors expect more than one rule: rules that guard the same field cannot be separated (a looser policy shown
under a receipt also makes the risk verdict not reproduce; a Proof of AI envelope that is changed is also no longer the one the
@ -136,9 +154,9 @@ key breaks both the id derivation and the match with the manufacturer's credenti
```
AERE_VERIFY_PROOF=<verify-proof.mjs from aere.network/tools, with verify-anchor.mjs, mpt.mjs, falcon512.mjs, registry-v3.mjs and package.json beside it and npm install done>
node conformance.mjs --impl "node implementare-aere.mjs" # the published verifiers behind the one verdict form: 458 offline vectors
node conformance.mjs --impl "node implementare-aere.mjs" # the published verifiers behind the one verdict form: 544 offline vectors
node conformance.mjs --impl "node implementare-aere.mjs" --online # and the 9 that read testnet 28001 (nothing is sent)
node conformance.mjs --impl "python3 implementare-integritate.py" # an independent implementation: 62 vectors, 405 reported NOT COVERED
node conformance.mjs --impl "python3 implementare-integritate.py" # an independent implementation: 62 vectors, 491 reported NOT COVERED
node conformance.mjs --impl "<your command>" # yours
node implementare-aere.mjs <artifact.json> [--online] # one artifact { artifact, input }: its verdict
```
@ -148,8 +166,10 @@ not JSON at all: a file that is not an envelope is refused at the form level, by
the vectors show (`{ log, head?, signer? }` for an audit log, `{ ledger, policy }` for an agent's ledger, `{ bundle }` for a trust
chain, `{ presentation, now, audience?, nonce?, trustedIssuers?, statusLists?, revocations?, maxAgeS? }` for a presentation of a
credential, `{ bundle, now, nonce?, audience?, trustedManufacturers?, statusLists?, firmwarePolicies?, statusRecords?,
softwareAttestation?, anchors?, maxAgeS? }` for a device bundle: `now`, the verifier's clock, is required for both, since a verdict
on the clock of the machine that runs a vector would not reproduce).
softwareAttestation?, anchors?, maxAgeS? }` for a device bundle, `{ sdJwt, issuerKey, issuerAlg?, now, audience?, nonce?,
expectedIssuer?, expectedTyp?, requireKeyBinding?, requireExp?, maxAgeS? }` for an SD-JWT presentation and the same plus
`{ expectedVct, statusListJwt?, statusListKey?, statusListAlg?, requireStatus? }` for an SD-JWT VC: `now`, the verifier's clock, is
required for all of them, since a verdict on the clock of the machine that runs a vector would not reproduce).
An implementation is a command that answers three calls with JSON on stdout: `--capabilities` (`{ artifacts, rules, online, batch }`:
what it claims to judge), `<vector.json> [--online]` (the verdict above for the file's `{ artifact, input }`), and, if it says
@ -159,14 +179,33 @@ exact set of failed rules and the state of each of the four levels are the expec
refusal. Without `--online` an implementation must not open a connection.
`implementare-integritate.py` is the second implementation: Python, standard library only, written from the rules and not from the
JavaScript. It claims 6 of the 181 rules (the form and the statement hash of an envelope; the form, the commitment, the salted field
JavaScript. It claims 6 of the 213 rules (the form and the statement hash of an envelope; the form, the commitment, the salted field
commitments and the RFC 9162 inclusion of a dataset record) and passes all 62 vectors it claims. It cannot check an ML-DSA signature
or read a chain, says so in its capabilities, and the runner reports the rest as not covered: 405 vectors, among them every vector of
the trust chain, the audit log, the agents' ledger, the identity presentations and the device bundles. For those six verifiers the
suite has one implementation, ours.
or read a chain, says so in its capabilities, and the runner reports the rest as not covered: 491 vectors, among them every vector of
the trust chain, the audit log, the agents' ledger, the identity presentations, the device bundles and the SD-JWT presentations. For
those eight verifiers the suite has one implementation, ours (for SD-JWT, the identity component measured our verifier against
`@sd-jwt/core` and `@sd-jwt/sd-jwt-vc` outside this suite; those libraries are not implementations of this suite's contract).
## How the suite itself is checked
Measured on 2026-10-18 (UTC), when the SD-JWT verifier and the SD-JWT VC profile were enrolled (Node.js 24.14.1; the reference
verifier of the development repository; testnet 28001 read, nothing sent):
- `node proba-conformance.mjs --online`: 12 rows green, 0 red. The rules and the vectors are what the code derives now: 213 rules of
13 verifiers, 553 vectors (54 of the kind `sdjwt-presentation`, 32 of `sdjwt-vc-presentation`). Every rule has a vector that
expects it (213 of 213); every artifact kind has a valid vector (17); every invalid vector is its base with one operation (249) or
one declared producer change (155); the published verifiers pass 553/553; the independent implementation passes all 62 it claims
and the other 491 are reported not covered; 97,966 malformed inputs given to the module verifiers each got a verdict and none
threw (4,398 still accepted, at 193 distinct paths, 4 of them of `sdjwt-presentation` and 2 of `sdjwt-vc-presentation`: the
optional inputs of the verifier, such as the issuer it expects); 183 malformed envelope files given to the reference verifier each
got a verdict.
- `node proba-conformance.mjs --control-negativ --online`: 295 rows green, 0 red: 213 of 213 rules (each of the 23 rules of the
SD-JWT verifier and the 9 of the VC profile planted out in turn fails exactly the vectors that expect it), 76 of 76 conditions of
the device verifier, six controls of the instruments (an implementation that calls everything valid fails 512 of the 544 offline
vectors). While the enrolment was being made, the control found one thing and it was fixed before this measurement: with
`vct-expected` planted out, the VC verifier threw on the vector that names no expected type instead of refusing it by the next
rule, which the suite reported as a broken vector, not as a refusal.
Measured on 2026-10-14 (UTC), after the third review of the device verifier (Node.js 24.14.1; the AIP-23 reference verifier fetched
from aere.network/tools with its four sibling files and `npm install` done in an empty folder, as a stranger would; testnet 28001
read, nothing sent):
@ -267,11 +306,11 @@ On 2026-10-05, while the identity verifier was being enrolled, one more, fixed t
## What it is not, and what is not measured
- **Not a certification, not an audit, not a mark.** Passing says that an implementation agrees with the published verifiers on these
467 inputs. It does not say either of them is correct, and no third party has reviewed the verifiers, the vectors or this suite.
553 inputs. It does not say either of them is correct, and no third party has reviewed the verifiers, the vectors or this suite.
- **The vectors and the verifiers have the same authors.** The expected verdicts were written by the people who wrote the verifiers.
The second implementation is independent in code and language, not in authorship, and it covers 6 rules of 181; the other
175 rules, among them every rule of the trust chain, the audit log, the agents' ledger, the identity verifier and the device
verifier, are judged here by one implementation.
The second implementation is independent in code and language, not in authorship, and it covers 6 rules of 213; the other
207 rules, among them every rule of the trust chain, the audit log, the agents' ledger, the identity verifier, the device
verifier and the SD-JWT verifiers, are judged here by one implementation.
- **Finality is the chain's.** The level says that the post-quantum certificate of the covering anchor verified on the chain where the
artifact was notarized. Every notarized vector here is on chain 28001, a testnet; nothing in this suite ran on mainnet.
- **Five of the six finality refusals have no vector.** The reference verifier can refuse at its finality level in six places; the
@ -320,7 +359,12 @@ On 2026-10-05, while the identity verifier was being enrolled, one more, fixed t
not read them; the statement carries its own `kind`, which is under the hash. (This file used to quote 526 malformed envelopes,
a figure of 2026-10-03 from a run whose script was not kept; the row above replaces it.)
- **Not part of AIP-23.** The rule ids, the four levels and the verdict form are this suite's reading of the published verifiers;
AIP-23 defines the envelope. The device verifier is enrolled. Of the identity verifiers published beside these, the presentation verifier is enrolled; SD-JWT,
Travel Rule and compliance are not.
AIP-23 defines the envelope. The device verifier is enrolled. Of the identity verifiers published beside these, the presentation
verifier, the SD-JWT verifier and the SD-JWT VC profile are enrolled; Travel Rule and compliance are not.
- **The SD-JWT vectors say what two libraries agree on, on these inputs.** The tokens of `@sd-jwt/core` and `@sd-jwt/sd-jwt-vc` in
the SD-JWT vectors are the fixtures the identity component derived from those libraries' real output on 2026-10-18 (their versions
are in the vector sources); the expected verdicts are those of our verifiers on them, which the identity component measured against
the libraries' own verdicts in both directions. A verifier that resolves the issuer key from `iss` or `x5c`, fetches the status list
or the type metadata, or takes an untyped token by default, is judged here on inputs where all of that is already brought.
- **The Python implementation** writes numbers the way JavaScript does only for integers and plain decimals, and sorts keys by code
point (JavaScript's order for keys in the Basic Multilingual Plane).

View File

@ -1397,14 +1397,249 @@
}
],
"marked": "by a marker on every check"
},
"sdjwt": {
"artifacts": [
"sdjwt-presentation"
],
"rules": [
{
"id": "sdjwt.form",
"source": "form",
"level": "integrity",
"sites": 7,
"says": "the compact serialization (issuer-signed JWT ~ disclosures ~ key binding) and every JWS part can be read: three parts, canonical base64url, JSON objects, no empty disclosure; the verifier clock is a time"
},
{
"id": "sdjwt.alg",
"source": "alg",
"level": "authenticity",
"sites": 1,
"says": "the JWS algorithm is one the verifier accepts (ES256, EdDSA, ML-DSA-65); never none"
},
{
"id": "sdjwt.typ",
"source": "typ",
"level": "integrity",
"sites": 1,
"says": "the issuer-signed JWT carries the explicit type the verifier expects (any ...+sd-jwt by default; RFC 9901 Section 9.11) and the key binding JWT kb+jwt"
},
{
"id": "sdjwt.crit",
"source": "crit",
"level": "integrity",
"sites": 1,
"says": "no critical header parameter (crit) is present: none is understood"
},
{
"id": "sdjwt.key",
"source": "key",
"level": "authenticity",
"sites": 3,
"says": "the key given is a public EC, OKP or AKP JWK that can be read, and of the algorithm the JWS declares (no algorithm confusion)"
},
{
"id": "sdjwt.signature",
"source": "signature",
"level": "authenticity",
"sites": 1,
"says": "the JWS signature verifies with that key: the issuer-signed JWT with the issuer key the verifier chose, the key binding JWT with cnf.jwk"
},
{
"id": "sdjwt.issuer",
"source": "issuer",
"level": "authenticity",
"sites": 1,
"says": "iss is the issuer the verifier expects, when it names one"
},
{
"id": "sdjwt.sd-alg",
"source": "sd-alg",
"level": "integrity",
"sites": 2,
"says": "_sd_alg is sha-256 (or absent), and appears only at the top level of the payload (RFC 9901 Section 4.1.1)"
},
{
"id": "sdjwt.disclosure-form",
"source": "disclosure-form",
"level": "integrity",
"sites": 5,
"says": "every disclosure is base64url JSON of [salt, name, value] for an object property or [salt, value] for an array element, and _sd is a list of strings"
},
{
"id": "sdjwt.disclosure-twice",
"source": "disclosure-twice",
"level": "integrity",
"sites": 1,
"says": "no disclosure is given twice"
},
{
"id": "sdjwt.digest-twice",
"source": "digest-twice",
"level": "integrity",
"sites": 1,
"says": "no digest appears more than once in the issuer-signed payload, directly or through disclosures (Section 7.1 step 4)"
},
{
"id": "sdjwt.disclosure-name",
"source": "disclosure-name",
"level": "integrity",
"sites": 2,
"says": "no disclosure names _sd, ..., _sd_alg or __proto__, and no claim is named __proto__"
},
{
"id": "sdjwt.claim-conflict",
"source": "claim-conflict",
"level": "integrity",
"sites": 1,
"says": "a disclosed claim does not already exist at its level (Section 7.1 step 3.c.ii.3)"
},
{
"id": "sdjwt.unreferenced",
"source": "unreferenced",
"level": "integrity",
"sites": 1,
"says": "every disclosure given is referenced by a digest of the issuer-signed JWT (Section 7.1 step 5)"
},
{
"id": "sdjwt.time",
"source": "time",
"level": "integrity",
"sites": 5,
"says": "exp, nbf and iat are numbers; exp is present when required and has not passed on the verifier clock (no allowance); nbf and iat are not ahead of it by more than the clock skew"
},
{
"id": "sdjwt.kb-context",
"source": "kb-context",
"level": "integrity",
"sites": 1,
"says": "the verifier gave its audience and nonce when a key binding JWT is present or required (Section 7.3 step 5.f)"
},
{
"id": "sdjwt.kb-required",
"source": "kb-required",
"level": "integrity",
"sites": 1,
"says": "a key binding JWT is present when the verifier requires one"
},
{
"id": "sdjwt.kb-cnf",
"source": "kb-cnf",
"level": "integrity",
"sites": 1,
"says": "the issuer-signed JWT names the holder key (cnf.jwk) when a key binding JWT is given"
},
{
"id": "sdjwt.kb-claims",
"source": "kb-claims",
"level": "integrity",
"sites": 1,
"says": "the key binding JWT carries aud, nonce, iat and sd_hash"
},
{
"id": "sdjwt.kb-audience",
"source": "kb-audience",
"level": "integrity",
"sites": 1,
"says": "the key binding JWT was made for this verifier (aud)"
},
{
"id": "sdjwt.kb-nonce",
"source": "kb-nonce",
"level": "integrity",
"sites": 1,
"says": "the key binding JWT carries the nonce this verifier gave"
},
{
"id": "sdjwt.kb-freshness",
"source": "kb-freshness",
"level": "integrity",
"sites": 3,
"says": "the key binding JWT was made within the allowed age of the verifier clock, and its exp and nbf, if it carries them, hold"
},
{
"id": "sdjwt.kb-sd-hash",
"source": "kb-sd-hash",
"level": "integrity",
"sites": 1,
"says": "sd_hash is the hash of exactly what was presented (the issuer-signed JWT and the disclosures shown)"
}
],
"marked": "by a marker on every check"
},
"sdjwt-vc": {
"artifacts": [
"sdjwt-vc-presentation"
],
"rules": [
{
"id": "sdjwtvc.vct-expected",
"source": "vct-expected",
"level": "integrity",
"sites": 1,
"says": "the verifier names the credential type(s) it expects (expectedVct)"
},
{
"id": "sdjwtvc.vct",
"source": "vct",
"level": "integrity",
"sites": 1,
"says": "the payload carries vct, a non-empty string (draft-ietf-oauth-sd-jwt-vc Section 2.2.2.3)"
},
{
"id": "sdjwtvc.vct-mismatch",
"source": "vct-mismatch",
"level": "integrity",
"sites": 1,
"says": "vct is one of the types the verifier expects"
},
{
"id": "sdjwtvc.disclosed-protected",
"source": "disclosed-protected",
"level": "integrity",
"sites": 1,
"says": "none of iss, nbf, exp, cnf, vct, vct#integrity, aka_vcts, status was selectively disclosed (Section 2.2.2.3)"
},
{
"id": "sdjwtvc.form",
"source": "form",
"level": "integrity",
"sites": 3,
"says": "vct#integrity, if present, is a string; status is an object, and status.status_list carries a non-negative integer idx and a uri"
},
{
"id": "sdjwtvc.status-list",
"source": "status-list",
"level": "integrity",
"sites": 9,
"says": "the Status List Token handed to the verifier can be read for the uri the credential names: signed with the key given, typ statuslist+jwt, sub equal to that uri, iat present and not ahead of the clock, exp not passed, status_list with bits 1, 2, 4 or 8 and an lst that inflates"
},
{
"id": "sdjwtvc.status-index",
"source": "status-index",
"level": "integrity",
"sites": 1,
"says": "the index the credential names is inside the list"
},
{
"id": "sdjwtvc.status-revoked",
"source": "status-revoked",
"level": "integrity",
"sites": 1,
"says": "the status at that index is 0 (VALID); 1 INVALID, 2 SUSPENDED and any other value refuse"
},
{
"id": "sdjwtvc.status-unjudged",
"source": "status-unjudged",
"level": "integrity",
"sites": 1,
"says": "a status the credential names was judged, unless the verifier waived it (requireStatus false), in which case the verdict is PARTIAL"
}
],
"marked": "by a marker on every check"
}
},
"notEnrolled": [
{
"verifier": "identity: SD-JWT (RFC 9901)",
"refusalSites": 26,
"why": "its refusals carry texts, not rule ids (counted: the calls of its refusal helper); it is checked by its own probe, on the RFC 9901 vectors"
},
{
"verifier": "identity: Travel Rule",
"refusalSites": 20,

View File

@ -33,6 +33,8 @@ import { newAgentIdentity, openLedger, agentIdFromKey, sessionId, canonical as c
import { construieste as lantAI } from '../ai-trust/lant-de-incredere.mjs';
import * as ID from '../identity/identity.mjs';
import * as DV from '../device-identity/device.mjs';
import * as SJ from '../identity/sdjwt.mjs';
import * as SV from '../identity/sdjwt-vc.mjs';
import { hartaPublica, LEVELS } from './reguli.mjs';
const AICI = path.dirname(fileURLToPath(import.meta.url));
@ -40,6 +42,9 @@ const DIR = path.join(AICI, 'vectori'); const PROASPETE = path.join(AICI, 'surse
const DOV = { chitanta: new URL('../payments/dovezi/chitanta-28001-2026-10-02T1716Z.json', import.meta.url), piata: new URL('../market-settlement/dovezi/piata-28001-2026-10-02T1652Z.json', import.meta.url),
date: new URL('../verifiable-data/dovezi/notarizare-28001-2026-10-02T0820Z.json', import.meta.url),
lantAI: new URL('../ai-trust/dovezi/lant-28001-2026-10-02T0519Z.json', import.meta.url) };
// fixed inputs of the SD-JWT vectors (2026-10-18): the RFC 9901 vectors, and the tokens of @sd-jwt/core and @sd-jwt/sd-jwt-vc that the
// identity component's interop scripts derived from those libraries' real output (public test keys inside)
const FIX = { rfc: new URL('../identity/fixturi-rfc9901.json', import.meta.url), interop: new URL('../identity/interop/fixturi-interop-sdjwt.json', import.meta.url), interopVc: new URL('../identity/interop/fixturi-interop-sdjwt-vc.json', import.meta.url) };
const citeste = (u) => JSON.parse(fs.readFileSync(fileURLToPath(u), 'utf8'));
const clona = (x) => JSON.parse(JSON.stringify(x));
const sha256 = (b) => '0x' + crypto.createHash('sha256').update(b).digest('hex');
@ -400,6 +405,86 @@ const PROASPETE_IN_PLUS = {
hardwareRoot: (() => { const st = clona(X1.statement); st.hardwareRoot = { type: 'tpm2-quote', evidence: 'AAAA' }; return { statement: st, signature: DV.signAttestation(st, dev) }; })(),
envelopeOfAnother: DV.proofOfDevice(atest({ now: la(61) }), buildProof) } };
},
// an SD-JWT (RFC 9901) issued with AERE keys (an issuer, a holder, a stranger: three hybrid key pairs that exist only in this call) at a
// fixed time, presented to one verifier, and the forged siblings only a key holder can make (signed again with the issuer or holder key)
sdjwt: async () => {
const NOW = Math.floor(Date.now() / 1000) - 3600; const iso = (s) => new Date(s * 1000).toISOString();
const iss = ID.generateKeys(), hol = ID.generateKeys(), strain = ID.generateKeys();
const AUD = 'https://verifier.example', NONCE = 'n-' + crypto.randomBytes(8).toString('hex'), ISS = 'https://issuer.example';
const CL = { given_name: 'Ada', family_name: 'Example', age_over_18: true, nationalities: ['RO', 'DE'], address: { locality: 'Cluj', country: 'RO' } };
const emite = (o = {}) => SJ.issueSdJwt({ issuer: iss, holder: hol, claims: CL, disclosable: ['given_name', 'family_name', 'age_over_18'], arrayDisclosable: ['nationalities'], iss: ISS, iat: NOW, exp: NOW + 365 * 86400, decoys: 2, ...o });
const arata = (sd, reveal, o = {}) => SJ.presentSdJwt({ sdJwt: sd, reveal, holder: hol, audience: AUD, nonce: NONCE, iat: NOW, ...o });
const b64u = (x) => Buffer.from(x).toString('base64url'); const dec = (s) => JSON.parse(Buffer.from(s, 'base64url').toString('utf8'));
const jwtDin = (antet, corp, cheie = iss.privat.ed25519) => { const cap = b64u(JSON.stringify(antet)) + '.' + b64u(JSON.stringify(corp)); return cap + '.' + b64u(crypto.sign(null, Buffer.from(cap), cheie)); };
const sha = (d) => crypto.createHash('sha256').update(d).digest('base64url');
const E = emite(), M = emite({ alg: 'ML-DSA-65', holderAlg: 'ML-DSA-65' });
const direct = arata(E.sdJwt, ['age_over_18', { element: 'RO', in: 'nationalities' }]);
const corp = dec(E.sdJwt.split('~')[0].split('.')[1]);
const bazaDirect = direct.split('~').slice(0, -1).join('~') + '~';
const kbPeste = (baza, corpKb = {}, cheie = hol.privat.ed25519, antet = { alg: 'EdDSA', typ: 'kb+jwt' }) => baza + jwtDin(antet, { iat: NOW, aud: AUD, nonce: NONCE, sd_hash: sha(baza), ...corpKb }, cheie);
// a hand-made issuer-signed JWT (EdDSA, typ aere+sd-jwt, cnf = the holder key), no key binding
const jeton = (extra, antet = { alg: 'EdDSA', typ: SJ.TYP }) => jwtDin(antet, { iss: ISS, iat: NOW, exp: NOW + 365 * 86400, _sd_alg: 'sha-256', cnf: { jwk: SJ.publicJwk(hol) }, ...extra }) + '~';
const dz = (c) => { const d = b64u(JSON.stringify(c)); return { d, dg: sha(d) }; };
const d1 = dz(['salt-1', 'a', 1]), dSd = dz(['salt-2', '_sd', ['x']]), dRole = dz(['salt-3', 'role', 'admin']), dUnu = dz(['only-a-salt']);
return { now: iso(NOW + 60), later: iso(NOW + 3660), muchLater: iso(NOW + 400 * 86400), audience: AUD, nonce: NONCE, issuer: ISS,
issuerJwk: SJ.publicJwk(iss), issuerJwkMlDsa: SJ.publicJwk(iss, 'ML-DSA-65'), holderJwk: SJ.publicJwk(hol),
issued: E.sdJwt, direct, directMlDsa: arata(M.sdJwt, ['age_over_18'], { holderAlg: 'ML-DSA-65' }),
forged: {
kbStranger: arata(E.sdJwt, ['age_over_18'], { holder: strain }),
kbNoNonce: kbPeste(bazaDirect, { nonce: undefined }),
kbTypJwt: kbPeste(bazaDirect, {}, hol.privat.ed25519, { alg: 'EdDSA', typ: 'JWT' }),
kbExpired: kbPeste(bazaDirect, { exp: NOW - 100 }),
kbNoCnf: kbPeste(jwtDin({ alg: 'EdDSA', typ: SJ.TYP }, { iss: ISS, iat: NOW, exp: NOW + 1000, _sd_alg: 'sha-256' }) + '~'),
expired: arata(emite({ exp: NOW - 1 }).sdJwt, ['age_over_18']),
notYet: arata(emite({ nbf: NOW + 3600 }).sdJwt, ['age_over_18']),
digestTwice: jeton({ _sd: [d1.dg, d1.dg] }) + d1.d + '~',
nestedSdAlg: jeton({ meta: { _sd_alg: 'sha-256', note: 1 } }),
sdAlg384: jeton({ _sd_alg: 'sha-384' }),
disclosureNamedSd: jeton({ _sd: [dSd.dg] }) + dSd.d + '~',
claimConflict: jeton({ role: 'user', _sd: [dRole.dg] }) + dRole.d + '~',
protoClaim: jwtDin({ alg: 'EdDSA', typ: SJ.TYP }, JSON.parse('{"iss":"' + ISS + '","iat":' + NOW + ',"exp":' + (NOW + 1000) + ',"_sd_alg":"sha-256","__proto__":{"admin":true}}')) + '~',
crit: jwtDin({ alg: 'EdDSA', typ: SJ.TYP, crit: ['b64'], b64: false }, corp) + '~',
typJwt: jwtDin({ alg: 'EdDSA', typ: 'JWT' }, corp) + '~',
algConfusion: jwtDin({ alg: 'ES256', typ: SJ.TYP }, corp) + '~',
algNone: b64u(JSON.stringify({ alg: 'none', typ: SJ.TYP })) + '.' + b64u(JSON.stringify(corp)) + '.~',
noExp: jeton({ exp: undefined }),
disclosureOneElement: jeton({ _sd: [dUnu.dg] }) + dUnu.d + '~',
disclosureNotJson: jeton({ _sd: [sha('bm90LWpzb24')] }) + 'bm90LWpzb24~',
sdNotList: jeton({ _sd: 'x' }) } };
},
// an SD-JWT VC (a PID-like credential: vct urn:eudi:pid:1, a Token Status List reference) issued with AERE keys, its Status List Tokens
// (clean, revoked, suspended, 8 bits, for another uri, expired, by a stranger, typed JWT, without iat, too short, ML-DSA-65) and the
// hand-made siblings that break the profile (no vct, status disclosed, a malformed status, a vct#integrity that is not a string)
sdjwtvc: async () => {
const NOW = Math.floor(Date.now() / 1000) - 3600; const iso = (s) => new Date(s * 1000).toISOString();
const iss = ID.generateKeys(), hol = ID.generateKeys(), strain = ID.generateKeys();
const AUD = 'https://verifier.example', NONCE = 'n-' + crypto.randomBytes(8).toString('hex'), ISS = 'https://issuer.example', VCT = 'urn:eudi:pid:1', URI = 'https://issuer.example/status/pid/1', IDX = 5;
const CL = { given_name: 'Ada', family_name: 'Example', birthdate: '1990-01-01', age_over_18: true, nationalities: ['RO', 'DE'], address: { locality: 'Cluj', country: 'RO' }, issuing_authority: 'Example Authority', issuing_country: 'RO' };
const emite = (o = {}) => SV.issueSdJwtVc({ issuer: iss, holder: hol, vct: VCT, claims: CL, disclosable: ['given_name', 'family_name', 'birthdate', 'age_over_18', 'address'], arrayDisclosable: ['nationalities'], iss: ISS, iat: NOW, nbf: NOW, exp: NOW + 365 * 86400, status: { status_list: { idx: IDX, uri: URI } }, decoys: 2, ...o });
const arata = (sd, reveal, o = {}) => SV.presentSdJwtVc({ sdJwt: sd, reveal, holder: hol, audience: AUD, nonce: NONCE, iat: NOW, ...o });
const lista = (statuses, bits = 1, o = {}) => SV.issueStatusListJwt({ issuer: iss, uri: URI, statuses, bits, iat: NOW, exp: NOW + 3600, ...o });
const b64u = (x) => Buffer.from(x).toString('base64url');
const jwtDin = (antet, corp, cheie = iss.privat.ed25519) => { const cap = b64u(JSON.stringify(antet)) + '.' + b64u(JSON.stringify(corp)); return cap + '.' + b64u(crypto.sign(null, Buffer.from(cap), cheie)); };
const sha = (d) => crypto.createHash('sha256').update(d).digest('base64url');
const T0 = new Array(16).fill(0), REV = T0.map((_, i) => (i === IDX ? 1 : 0)), SUS = T0.map((_, i) => (i === IDX ? 2 : 0));
const E = emite(), M = emite({ alg: 'ML-DSA-65', holderAlg: 'ML-DSA-65' }), faraStare = SV.issueSdJwtVc({ issuer: iss, holder: hol, vct: VCT, claims: CL, disclosable: ['birthdate'], iss: ISS, iat: NOW, exp: NOW + 365 * 86400 });
const reveal = ['birthdate', 'age_over_18', { element: 'RO', in: 'nationalities' }];
const corpL = JSON.parse(Buffer.from(lista(T0).split('.')[1], 'base64url').toString('utf8'));
const jeton = (extra, dezv = []) => jwtDin({ alg: 'EdDSA', typ: 'dc+sd-jwt' }, { vct: VCT, iss: ISS, iat: NOW, exp: NOW + 365 * 86400, _sd_alg: 'sha-256', cnf: { jwk: SJ.publicJwk(hol) }, ...extra }) + '~' + dezv.map((d) => d + '~').join('');
const dStatus = b64u(JSON.stringify(['salt-s', 'status', { status_list: { idx: 1, uri: URI } }]));
return { now: iso(NOW + 60), audience: AUD, nonce: NONCE, issuer: ISS, vct: VCT, uri: URI, idx: IDX, issuerJwk: SJ.publicJwk(iss), issuerJwkMlDsa: SJ.publicJwk(iss, 'ML-DSA-65'),
direct: arata(E.sdJwt, reveal), directMlDsa: arata(M.sdJwt, reveal, { holderAlg: 'ML-DSA-65' }), noStatus: arata(faraStare.sdJwt, ['birthdate']),
lists: { clean: lista(T0), revoked: lista(REV), suspended: lista(SUS, 2), eightBits: lista(T0, 8), otherUri: lista(T0, 1, { uri: URI + '-other' }), expired: lista(T0, 1, { exp: NOW + 30 }),
stranger: SV.issueStatusListJwt({ issuer: strain, uri: URI, statuses: T0, iat: NOW }), short: SV.issueStatusListJwt({ issuer: iss, uri: URI, statuses: [0, 0, 0, 0], bits: 8, iat: NOW }),
typJwt: jwtDin({ alg: 'EdDSA', typ: 'JWT' }, corpL), noIat: jwtDin({ alg: 'EdDSA', typ: 'statuslist+jwt' }, (({ iat, ...r }) => r)(corpL)),
mlDsa: SV.issueStatusListJwt({ issuer: iss, alg: 'ML-DSA-65', uri: URI, statuses: T0, iat: NOW, exp: NOW + 3600 }) },
forged: {
noVct: arata(SJ.issueSdJwt({ issuer: iss, holder: hol, claims: { given_name: 'Ada' }, iss: ISS, iat: NOW, exp: NOW + 365 * 86400, typ: 'dc+sd-jwt' }).sdJwt, []),
statusDisclosed: jeton({ _sd: [sha(dStatus)] }, [dStatus]),
statusIdxNegative: jeton({ status: { status_list: { idx: -1, uri: URI } } }),
statusNotObject: jeton({ status: 'revoked' }),
vctIntegrityNumber: jeton({ 'vct#integrity': 7 }) } };
},
};
// ---------- fixed inputs of the AIP-23 kinds (the inputs of the published AIP-23 kind vectors) ----------
@ -998,6 +1083,134 @@ function construieste() {
mm('device-bundle/attestation-only.attestation-member-more', 'the attestation with a member more beside its statement and its signature', ba, ['bundle', 'attestation', 'note'], ['device.attestation-signature']);
mm('device-bundle/attestation-only.attestation-signature-member-more', 'the attestation with a member more in its signature object', ba, ['bundle', 'attestation', 'signature', 'note'], ['device.attestation-signature']);
tot('device-bundle/active-record-signature-member-more.partial', 'a status record with a member more in its signature object is not a signed record: the only "active" is not believed', bd, { op: 'add', path: ['statusRecords', 0, 'signature', 'note'], value: 'x' }, { ...AP, ...NI }); }
// (K) an SD-JWT presentation (IETF RFC 9901; 2026-10-18): the RFC's own example (ES256, the key of Appendix A.5), the tokens @sd-jwt/core
// issued and presented (the interop fixtures of the identity component, derived from that library's real output), and ours with AERE keys.
// The verifier stops at its first refusal: an integrity refusal leaves authenticity not reached, an authenticity refusal leaves integrity not reached
const curat = (o) => JSON.parse(JSON.stringify(o));
const schimbate = (a, b) => [...new Set([...Object.keys(a), ...Object.keys(b)])].filter((k) => JSON.stringify(a[k]) !== JSON.stringify(b[k])).sort().map((k) => [k]);
{ const SK = Object.keys(HARTA).filter((r) => r.startsWith('sdjwt.')); const A = 'sdjwt-presentation'; const RFC = citeste(FIX.rfc); const IO = citeste(FIX.interop); const X = P.sdjwt;
const AP = { authenticity: 'PASSED' }; const nivelul = (r) => (HARTA[r].level === 'authenticity' ? { integrity: 'NOT_MEASURED', authenticity: 'FAILED' } : { authenticity: 'NOT_MEASURED' });
const inv = (id, titlu, baza, op, r) => invalid(id, titlu, baza, op, [r], { levels: nivelul(r) });
const prod = (id, titlu, baza, sdJwt, r, nota, extra = {}) => { const b = V.find((x) => x.id === baza); if (!b) throw new Error('no base ' + baza); const input = curat({ ...clona(b.input), sdJwt, ...extra }); invalid(id, titlu, baza, null, [r], { levels: nivelul(r), producer: { note: nota, input, changed: schimbate(b.input, input) } }); };
const srcRfc = 'IETF RFC 9901 Section 5 and Appendix A.5 (code components, Revised BSD License), via fixturi-rfc9901.json of the identity component';
const kb = RFC.keyBindingPayload, laKb = new Date(kb.iat * 1000).toISOString(); const br = 'sdjwt-presentation/rfc9901.valid', bri = 'sdjwt-presentation/rfc9901-issued.valid';
valid(br, A, 'the presentation of RFC 9901 Section 5.2 (ES256, the issuer key of Appendix A.5) with its Key Binding JWT, judged at the time of that JWT with its audience and nonce', srcRfc, { sdJwt: RFC.presentation, issuerKey: RFC.issuerJwk, issuerAlg: 'ES256', audience: kb.aud, nonce: kb.nonce, now: laKb }, { exercises: SK, levels: AP });
valid(bri, A, 'the SD-JWT of RFC 9901 Section 5.1 as issued, every disclosure, no key binding (the verifier does not require one)', srcRfc, { sdJwt: RFC.sdJwt, issuerKey: RFC.issuerJwk, issuerAlg: 'ES256', now: laKb, requireKeyBinding: false }, { exercises: SK, levels: AP });
inv('sdjwt-presentation/rfc9901.kb-audience', 'the same presentation shown to another verifier', br, { op: 'set', path: ['audience'], value: 'https://other.example' }, 'sdjwt.kb-audience');
inv('sdjwt-presentation/rfc9901.kb-nonce', 'the verifier gave another nonce (a replay)', br, { op: 'set', path: ['nonce'], value: 'another-nonce' }, 'sdjwt.kb-nonce');
inv('sdjwt-presentation/rfc9901.kb-freshness', 'the verifier clock is an hour after the key binding JWT was made', br, { op: 'set', path: ['now'], value: new Date((kb.iat + 3600) * 1000).toISOString() }, 'sdjwt.kb-freshness');
inv('sdjwt-presentation/rfc9901.kb-context', 'the verifier gives no audience: a key binding cannot be judged, and the presentation is refused rather than taken on trust', br, { op: 'remove', path: ['audience'] }, 'sdjwt.kb-context');
inv('sdjwt-presentation/rfc9901.issuer', 'the verifier expects another issuer', br, { op: 'add', path: ['expectedIssuer'], value: 'https://other-issuer.example' }, 'sdjwt.issuer');
inv('sdjwt-presentation/rfc9901.key', 'the issuer key given is an RSA JWK, which this verifier does not take', br, { op: 'set', path: ['issuerKey'], value: { kty: 'RSA', n: 'AQAB', e: 'AQAB' } }, 'sdjwt.key');
inv('sdjwt-presentation/rfc9901.signature', 'the issuer key given is the holder key of the example (cnf.jwk): the issuer signature does not verify with it', br, { op: 'set', path: ['issuerKey'], value: RFC.processedPayload.cnf.jwk }, 'sdjwt.signature');
inv('sdjwt-presentation/rfc9901.typ', 'the verifier expects another explicit type', br, { op: 'add', path: ['expectedTyp'], value: 'other+sd-jwt' }, 'sdjwt.typ');
inv('sdjwt-presentation/rfc9901.form-clock', 'the verifier clock is not a time', br, { op: 'set', path: ['now'], value: 'yesterday' }, 'sdjwt.form');
inv('sdjwt-presentation/rfc9901.form', 'the token has no ~ at all (not an SD-JWT)', br, { op: 'set', path: ['sdJwt'], value: RFC.presentation.split('~')[0] }, 'sdjwt.form');
inv('sdjwt-presentation/rfc9901.kb-required', 'the SD-JWT as issued, no key binding, shown to a verifier that requires one', br, { op: 'set', path: ['sdJwt'], value: RFC.sdJwt }, 'sdjwt.kb-required');
const pr = RFC.presentation.split('~'); const kbR = pr.pop();
inv('sdjwt-presentation/rfc9901.kb-sd-hash', 'a disclosure taken out after the key binding JWT was signed', br, { op: 'set', path: ['sdJwt'], value: [...pr.slice(0, 2), ...pr.slice(3), kbR].join('~') }, 'sdjwt.kb-sd-hash');
const pi = RFC.sdJwt.split('~');
inv('sdjwt-presentation/rfc9901-issued.disclosure-twice', 'the same disclosure given twice', bri, { op: 'set', path: ['sdJwt'], value: [pi[0], pi[1], pi[1], ...pi.slice(2)].join('~') }, 'sdjwt.disclosure-twice');
inv('sdjwt-presentation/rfc9901-issued.form-empty', 'an empty disclosure between two ~', bri, { op: 'set', path: ['sdJwt'], value: [pi[0], '', ...pi.slice(1)].join('~') }, 'sdjwt.form');
{ const c = JSON.parse(Buffer.from(pi[1], 'base64url').toString('utf8')); c[2] = String(c[2]) + 'x'; const schimbat = Buffer.from(JSON.stringify(c)).toString('base64url');
inv('sdjwt-presentation/rfc9901-issued.unreferenced', 'the value of the first disclosure changed: its digest is in no _sd', bri, { op: 'set', path: ['sdJwt'], value: [pi[0], schimbat, ...pi.slice(2)].join('~') }, 'sdjwt.unreferenced'); }
// ours: AERE keys (EdDSA and ML-DSA-65), and the forged siblings only a key holder can make
const srcA = 'producers (sdjwt.mjs: issueSdJwt, presentSdJwt), three hybrid key pairs made and discarded at generation';
const bo = 'sdjwt-presentation/aere.valid', bom = 'sdjwt-presentation/aere-ml-dsa-65.valid', bi = 'sdjwt-presentation/aere-issued.valid';
const intrareA = (sdJwt, o = {}) => ({ sdJwt, issuerKey: X.issuerJwk, issuerAlg: 'EdDSA', audience: X.audience, nonce: X.nonce, now: X.now, expectedIssuer: X.issuer, ...o });
valid(bo, A, 'an SD-JWT issued with AERE keys (EdDSA): two of three disclosable claims and one list element shown, two decoy digests, a key binding JWT for this verifier', srcA, intrareA(X.direct), { exercises: SK, levels: AP });
valid(bom, A, 'the same credential, issuer and holder keys ML-DSA-65 (RFC 9964, JWK type AKP)', srcA, intrareA(X.directMlDsa, { issuerKey: X.issuerJwkMlDsa, issuerAlg: 'ML-DSA-65' }), { exercises: SK, levels: AP });
valid(bi, A, 'the same SD-JWT as issued (every disclosure, no key binding), judged by a verifier that does not require key binding', srcA, { sdJwt: X.issued, issuerKey: X.issuerJwk, issuerAlg: 'EdDSA', now: X.now, requireKeyBinding: false }, { exercises: SK, levels: AP });
const F = X.forged;
prod('sdjwt-presentation/aere.signature-kb', 'the key binding JWT is signed by another key than cnf.jwk', bo, F.kbStranger, 'sdjwt.signature', 'a stranger made the key binding JWT with its own key over the holder\'s SD-JWT');
prod('sdjwt-presentation/aere.kb-claims', 'the key binding JWT carries no nonce', bo, F.kbNoNonce, 'sdjwt.kb-claims', 'the holder signed a key binding JWT without the nonce claim');
prod('sdjwt-presentation/aere.typ-kb', 'the key binding JWT is typed JWT, not kb+jwt', bo, F.kbTypJwt, 'sdjwt.typ', 'the holder signed the key binding JWT with typ JWT');
prod('sdjwt-presentation/aere.kb-freshness-exp', 'the key binding JWT carries an exp that has passed', bo, F.kbExpired, 'sdjwt.kb-freshness', 'the holder signed a key binding JWT with exp in the past');
prod('sdjwt-presentation/aere.kb-cnf', 'the issuer-signed JWT names no holder key, and a key binding JWT is attached anyway', bo, F.kbNoCnf, 'sdjwt.kb-cnf', 'the issuer signed a JWT without cnf; a key binding JWT was attached to it');
prod('sdjwt-presentation/aere.time-expired', 'the credential expired a second before the verifier clock', bo, F.expired, 'sdjwt.time', 'the issuer issued the same claims with exp in the past, the holder presented them');
prod('sdjwt-presentation/aere.time-not-yet', 'the credential is not valid for another hour (nbf ahead of the clock by more than the skew)', bo, F.notYet, 'sdjwt.time', 'the issuer issued the same claims with nbf an hour ahead, the holder presented them');
prod('sdjwt-presentation/aere-issued.digest-twice', 'the issuer signed the same digest twice in _sd', bi, F.digestTwice, 'sdjwt.digest-twice', 'the issuer signed a payload whose _sd repeats a digest');
prod('sdjwt-presentation/aere-issued.sd-alg-nested', 'the issuer signed an _sd_alg below the top level (RFC 9901 Section 4.1.1 forbids it)', bi, F.nestedSdAlg, 'sdjwt.sd-alg', 'the issuer signed a payload with _sd_alg inside a nested object');
prod('sdjwt-presentation/aere-issued.sd-alg', 'the issuer signed _sd_alg sha-384, which this verifier does not understand', bi, F.sdAlg384, 'sdjwt.sd-alg', 'the issuer signed a payload with _sd_alg sha-384');
prod('sdjwt-presentation/aere-issued.disclosure-name', 'a disclosure named _sd, signed for by the issuer', bi, F.disclosureNamedSd, 'sdjwt.disclosure-name', 'the issuer put in _sd the digest of a disclosure named _sd');
prod('sdjwt-presentation/aere-issued.disclosure-name-proto', 'a plain claim named __proto__, signed by the issuer', bi, F.protoClaim, 'sdjwt.disclosure-name', 'the issuer signed a payload with a claim named __proto__');
prod('sdjwt-presentation/aere-issued.claim-conflict', 'a disclosure that would overwrite a claim the payload has in the clear', bi, F.claimConflict, 'sdjwt.claim-conflict', 'the issuer signed a plain claim role and the digest of a disclosure named role');
prod('sdjwt-presentation/aere-issued.crit', 'the issuer-signed JWT carries a crit header parameter', bi, F.crit, 'sdjwt.crit', 'the issuer signed the header with crit [b64] and b64 false');
prod('sdjwt-presentation/aere-issued.typ', 'the issuer-signed JWT is typed JWT, not an explicit SD-JWT type', bi, F.typJwt, 'sdjwt.typ', 'the issuer signed the header with typ JWT');
prod('sdjwt-presentation/aere-issued.key-confusion', 'the header says ES256 and the signature was made with the Ed25519 key (algorithm confusion)', bi, F.algConfusion, 'sdjwt.key', 'the issuer signed with its Ed25519 key under an ES256 header');
prod('sdjwt-presentation/aere-issued.alg-none', 'alg none, no signature', bi, F.algNone, 'sdjwt.alg', 'the payload re-encoded under an alg none header with an empty signature');
prod('sdjwt-presentation/aere-issued.time-no-exp', 'the issuer-signed JWT has no exp, and the verifier requires one', bi, F.noExp, 'sdjwt.time', 'the issuer signed a payload without exp');
prod('sdjwt-presentation/aere-issued.disclosure-form', 'a disclosure that is a one-element list', bi, F.disclosureOneElement, 'sdjwt.disclosure-form', 'the issuer signed the digest of a disclosure that is [salt] alone');
prod('sdjwt-presentation/aere-issued.disclosure-form-not-json', 'a disclosure that is base64url of text that is not JSON', bi, F.disclosureNotJson, 'sdjwt.disclosure-form', 'the issuer signed the digest of a disclosure whose bytes are not JSON');
prod('sdjwt-presentation/aere-issued.disclosure-form-sd', '_sd is a string, not a list of digests', bi, F.sdNotList, 'sdjwt.disclosure-form', 'the issuer signed a payload whose _sd is a string');
inv('sdjwt-presentation/aere-issued.time-years-later', 'the verifier clock is years later: the credential has expired', bi, { op: 'set', path: ['now'], value: X.muchLater }, 'sdjwt.time');
// @sd-jwt/core (openwallet-foundation-labs/identity-common-ts), from the interop fixtures: its tokens, with its public test keys
const srcIo = `@sd-jwt/core ${IO.biblioteci['@sd-jwt/core']} with jose ${IO.biblioteci.jose} (interop/fixturi-interop-sdjwt.json of the identity component, generated ${IO.generat.slice(0, 10)}; its test keys made and discarded at generation)`;
const laIo = new Date(IO.ceasVerificare * 1000).toISOString();
const intrareIo = (c) => ({ sdJwt: c.prezentare, issuerKey: c.issuerJwk, issuerAlg: c.alg, audience: IO.audience, nonce: IO.nonce, now: laIo, ...(c.optiuni || {}) });
const cazIo = (re) => { const c = IO.cazuri.find((x) => re.test(x.nume)); if (!c) throw new Error('the interop fixtures have no case ' + re); return c; };
const bioE = 'sdjwt-presentation/sd-jwt-core.valid';
for (const [alg, id, titlu] of [['EdDSA', bioE, 'an SD-JWT issued and presented by @sd-jwt/core (EdDSA): nested disclosures (address.locality), a list element, two decoys, a key binding JWT; the token carries no typ, so the verifier takes any (expectedTyp null)'], ['ES256', 'sdjwt-presentation/sd-jwt-core-es256.valid', 'the same from @sd-jwt/core with ES256 (P-256) keys'], ['ML-DSA-65', 'sdjwt-presentation/sd-jwt-core-ml-dsa-65.valid', 'the same from @sd-jwt/core with ML-DSA-65 keys (RFC 9964)']]) {
const c = cazIo(new RegExp('^' + alg + ': prezentare @sd-jwt/core cu dezvaluiri imbricate')); valid(id, A, titlu, srcIo, intrareIo(c), { exercises: SK, levels: AP }); }
{ const c = cazIo(/typ example\+sd-jwt/); valid('sdjwt-presentation/sd-jwt-core-typed.valid', A, 'an SD-JWT from @sd-jwt/core issued with typ example+sd-jwt, taken by the default type of the verifier', srcIo, intrareIo(c), { exercises: SK, levels: AP }); }
inv('sdjwt-presentation/sd-jwt-core.typ', 'the untyped token of @sd-jwt/core under the default type of the verifier (an explicit ...+sd-jwt is required)', bioE, { op: 'remove', path: ['expectedTyp'] }, 'sdjwt.typ');
const negIo = (id, titlu, re, r, nota) => { const c = cazIo(re); prod(id, titlu, bioE, c.prezentare, r, nota); };
negIo('sdjwt-presentation/sd-jwt-core.unreferenced', 'the value of a disclosure of @sd-jwt/core changed', /^NEGATIV: dezvaluirea age_over_18 cu valoarea schimbata/, 'sdjwt.unreferenced', 'a disclosure of the @sd-jwt/core token with its value changed (no key binding in that presentation)');
negIo('sdjwt-presentation/sd-jwt-core.kb-audience', 'presented by @sd-jwt/core for another audience', /^NEGATIV: KB pentru alt aud/, 'sdjwt.kb-audience', '@sd-jwt/core presented the token with a key binding JWT for https://other.example');
negIo('sdjwt-presentation/sd-jwt-core.alg', 'the @sd-jwt/core payload under alg none', /^NEGATIV: alg none/, 'sdjwt.alg', 'the issuer-signed payload of @sd-jwt/core re-encoded under alg none');
negIo('sdjwt-presentation/sd-jwt-core.digest-twice', 'the @sd-jwt/core payload with a digest repeated in _sd, signed again by its issuer key', /^NEGATIV: acelasi digest de doua ori/, 'sdjwt.digest-twice', 'the @sd-jwt/core issuer key signed its payload with the first digest of _sd repeated');
negIo('sdjwt-presentation/sd-jwt-core.signature-kb', 'presented by @sd-jwt/core with a key binding JWT signed by another key than cnf.jwk', /^NEGATIV: KB semnat de alta cheie/, 'sdjwt.signature', '@sd-jwt/core presented the token with a key binding JWT of another key');
negIo('sdjwt-presentation/sd-jwt-core.kb-sd-hash', 'a disclosure removed from the @sd-jwt/core presentation after key binding', /^NEGATIV: o dezvaluire scoasa/, 'sdjwt.kb-sd-hash', 'a disclosure taken out of the @sd-jwt/core presentation after its key binding JWT was signed');
{ const c = cazIo(/_sd_alg sha-384/); prod('sdjwt-presentation/sd-jwt-core.sd-alg', 'a token @sd-jwt/core issued with _sd_alg sha-384, which this verifier does not understand', bioE, c.prezentare, 'sdjwt.sd-alg', '@sd-jwt/core issued and presented the same claims with hashAlg sha-384 (another issuer key of its own)', { issuerKey: c.issuerJwk }); } }
// (L) an SD-JWT VC presentation (draft-ietf-oauth-sd-jwt-vc with the Token Status List; 2026-10-18): ours with AERE keys and its status
// lists, and the credentials and lists @sd-jwt/sd-jwt-vc and @owf/token-status-list produced (the interop fixtures). No vector here EXPECTS
// a rule of sdjwt: the profile imports sdjwt.mjs from its real file, so a planted copy of sdjwt is not reached through this artifact
{ const VK = Object.keys(HARTA).filter((r) => r.startsWith('sdjwt.') || r.startsWith('sdjwtvc.')); const A = 'sdjwt-vc-presentation'; const X = P.sdjwtvc; const IO = citeste(FIX.interopVc);
const AP = { authenticity: 'PASSED' }, NI = { integrity: 'NOT_MEASURED' }, OPR = { authenticity: 'NOT_MEASURED' };
const inv = (id, titlu, baza, op, r) => invalid(id, titlu, baza, op, [r], { levels: OPR });
const prod = (id, titlu, baza, sdJwt, r, nota, extra = {}) => { const b = V.find((x) => x.id === baza); if (!b) throw new Error('no base ' + baza); const input = curat({ ...clona(b.input), sdJwt, ...extra }); invalid(id, titlu, baza, null, [r], { levels: OPR, producer: { note: nota, input, changed: schimbate(b.input, input) } }); };
const srcA = 'producers (sdjwt-vc.mjs: issueSdJwtVc, presentSdJwtVc, issueStatusListJwt), three hybrid key pairs made and discarded at generation';
const intrare = (sdJwt, o = {}) => curat({ sdJwt, issuerKey: X.issuerJwk, issuerAlg: 'EdDSA', audience: X.audience, nonce: X.nonce, now: X.now, expectedIssuer: X.issuer, expectedVct: X.vct, statusListJwt: X.lists.clean, ...o });
const bv = 'sdjwt-vc-presentation/aere-pid.valid';
valid(bv, A, `an SD-JWT VC issued with AERE keys (EdDSA; vct ${X.vct}, typ dc+sd-jwt, a status_list reference), three claims shown, judged with the issuer's Status List Token (all VALID)`, srcA, intrare(X.direct), { exercises: VK, levels: AP });
valid('sdjwt-vc-presentation/aere-pid-ml-dsa-65.valid', A, 'the same credential and its status list, issuer and holder ML-DSA-65', srcA, intrare(X.directMlDsa, { issuerKey: X.issuerJwkMlDsa, issuerAlg: 'ML-DSA-65', statusListJwt: X.lists.mlDsa }), { exercises: VK, levels: AP });
valid('sdjwt-vc-presentation/aere-no-status.valid', A, 'a credential that names no status, judged without a list', srcA, intrare(X.noStatus, { statusListJwt: undefined }), { exercises: VK, levels: AP });
valid('sdjwt-vc-presentation/aere-pid-status-waived.partial', A, 'the same credential without its list, the verifier waiving the status (requireStatus false): nothing fails, the status it names was not judged, so it is not VALID', srcA, intrare(X.direct, { statusListJwt: undefined, requireStatus: false }), { exercises: VK, verdict: 'PARTIAL', levels: { ...AP, ...NI } });
{ const op = { op: 'set', path: ['statusListJwt'], value: X.lists.eightBits }; valid('sdjwt-vc-presentation/aere-pid-8-bits.valid', A, 'the same credential with a status list of 8 bits per entry (all VALID)', srcA, aplica(V.find((x) => x.id === bv).input, op), { exercises: VK, levels: AP, base: bv, mutation: op }); }
inv('sdjwt-vc-presentation/aere-pid.vct-expected', 'the verifier names no credential type it expects', bv, { op: 'remove', path: ['expectedVct'] }, 'sdjwtvc.vct-expected');
inv('sdjwt-vc-presentation/aere-pid.vct-mismatch', 'the verifier expects another credential type', bv, { op: 'set', path: ['expectedVct'], value: 'urn:eudi:pid:2' }, 'sdjwtvc.vct-mismatch');
inv('sdjwt-vc-presentation/aere-pid.status-revoked', 'the issuer\'s list has status 1 (INVALID) at the credential\'s index', bv, { op: 'set', path: ['statusListJwt'], value: X.lists.revoked }, 'sdjwtvc.status-revoked');
inv('sdjwt-vc-presentation/aere-pid.status-suspended', 'the issuer\'s list, 2 bits per entry, has status 2 (SUSPENDED) at the index', bv, { op: 'set', path: ['statusListJwt'], value: X.lists.suspended }, 'sdjwtvc.status-revoked');
inv('sdjwt-vc-presentation/aere-pid.status-list-other-uri', 'the list handed was published for another uri (sub)', bv, { op: 'set', path: ['statusListJwt'], value: X.lists.otherUri }, 'sdjwtvc.status-list');
inv('sdjwt-vc-presentation/aere-pid.status-list-expired', 'the list handed expired before the verifier clock', bv, { op: 'set', path: ['statusListJwt'], value: X.lists.expired }, 'sdjwtvc.status-list');
inv('sdjwt-vc-presentation/aere-pid.status-list-stranger', 'the list handed is signed by another key than the issuer\'s', bv, { op: 'set', path: ['statusListJwt'], value: X.lists.stranger }, 'sdjwtvc.status-list');
inv('sdjwt-vc-presentation/aere-pid.status-list-typ', 'the list handed is typed JWT, not statuslist+jwt', bv, { op: 'set', path: ['statusListJwt'], value: X.lists.typJwt }, 'sdjwtvc.status-list');
inv('sdjwt-vc-presentation/aere-pid.status-list-no-iat', 'the list handed has no iat', bv, { op: 'set', path: ['statusListJwt'], value: X.lists.noIat }, 'sdjwtvc.status-list');
inv('sdjwt-vc-presentation/aere-pid.status-index', 'the list handed is shorter than the index the credential names', bv, { op: 'set', path: ['statusListJwt'], value: X.lists.short }, 'sdjwtvc.status-index');
inv('sdjwt-vc-presentation/aere-pid.status-unjudged', 'no list handed, and the verifier did not waive the status', bv, { op: 'remove', path: ['statusListJwt'] }, 'sdjwtvc.status-unjudged');
const F = X.forged;
prod('sdjwt-vc-presentation/aere-pid.vct', 'a credential typed dc+sd-jwt with no vct at all', bv, F.noVct, 'sdjwtvc.vct', 'the issuer signed an SD-JWT typed dc+sd-jwt without vct; the holder presented it');
prod('sdjwt-vc-presentation/aere-pid.disclosed-protected', 'the status claim made selectively disclosable, and disclosed', bv, F.statusDisclosed, 'sdjwtvc.disclosed-protected', 'the issuer put status behind a disclosure (no key binding in this token)', { requireKeyBinding: false });
prod('sdjwt-vc-presentation/aere-pid.form-idx', 'a status reference with a negative index', bv, F.statusIdxNegative, 'sdjwtvc.form', 'the issuer signed status.status_list.idx -1 (no key binding in this token)', { requireKeyBinding: false });
prod('sdjwt-vc-presentation/aere-pid.form-status', 'a status claim that is a string', bv, F.statusNotObject, 'sdjwtvc.form', 'the issuer signed status "revoked" (no key binding in this token)', { requireKeyBinding: false });
prod('sdjwt-vc-presentation/aere-pid.form-integrity', 'a vct#integrity that is a number', bv, F.vctIntegrityNumber, 'sdjwtvc.form', 'the issuer signed vct#integrity 7 (no key binding in this token)', { requireKeyBinding: false });
// @sd-jwt/sd-jwt-vc and @owf/token-status-list, from the interop fixtures
const srcIo = `@sd-jwt/sd-jwt-vc ${IO.biblioteci['@sd-jwt/sd-jwt-vc']} and @owf/token-status-list ${IO.biblioteci['@owf/token-status-list']} with jose ${IO.biblioteci.jose} (interop/fixturi-interop-sdjwt-vc.json of the identity component, generated ${IO.generat.slice(0, 10)}; their test keys made and discarded at generation)`;
const laIo = new Date(IO.ceasVerificare * 1000).toISOString();
const intrareIo = (c) => curat({ sdJwt: c.prezentare, issuerKey: c.issuerJwk, issuerAlg: c.alg, audience: IO.audience, nonce: IO.nonce, now: laIo, expectedVct: c.expectedVct, statusListJwt: c.statusListJwt, ...(c.optiuni || {}) });
const cazIo = (re) => { const c = IO.cazuri.find((x) => re.test(x.nume)); if (!c) throw new Error('the VC interop fixtures have no case ' + re); return c; };
const bvE = 'sdjwt-vc-presentation/sd-jwt-vc.valid';
for (const [alg, id, titlu] of [['EdDSA', bvE, 'an SD-JWT VC issued and presented by @sd-jwt/sd-jwt-vc (EdDSA; typ dc+sd-jwt, vct urn:eudi:pid:1, a status_list reference) with the Status List Token of @owf/token-status-list (all VALID)'], ['ES256', 'sdjwt-vc-presentation/sd-jwt-vc-es256.valid', 'the same with ES256 keys'], ['ML-DSA-65', 'sdjwt-vc-presentation/sd-jwt-vc-ml-dsa-65.valid', 'the same with ML-DSA-65 keys']]) {
const c = cazIo(new RegExp('^' + alg + ': SD-JWT VC @sd-jwt/sd-jwt-vc')); valid(id, A, titlu, srcIo, intrareIo(c), { exercises: VK, levels: AP }); }
{ const c = cazIo(/^lista LOR pe 8 biti/); valid('sdjwt-vc-presentation/sd-jwt-vc-8-bits.valid', A, 'the same credential with the 8-bit list of @owf/token-status-list', srcIo, intrareIo(c), { exercises: VK, levels: AP }); }
{ const c = cazIo(/^fara lista, la noi cu requireStatus:false/); valid('sdjwt-vc-presentation/sd-jwt-vc-status-waived.partial', A, 'the @sd-jwt/sd-jwt-vc credential without its list, the status waived: not judged, so not VALID', srcIo, intrareIo(c), { exercises: VK, verdict: 'PARTIAL', levels: { ...AP, ...NI } }); }
const negIo = (id, titlu, re, r, nota) => { const c = cazIo(re); const b = V.find((x) => x.id === bvE); const input = intrareIo(c); invalid(id, titlu, bvE, null, [r], { levels: OPR, producer: { note: nota, input, changed: schimbate(b.input, input) } }); };
negIo('sdjwt-vc-presentation/sd-jwt-vc.status-revoked', 'the list of @owf/token-status-list with status 1 at the index', /^NEGATIV: lista LOR cu indexul 5 = 1/, 'sdjwtvc.status-revoked', '@owf/token-status-list wrote the list with INVALID at the credential\'s index');
negIo('sdjwt-vc-presentation/sd-jwt-vc.status-suspended', 'the 2-bit list of @owf/token-status-list with status 2 at the index', /^NEGATIV: lista LOR pe 2 biti/, 'sdjwtvc.status-revoked', '@owf/token-status-list wrote a 2-bit list with SUSPENDED at the credential\'s index');
negIo('sdjwt-vc-presentation/sd-jwt-vc.status-list-other-uri', 'the list of @owf/token-status-list published for another uri', /^NEGATIV: lista LOR pentru ALT uri/, 'sdjwtvc.status-list', '@owf/token-status-list wrote the list with another sub');
negIo('sdjwt-vc-presentation/sd-jwt-vc.status-list-expired', 'the list of @owf/token-status-list, expired', /^NEGATIV: lista LOR expirata/, 'sdjwtvc.status-list', '@owf/token-status-list wrote the list with exp before the verifier clock');
negIo('sdjwt-vc-presentation/sd-jwt-vc.vct-mismatch', 'the verifier expects another credential type than the @sd-jwt/sd-jwt-vc credential carries', /^NEGATIV: verificatorul asteapta alt vct/, 'sdjwtvc.vct-mismatch', 'the same credential and list, the verifier expecting urn:eudi:pid:2');
negIo('sdjwt-vc-presentation/sd-jwt-vc.status-unjudged', 'the @sd-jwt/sd-jwt-vc credential without its list, the status not waived', /^NEGATIV: fara lista, la noi implicit/, 'sdjwtvc.status-unjudged', 'the same credential, no list handed'); }
// (E) a dataset: a record, a range answer, a consistency proof, an availability sample
const DS = P.dataset; const REC = ['dataset.form', 'dataset.commitment', 'dataset.field', 'dataset.inclusion']; const src = 'producer (verifiable-data), random salts, generated ' + P.at;
valid('dataset-record/r5.valid', 'dataset-record', 'one record against the commitment of version 2, two fields disclosed', src, { record: DS.record, commitment: DS.newer }, { exercises: REC });

View File

@ -172,6 +172,26 @@ async function judeca(artifact, input, online) {
else if (st.witness === 'UNMEASURED') ambele(online ? 'unmeasurable' : 'claim-not-checked', online ? String(det.witness.detail).slice(0, 200) : 'the bundle brings notarized heads; this run was offline, they were not read');
else if (st.form === 'PASSED') ambele('unwitnessed', 'no witness: every time in this bundle is the statement of whoever holds the keys');
if (claim) nemasurat(acc, 'anchoring', 'claim-not-checked', 'an envelope of the bundle claims a notarization; this run was offline, the claim was not checked');
} else if (artifact === 'sdjwt-presentation' || artifact === 'sdjwt-vc-presentation') {
// an SD-JWT (RFC 9901) or an SD-JWT VC presentation, judged by sdjwt.mjs / sdjwt-vc.mjs with what THIS verifier brings: the issuer
// key it chose (a public JWK), its clock (required), its audience and nonce, the issuer and the type it expects and, for a VC, the
// credential type it expects and the Status List Token it fetched. These verifiers stop at their first refusal and name its rule;
// a VC refusal may name a rule of sdjwt (the profile verifies the SD-JWT first)
const vc = artifact === 'sdjwt-vc-presentation';
const M = await incarca(vc ? 'sdjwtvc' : 'sdjwt'); const RB = VERIFICATOARE.sdjwt.reguli, RV = VERIFICATOARE['sdjwt-vc'].reguli;
if (typeof input.now !== 'string') throw new Error('an SD-JWT presentation is judged on the verifier\'s clock: input.now (an RFC 3339 time) is required');
const o = { now: input.now }; for (const k of ['issuerKey', 'issuerAlg', 'audience', 'nonce', 'expectedIssuer', 'requireKeyBinding', 'requireExp', 'maxAgeS', 'expectedTyp', 'expectedVct', 'statusListJwt', 'statusListKey', 'statusListAlg', 'requireStatus']) if (input[k] !== undefined) o[k] = input[k];
const r = vc ? M.verifySdJwtVc(input.sdJwt, o) : M.verifySdJwt(input.sdJwt, o);
if (r.valid !== (r.rule == null)) throw new Error('the SD-JWT verifier refused without naming a rule');
if (!r.valid) {
const m = (vc && RV[r.rule]) || RB[r.rule]; if (!m) throw new Error('the SD-JWT verifier named a rule this suite does not map: ' + r.rule);
pica(acc, m[1], m[0], r.reason); nemasurat(acc, m[1] === 'integrity' ? 'authenticity' : 'integrity', 'not-reached', 'the verifier stopped at its first refusal');
} else {
trece(acc, 'integrity', `no rule of the SD-JWT${vc ? ' VC' : ''} verifier refused: ${r.disclosed.length} disclosure(s) bound to the issuer-signed JWT${vc ? ', vct ' + r.vct : ''}`);
trece(acc, 'authenticity', `the issuer-signed JWT verifies (${r.alg}) with the issuer key the verifier gave` + (r.keyBinding ? `; the key binding JWT (${r.keyBinding.alg}) verifies with cnf.jwk for this audience and nonce` : '; no key binding (the verifier did not require one)'));
if (vc && r.status && r.status.present && !r.status.judged) nemasurat(acc, 'integrity', 'claim-not-checked', `the credential names a status (${r.status.mechanism}${r.status.uri ? ' at ' + r.status.uri : ''}) and no list was judged: the verifier waived it`);
}
for (const l of ['anchoring', 'finality']) nemasurat(acc, l, 'not-judged', 'an SD-JWT is anchored by notarizing an AIP-23 envelope of it, judged as the artifact `envelope`');
} else if (artifact.startsWith('dataset-')) {
const M = await incarca('baza'); let r;
if (artifact === 'dataset-record') r = M.verificaInregistrare(input.record, input.commitment);

View File

@ -185,7 +185,9 @@ const ramase = () => [...Object.values(MODULE).map((m) => path.dirname(fileURLTo
* @returns {{ cazuri: number, aruncate: string[], acceptate: string[] }} acceptate = the paths (without array positions) whose damage was accepted
*/
async function malformate() {
const R = await incarca('risc'), C = await incarca('chitanta'), P = await incarca('piata'), B = await incarca('baza'), SC = await incarca('sidecar'), AR = await incarca('arbore'), L = await incarca('ledger'), ID = await incarca('identity'), DV = await incarca('device'); const clona = (x) => JSON.parse(JSON.stringify(x));
const R = await incarca('risc'), C = await incarca('chitanta'), P = await incarca('piata'), B = await incarca('baza'), SC = await incarca('sidecar'), AR = await incarca('arbore'), L = await incarca('ledger'), ID = await incarca('identity'), DV = await incarca('device'), SJ = await incarca('sdjwt'), SV = await incarca('sdjwtvc'); const clona = (x) => JSON.parse(JSON.stringify(x));
// the SD-JWT verifiers (2026-10-18), called the way the adapter calls them; a VC whose status was waived and not judged is PARTIAL, not accepted
const optSd = (i) => { const o = { now: i.now }; for (const k of ['issuerKey', 'issuerAlg', 'audience', 'nonce', 'expectedIssuer', 'requireKeyBinding', 'requireExp', 'maxAgeS', 'expectedTyp', 'expectedVct', 'statusListJwt', 'statusListKey', 'statusListAlg', 'requireStatus']) if (i[k] !== undefined) o[k] = i[k]; return o; };
const J = { 'payment-risk': (i) => R.judeca(i.policy, i.inputs).decision === 'ALLOW', 'payment-receipt': (i) => C.verificaChitanta(i.receipt, { policy: i.policy, inputs: i.inputs, tx: i.tx, receipt: i.txReceipt }).verdict === 'VALID', 'market-timeline': (i) => P.judeca(i).verdict === 'VALID',
'dataset-record': (i) => B.verificaInregistrare(i.record, i.commitment).ok, 'dataset-answer': (i) => B.verificaRaspuns(i.answer, i.commitment).verdict === 'VALID', 'dataset-consistency': (i) => B.verificaConsistentaVersiuni(i.proof, i.older, i.newer).ok,
// the verifiers enrolled after the first four (2026-10-05), called the way the adapter calls them; ai-trust is not here: each case would run the reference verifier several times
@ -196,7 +198,9 @@ async function malformate() {
// identity (2026-10-05): the presentation and everything handed with it; the verifier's own configuration is left out below
'identity-presentation': (i) => { const o = { now: i.now }; for (const k of ['audience', 'nonce', 'trustedIssuers', 'statusLists', 'revocations', 'maxAgeS']) if (i[k] !== undefined) o[k] = i[k]; const r = ID.verifyPresentation(i.presentation, o); return r.valid && !r.unjudged.some((c) => NEJUDECATE_IDENTITY[c]); }, // accepted = what the suite would call VALID, not PARTIAL
// a device bundle (2026-10-05) and everything handed with it; the verifier's own configuration (its clock, the manufacturers it trusts, the lists themselves) is left out below
'device-bundle': (i) => { const o = { now: i.now }; for (const k of ['nonce', 'audience', 'trustedManufacturers', 'statusLists', 'firmwarePolicies', 'statusRecords', 'softwareAttestation', 'anchors', 'maxAgeS']) if (i[k] !== undefined) o[k] = i[k]; return DV.verifyDevice(i.bundle, o).verdict === 'VALID'; } };
'device-bundle': (i) => { const o = { now: i.now }; for (const k of ['nonce', 'audience', 'trustedManufacturers', 'statusLists', 'firmwarePolicies', 'statusRecords', 'softwareAttestation', 'anchors', 'maxAgeS']) if (i[k] !== undefined) o[k] = i[k]; return DV.verifyDevice(i.bundle, o).verdict === 'VALID'; },
'sdjwt-presentation': (i) => SJ.verifySdJwt(i.sdJwt, optSd(i)).valid,
'sdjwt-vc-presentation': (i) => { const r = SV.verifySdJwtVc(i.sdJwt, optSd(i)); return r.valid && !(r.status && r.status.present && !r.status.judged); } };
const cai = (x, p = []) => (x !== null && typeof x === 'object' ? [p, ...Object.keys(x).flatMap((k) => cai(x[k], [...p, Array.isArray(x) ? Number(k) : k]))] : [p]).filter((q) => q.length);
const VAL = [null, 'x', 7, [], {}]; let cazuri = 0; const aruncate = [], acceptate = [], sarite = [];
// a vector whose input is larger than MARE characters is not damaged path by path: thousands of paths, each judged over the whole input

View File

@ -26,6 +26,10 @@ export const MODULE = {
ledger: { url: new URL('../agents/agent-ledger.mjs', import.meta.url), env: 'AERE_CONF_MODUL_LEDGER' },
identity: { url: new URL('../identity/identity.mjs', import.meta.url), env: 'AERE_CONF_MODUL_IDENTITY' },
device: { url: new URL('../device-identity/device.mjs', import.meta.url), env: 'AERE_CONF_MODUL_DEVICE' },
// 2026-10-18 (B10): SD-JWT (RFC 9901) and its SD-JWT VC profile. The profile imports sdjwt.mjs from its real file: a planted copy of
// sdjwt.mjs is reached only by the sdjwt-presentation artifact, so no sdjwt-vc vector expects a rule of sdjwt (it may exercise them)
sdjwt: { url: new URL('../identity/sdjwt.mjs', import.meta.url), env: 'AERE_CONF_MODUL_SDJWT' },
sdjwtvc: { url: new URL('../identity/sdjwt-vc.mjs', import.meta.url), env: 'AERE_CONF_MODUL_SDJWTVC' },
};
export const caleModul = (k) => process.env[MODULE[k].env] || fileURLToPath(MODULE[k].url);
export const incarca = (k) => import(pathToFileURL(caleModul(k)).href);
@ -241,6 +245,45 @@ export const VERIFICATOARE = {
'witness-envelope': ['device.witness-envelope', I, 'the AIP-23 envelope given is the envelope of a device attestation, hashes to its statementHash and commits to this device and this attestation'],
'witness-time': ['device.witness-time', I, 'the attestation is not dated after the moment the verifier read its envelope on the chain (of several readings, the earliest)'],
unreadable: ['device.unreadable', I, 'every field a check reads can be read (a time is an RFC 3339 UTC time, a hash input is JSON)'] } },
// an SD-JWT presentation (IETF RFC 9901; enrolled 2026-10-18), judged with what the verifier brings: the issuer key it chose (a public
// JWK; never one taken from the token), its clock, its audience and nonce, the issuer and the type it expects. The verifier stops at its
// first refusal and names it; an integrity refusal leaves authenticity not reached, an authenticity refusal leaves integrity not reached
sdjwt: { artifacts: ['sdjwt-presentation'], sursa: 'sdjwt', reguli: {
form: ['sdjwt.form', I, 'the compact serialization (issuer-signed JWT ~ disclosures ~ key binding) and every JWS part can be read: three parts, canonical base64url, JSON objects, no empty disclosure; the verifier clock is a time'],
alg: ['sdjwt.alg', AU, 'the JWS algorithm is one the verifier accepts (ES256, EdDSA, ML-DSA-65); never none'],
typ: ['sdjwt.typ', I, 'the issuer-signed JWT carries the explicit type the verifier expects (any ...+sd-jwt by default; RFC 9901 Section 9.11) and the key binding JWT kb+jwt'],
crit: ['sdjwt.crit', I, 'no critical header parameter (crit) is present: none is understood'],
key: ['sdjwt.key', AU, 'the key given is a public EC, OKP or AKP JWK that can be read, and of the algorithm the JWS declares (no algorithm confusion)'],
signature: ['sdjwt.signature', AU, 'the JWS signature verifies with that key: the issuer-signed JWT with the issuer key the verifier chose, the key binding JWT with cnf.jwk'],
issuer: ['sdjwt.issuer', AU, 'iss is the issuer the verifier expects, when it names one'],
'sd-alg': ['sdjwt.sd-alg', I, '_sd_alg is sha-256 (or absent), and appears only at the top level of the payload (RFC 9901 Section 4.1.1)'],
'disclosure-form': ['sdjwt.disclosure-form', I, 'every disclosure is base64url JSON of [salt, name, value] for an object property or [salt, value] for an array element, and _sd is a list of strings'],
'disclosure-twice': ['sdjwt.disclosure-twice', I, 'no disclosure is given twice'],
'digest-twice': ['sdjwt.digest-twice', I, 'no digest appears more than once in the issuer-signed payload, directly or through disclosures (Section 7.1 step 4)'],
'disclosure-name': ['sdjwt.disclosure-name', I, 'no disclosure names _sd, ..., _sd_alg or __proto__, and no claim is named __proto__'],
'claim-conflict': ['sdjwt.claim-conflict', I, 'a disclosed claim does not already exist at its level (Section 7.1 step 3.c.ii.3)'],
unreferenced: ['sdjwt.unreferenced', I, 'every disclosure given is referenced by a digest of the issuer-signed JWT (Section 7.1 step 5)'],
time: ['sdjwt.time', I, 'exp, nbf and iat are numbers; exp is present when required and has not passed on the verifier clock (no allowance); nbf and iat are not ahead of it by more than the clock skew'],
'kb-context': ['sdjwt.kb-context', I, 'the verifier gave its audience and nonce when a key binding JWT is present or required (Section 7.3 step 5.f)'],
'kb-required': ['sdjwt.kb-required', I, 'a key binding JWT is present when the verifier requires one'],
'kb-cnf': ['sdjwt.kb-cnf', I, 'the issuer-signed JWT names the holder key (cnf.jwk) when a key binding JWT is given'],
'kb-claims': ['sdjwt.kb-claims', I, 'the key binding JWT carries aud, nonce, iat and sd_hash'],
'kb-audience': ['sdjwt.kb-audience', I, 'the key binding JWT was made for this verifier (aud)'],
'kb-nonce': ['sdjwt.kb-nonce', I, 'the key binding JWT carries the nonce this verifier gave'],
'kb-freshness': ['sdjwt.kb-freshness', I, 'the key binding JWT was made within the allowed age of the verifier clock, and its exp and nbf, if it carries them, hold'],
'kb-sd-hash': ['sdjwt.kb-sd-hash', I, 'sd_hash is the hash of exactly what was presented (the issuer-signed JWT and the disclosures shown)'] } },
// an SD-JWT VC presentation (draft-ietf-oauth-sd-jwt-vc, with the Token Status List; enrolled 2026-10-18): the rules of the profile on
// top of sdjwt; the verifier also brings the credential type it expects and the Status List Token it fetched
'sdjwt-vc': { artifacts: ['sdjwt-vc-presentation'], sursa: 'sdjwtvc', reguli: {
'vct-expected': ['sdjwtvc.vct-expected', I, 'the verifier names the credential type(s) it expects (expectedVct)'],
vct: ['sdjwtvc.vct', I, 'the payload carries vct, a non-empty string (draft-ietf-oauth-sd-jwt-vc Section 2.2.2.3)'],
'vct-mismatch': ['sdjwtvc.vct-mismatch', I, 'vct is one of the types the verifier expects'],
'disclosed-protected': ['sdjwtvc.disclosed-protected', I, 'none of iss, nbf, exp, cnf, vct, vct#integrity, aka_vcts, status was selectively disclosed (Section 2.2.2.3)'],
form: ['sdjwtvc.form', I, 'vct#integrity, if present, is a string; status is an object, and status.status_list carries a non-negative integer idx and a uri'],
'status-list': ['sdjwtvc.status-list', I, 'the Status List Token handed to the verifier can be read for the uri the credential names: signed with the key given, typ statuslist+jwt, sub equal to that uri, iat present and not ahead of the clock, exp not passed, status_list with bits 1, 2, 4 or 8 and an lst that inflates'],
'status-index': ['sdjwtvc.status-index', I, 'the index the credential names is inside the list'],
'status-revoked': ['sdjwtvc.status-revoked', I, 'the status at that index is 0 (VALID); 1 INVALID, 2 SUSPENDED and any other value refuse'],
'status-unjudged': ['sdjwtvc.status-unjudged', I, 'a status the credential names was judged, unless the verifier waived it (requireStatus false), in which case the verdict is PARTIAL'] } },
};
/**
* The FAILED sites of verify-proof's `finality` level, classified. `fragment` must appear on exactly one such source line; `re`
@ -284,7 +327,6 @@ export const NEJUDECATE_DEVICE = { 'manufacture-missing': ['integrity', 'not-sup
'hardware-root': ['authenticity', 'unmeasurable'], 'witness-unread': ['anchoring', 'claim-not-checked'] };
/** Verifiers published beside these that the suite does NOT enrol yet, with the pattern that counts their refusal sites. */
export const NEINROLATE = [
{ name: 'identity: SD-JWT (RFC 9901)', files: [new URL('../identity/sdjwt.mjs', import.meta.url)], re: /\brefuz\(/g, why: 'its refusals carry texts, not rule ids (counted: the calls of its refusal helper); it is checked by its own probe, on the RFC 9901 vectors' },
{ name: 'identity: Travel Rule', files: [new URL('../identity/travel-rule.mjs', import.meta.url)], re: /motive\.push\(/g, why: 'its refusals are reasons in a list, not rule ids (counted: the places that add one); it takes the presentation verdict from the enrolled verifier' },
{ name: 'identity: compliance', files: [new URL('../identity/conformitate.mjs', import.meta.url)], re: /motive\.push\(/g, why: 'its refusals are reasons in a list, not rule ids (counted: the places that add one); it takes the presentation verdict from the enrolled verifier' },
];

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,7 @@
{
"v": 1,
"kind": "aere-conformance-vector-index",
"count": 467,
"count": 553,
"artifacts": {
"envelope": 64,
"payment-risk": 11,
@ -14,12 +14,14 @@
"agent-ledger": 18,
"identity-presentation": 65,
"device-bundle": 194,
"sdjwt-presentation": 54,
"sdjwt-vc-presentation": 32,
"dataset-record": 6,
"dataset-answer": 11,
"dataset-consistency": 3,
"dataset-sample": 2
},
"offline": 458,
"offline": 544,
"online": 9,
"rules": {
"agents.anchor": [
@ -731,6 +733,137 @@
],
"risk.window": [
"payment-risk/company-p1.window"
],
"sdjwt.alg": [
"sdjwt-presentation/aere-issued.alg-none",
"sdjwt-presentation/sd-jwt-core.alg"
],
"sdjwt.claim-conflict": [
"sdjwt-presentation/aere-issued.claim-conflict"
],
"sdjwt.crit": [
"sdjwt-presentation/aere-issued.crit"
],
"sdjwt.digest-twice": [
"sdjwt-presentation/aere-issued.digest-twice",
"sdjwt-presentation/sd-jwt-core.digest-twice"
],
"sdjwt.disclosure-form": [
"sdjwt-presentation/aere-issued.disclosure-form",
"sdjwt-presentation/aere-issued.disclosure-form-not-json",
"sdjwt-presentation/aere-issued.disclosure-form-sd"
],
"sdjwt.disclosure-name": [
"sdjwt-presentation/aere-issued.disclosure-name",
"sdjwt-presentation/aere-issued.disclosure-name-proto"
],
"sdjwt.disclosure-twice": [
"sdjwt-presentation/rfc9901-issued.disclosure-twice"
],
"sdjwt.form": [
"sdjwt-presentation/rfc9901.form-clock",
"sdjwt-presentation/rfc9901.form",
"sdjwt-presentation/rfc9901-issued.form-empty"
],
"sdjwt.issuer": [
"sdjwt-presentation/rfc9901.issuer"
],
"sdjwt.kb-audience": [
"sdjwt-presentation/rfc9901.kb-audience",
"sdjwt-presentation/sd-jwt-core.kb-audience"
],
"sdjwt.kb-claims": [
"sdjwt-presentation/aere.kb-claims"
],
"sdjwt.kb-cnf": [
"sdjwt-presentation/aere.kb-cnf"
],
"sdjwt.kb-context": [
"sdjwt-presentation/rfc9901.kb-context"
],
"sdjwt.kb-freshness": [
"sdjwt-presentation/rfc9901.kb-freshness",
"sdjwt-presentation/aere.kb-freshness-exp"
],
"sdjwt.kb-nonce": [
"sdjwt-presentation/rfc9901.kb-nonce"
],
"sdjwt.kb-required": [
"sdjwt-presentation/rfc9901.kb-required"
],
"sdjwt.kb-sd-hash": [
"sdjwt-presentation/rfc9901.kb-sd-hash",
"sdjwt-presentation/sd-jwt-core.kb-sd-hash"
],
"sdjwt.key": [
"sdjwt-presentation/rfc9901.key",
"sdjwt-presentation/aere-issued.key-confusion"
],
"sdjwt.sd-alg": [
"sdjwt-presentation/aere-issued.sd-alg-nested",
"sdjwt-presentation/aere-issued.sd-alg",
"sdjwt-presentation/sd-jwt-core.sd-alg"
],
"sdjwt.signature": [
"sdjwt-presentation/rfc9901.signature",
"sdjwt-presentation/aere.signature-kb",
"sdjwt-presentation/sd-jwt-core.signature-kb"
],
"sdjwt.time": [
"sdjwt-presentation/aere.time-expired",
"sdjwt-presentation/aere.time-not-yet",
"sdjwt-presentation/aere-issued.time-no-exp",
"sdjwt-presentation/aere-issued.time-years-later"
],
"sdjwt.typ": [
"sdjwt-presentation/rfc9901.typ",
"sdjwt-presentation/aere.typ-kb",
"sdjwt-presentation/aere-issued.typ",
"sdjwt-presentation/sd-jwt-core.typ"
],
"sdjwt.unreferenced": [
"sdjwt-presentation/rfc9901-issued.unreferenced",
"sdjwt-presentation/sd-jwt-core.unreferenced"
],
"sdjwtvc.disclosed-protected": [
"sdjwt-vc-presentation/aere-pid.disclosed-protected"
],
"sdjwtvc.form": [
"sdjwt-vc-presentation/aere-pid.form-idx",
"sdjwt-vc-presentation/aere-pid.form-status",
"sdjwt-vc-presentation/aere-pid.form-integrity"
],
"sdjwtvc.status-index": [
"sdjwt-vc-presentation/aere-pid.status-index"
],
"sdjwtvc.status-list": [
"sdjwt-vc-presentation/aere-pid.status-list-other-uri",
"sdjwt-vc-presentation/aere-pid.status-list-expired",
"sdjwt-vc-presentation/aere-pid.status-list-stranger",
"sdjwt-vc-presentation/aere-pid.status-list-typ",
"sdjwt-vc-presentation/aere-pid.status-list-no-iat",
"sdjwt-vc-presentation/sd-jwt-vc.status-list-other-uri",
"sdjwt-vc-presentation/sd-jwt-vc.status-list-expired"
],
"sdjwtvc.status-revoked": [
"sdjwt-vc-presentation/aere-pid.status-revoked",
"sdjwt-vc-presentation/aere-pid.status-suspended",
"sdjwt-vc-presentation/sd-jwt-vc.status-revoked",
"sdjwt-vc-presentation/sd-jwt-vc.status-suspended"
],
"sdjwtvc.status-unjudged": [
"sdjwt-vc-presentation/aere-pid.status-unjudged",
"sdjwt-vc-presentation/sd-jwt-vc.status-unjudged"
],
"sdjwtvc.vct": [
"sdjwt-vc-presentation/aere-pid.vct"
],
"sdjwtvc.vct-expected": [
"sdjwt-vc-presentation/aere-pid.vct-expected"
],
"sdjwtvc.vct-mismatch": [
"sdjwt-vc-presentation/aere-pid.vct-mismatch",
"sdjwt-vc-presentation/sd-jwt-vc.vct-mismatch"
]
},
"vectors": [
@ -3867,6 +4000,608 @@
"requires": [],
"sha256": "0x9c5c730adbb0fbeacb86537d2105eedcd6c687948742a28dceb9917f2851d8dc"
},
{
"id": "sdjwt-presentation/rfc9901.valid",
"artifact": "sdjwt-presentation",
"verdict": "VALID",
"requires": [],
"sha256": "0xb17ee5bbb8da8bae3d03143e6160d4d64acf63b55a02c25a16fd4094ed8a9ff8"
},
{
"id": "sdjwt-presentation/rfc9901-issued.valid",
"artifact": "sdjwt-presentation",
"verdict": "VALID",
"requires": [],
"sha256": "0x04c37a5643c2709acdd97554beecd6f236422d43e65d359c3a9285e98ffbda35"
},
{
"id": "sdjwt-presentation/rfc9901.kb-audience",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x0ffcf487db005bcbace1d7d0961737b5642d4eabc6ccec2fdf383974657cf50b"
},
{
"id": "sdjwt-presentation/rfc9901.kb-nonce",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0xdb638acdc2a716dcdb39bb604193563bb635829be33e71335c591c7e579149f0"
},
{
"id": "sdjwt-presentation/rfc9901.kb-freshness",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x87d7a9a0b9024a3650ac95e626ed9b6431d8b681e035f4737e7e8769e273eb56"
},
{
"id": "sdjwt-presentation/rfc9901.kb-context",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0xe4d777dc0cf33955839d38d08fb6964d443045b41855f124f0b4b07ec6ae8441"
},
{
"id": "sdjwt-presentation/rfc9901.issuer",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x79002f5b01ff4319a8ade3c075ab529e4a8f21b0901836495a9b664dd9ea498e"
},
{
"id": "sdjwt-presentation/rfc9901.key",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0xd4f715d484688437ceaed4de485dfc60d23474474c99cb3d5c5ed08e9c114ad5"
},
{
"id": "sdjwt-presentation/rfc9901.signature",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0xbed1f3e911242d854ed61119b0ea7ed3d3ba7b22c66f0093fc411cd07b337ba4"
},
{
"id": "sdjwt-presentation/rfc9901.typ",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x610b0511d94253f4ed741599f8bdc8560de2ce824a6b265b02af851ef2ad2468"
},
{
"id": "sdjwt-presentation/rfc9901.form-clock",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x0548482f4dd888b221529a681153f98468c05eeceb71124a062ed6cd3fecd4ff"
},
{
"id": "sdjwt-presentation/rfc9901.form",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x75c50a18e68f039ee30268349b4f8d596243630283c7aac37e52bfe86a4f4cd9"
},
{
"id": "sdjwt-presentation/rfc9901.kb-required",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0xf7e658e06a4915c8c3c2316e71d94aa39f07f0a8143f711b37cd10c3d215064d"
},
{
"id": "sdjwt-presentation/rfc9901.kb-sd-hash",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0xfbd3aa0ad889053fc367fe07d0ba9c3cb317f9699b5471bdb3945a3b72380ea4"
},
{
"id": "sdjwt-presentation/rfc9901-issued.disclosure-twice",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x0e7b8c7215d4a411169962bb2427ad362a5d861508c1c694e7a5efa5a71d42d5"
},
{
"id": "sdjwt-presentation/rfc9901-issued.form-empty",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x4ed4bd8bfcbd330fed266458bedf5924dcd06683918052546ec20b92b15d1f7b"
},
{
"id": "sdjwt-presentation/rfc9901-issued.unreferenced",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x5c948c3cd0334abfacdd0b45c46165d211218516041d21bc966db66c64666283"
},
{
"id": "sdjwt-presentation/aere.valid",
"artifact": "sdjwt-presentation",
"verdict": "VALID",
"requires": [],
"sha256": "0xa4bf25e6c7be85907e2faa208a3cfbc24b4afee8a9bdc42afa7e4a03402c4244"
},
{
"id": "sdjwt-presentation/aere-ml-dsa-65.valid",
"artifact": "sdjwt-presentation",
"verdict": "VALID",
"requires": [],
"sha256": "0x566239bb9b499e3d9880278862d039190862ddc739b81ad047a5bc3cd4c2bd84"
},
{
"id": "sdjwt-presentation/aere-issued.valid",
"artifact": "sdjwt-presentation",
"verdict": "VALID",
"requires": [],
"sha256": "0x060d56983b8b5866320966db55e0e62bacc03bd50d87f3fabb69909599b6758e"
},
{
"id": "sdjwt-presentation/aere.signature-kb",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x6c4a37b0ee1f278f680076721f8dd9ca13ae438b50d9c5845e260433bcaa1cdf"
},
{
"id": "sdjwt-presentation/aere.kb-claims",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0xcf83d7bc18ada8ff77c1912c1c3678afbd93a96b790b8af4eb715c0077f41c0e"
},
{
"id": "sdjwt-presentation/aere.typ-kb",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x5d19972b3f596cc41986eacb9ce8e9fe15eefe64d77578d271c9ec323bb80054"
},
{
"id": "sdjwt-presentation/aere.kb-freshness-exp",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x113fad84b78b77a54a36b694e446bd97501b53088c53dd0b6370b25e1d1c5d18"
},
{
"id": "sdjwt-presentation/aere.kb-cnf",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0xf9d13dac0ffa00600d47be96bbd5c04e7c59eebd0b247ee9638c7246a321b6c0"
},
{
"id": "sdjwt-presentation/aere.time-expired",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x69e121ba34eb04588a2600eb1b8ad64ce72e2f9f995994e2ddad4bd863ce08b3"
},
{
"id": "sdjwt-presentation/aere.time-not-yet",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x062fcd99cb0ff9fe38a67b91d3aaf1219f57401b0aa24a0c78be9257d759e9ac"
},
{
"id": "sdjwt-presentation/aere-issued.digest-twice",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x44887dec6503ca912cea3a6ddafa4ed5e01333ab826f5259414dc684402e45f0"
},
{
"id": "sdjwt-presentation/aere-issued.sd-alg-nested",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x0ea82f93edb3b19517207915b79574a6da7f1133a257927ef4186cb5d658d3a2"
},
{
"id": "sdjwt-presentation/aere-issued.sd-alg",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0xa2d1384753a66a5dba6f2687500055c6bf37fc2ffdfa338beba4fbc7206e4301"
},
{
"id": "sdjwt-presentation/aere-issued.disclosure-name",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x132e6e91a14bc3d0d6677269ec6c2a398c3d8e1adb194e09fab8bff5c34c21fe"
},
{
"id": "sdjwt-presentation/aere-issued.disclosure-name-proto",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x5338feb82fe56b769e75c5fb64c3f94efe179401e60b855ca1c87919eacebbd4"
},
{
"id": "sdjwt-presentation/aere-issued.claim-conflict",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0xed21f15610061eb4f8e1888283913fb96785e8bf2cd9e7afc8d92a98e2cbc47d"
},
{
"id": "sdjwt-presentation/aere-issued.crit",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0xa2ce76f79c13e9faec8f0a172bab8af7d41d0be77d2eb7bda7966c27c1a712db"
},
{
"id": "sdjwt-presentation/aere-issued.typ",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x66d813e2099009cb947872aff7afba7d53ae5d57d80c4ff30fb44b9d18b3c873"
},
{
"id": "sdjwt-presentation/aere-issued.key-confusion",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x170a83409c1388467a3e3a287f21d965aea111738df4bf608ed4c40cdbcf52ac"
},
{
"id": "sdjwt-presentation/aere-issued.alg-none",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0xdd89f1d66bcb56a2f3dbe8153b8c87801f818be52d616702a4d40edcb5102277"
},
{
"id": "sdjwt-presentation/aere-issued.time-no-exp",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0xe673e99b16402da40f4fdfef1dc32c77aba7903972bbb277be76ea802366b5e3"
},
{
"id": "sdjwt-presentation/aere-issued.disclosure-form",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x9c63eed2d02e6f8207267937799233ff643de6796b3755d44b8c52a60e9739f8"
},
{
"id": "sdjwt-presentation/aere-issued.disclosure-form-not-json",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0xb669d3f8a57b0d926beaf415578e809a3b3e7f90440818a60bc2ae6da92a0373"
},
{
"id": "sdjwt-presentation/aere-issued.disclosure-form-sd",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x6df675c2e2ddda38eca7dcc925af1532418b90318dbdf88c6ac10bbdb9e7e9a1"
},
{
"id": "sdjwt-presentation/aere-issued.time-years-later",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0xf660f7dea5fe9bedb4495bb7a0df617385b73ef8ad41797d3a6b5ed77303a926"
},
{
"id": "sdjwt-presentation/sd-jwt-core.valid",
"artifact": "sdjwt-presentation",
"verdict": "VALID",
"requires": [],
"sha256": "0x71d62658266c8f31fa6aeff83fb5565c407d2b981ab78b6a06e90f580791da59"
},
{
"id": "sdjwt-presentation/sd-jwt-core-es256.valid",
"artifact": "sdjwt-presentation",
"verdict": "VALID",
"requires": [],
"sha256": "0x1a63524779967f5fbd00b39ffed1af4dcee3cbf87e92be2be21020a15142c2ac"
},
{
"id": "sdjwt-presentation/sd-jwt-core-ml-dsa-65.valid",
"artifact": "sdjwt-presentation",
"verdict": "VALID",
"requires": [],
"sha256": "0x482b805ad218e84510a35632c63045f310f2b78050d95d0207361ab6bf8b0abc"
},
{
"id": "sdjwt-presentation/sd-jwt-core-typed.valid",
"artifact": "sdjwt-presentation",
"verdict": "VALID",
"requires": [],
"sha256": "0xa1d9246df259269051d7a2a7ac3153f7254bb5cc6ff8f37e3c2c2f0368ebbf4f"
},
{
"id": "sdjwt-presentation/sd-jwt-core.typ",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0xfb5ba1d694fb5f7bf163f49a1e4d02916ad8cea38a0f677347f69b3fe82478e1"
},
{
"id": "sdjwt-presentation/sd-jwt-core.unreferenced",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x456d9abc237881556e309710c823998f2e84b53d3a3a4d3b3878454ef80a32e9"
},
{
"id": "sdjwt-presentation/sd-jwt-core.kb-audience",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x6cfa3d696a540aaa0ea0b9a721ee4716ee7687bb95413b1119e85f682e0e55dc"
},
{
"id": "sdjwt-presentation/sd-jwt-core.alg",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x8cd27350a3cd59185d43122746f416477403e75afa100bddca2ed8b064be14db"
},
{
"id": "sdjwt-presentation/sd-jwt-core.digest-twice",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x02a188377b49d09c05ad3b1983bbf66063c6be05aadeb7024348efb90c4afed8"
},
{
"id": "sdjwt-presentation/sd-jwt-core.signature-kb",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x424f7a30fe9735ea5908430cbef3514f1bff7b77ce16ab3e4455fa31e3b1a0d5"
},
{
"id": "sdjwt-presentation/sd-jwt-core.kb-sd-hash",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0xfc9fbaf5afb2e166b24747502dd4a07cb8adf72b937546a1e7f2f3cf5daf5f6c"
},
{
"id": "sdjwt-presentation/sd-jwt-core.sd-alg",
"artifact": "sdjwt-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x72a06db812e62ebf82790e5b6ebe2c17d5db41f171fa6d2c09fd66bbe5519fc8"
},
{
"id": "sdjwt-vc-presentation/aere-pid.valid",
"artifact": "sdjwt-vc-presentation",
"verdict": "VALID",
"requires": [],
"sha256": "0x4037fa40a084b4c2f1a7af6802b2571a93bc8042aae8b38e4d6793464e1bab8b"
},
{
"id": "sdjwt-vc-presentation/aere-pid-ml-dsa-65.valid",
"artifact": "sdjwt-vc-presentation",
"verdict": "VALID",
"requires": [],
"sha256": "0xd9f9a5f9f6ae3565fa24512fb3fc8cf2555c6126bc0712b72959acd2a1aec56b"
},
{
"id": "sdjwt-vc-presentation/aere-no-status.valid",
"artifact": "sdjwt-vc-presentation",
"verdict": "VALID",
"requires": [],
"sha256": "0xa875911438b0d95388b243f86e76406cd5ae2fa8ba20626f04037a6024816890"
},
{
"id": "sdjwt-vc-presentation/aere-pid-status-waived.partial",
"artifact": "sdjwt-vc-presentation",
"verdict": "PARTIAL",
"requires": [],
"sha256": "0xb5a2b2ec0165ca31cee3ee3eeed8768f1ba2263738c3efd2f99bdceabf04ab55"
},
{
"id": "sdjwt-vc-presentation/aere-pid-8-bits.valid",
"artifact": "sdjwt-vc-presentation",
"verdict": "VALID",
"requires": [],
"sha256": "0x83b6a8c4a65390d5b6debaed5042222620f0a82aff53473792e136925c28195a"
},
{
"id": "sdjwt-vc-presentation/aere-pid.vct-expected",
"artifact": "sdjwt-vc-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x45771debbe260bbbc6e2a7b5fbe551317d4660948581925a158edae9689b08f7"
},
{
"id": "sdjwt-vc-presentation/aere-pid.vct-mismatch",
"artifact": "sdjwt-vc-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x2f1e4cd09d7184e0a9ec39466de9053100ff48636ee9a33dab389c50abc9af62"
},
{
"id": "sdjwt-vc-presentation/aere-pid.status-revoked",
"artifact": "sdjwt-vc-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0xd9a95cc74c4b566d23e0513c25ea2d177ac3e7e426534995d36748fc50ff7552"
},
{
"id": "sdjwt-vc-presentation/aere-pid.status-suspended",
"artifact": "sdjwt-vc-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0xa846cc09df82afbe62a374ccf6329cf7d4b2cbfe9ca012696738179d76dc20fe"
},
{
"id": "sdjwt-vc-presentation/aere-pid.status-list-other-uri",
"artifact": "sdjwt-vc-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0xf772ddd4a3807705110eb41028ecd3ab28626de41199710b085215afbbbddd44"
},
{
"id": "sdjwt-vc-presentation/aere-pid.status-list-expired",
"artifact": "sdjwt-vc-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x75081bea94d1a739b44ae005d6cc81c46e2a960dd3c4c4ebefd2f8d22419c55b"
},
{
"id": "sdjwt-vc-presentation/aere-pid.status-list-stranger",
"artifact": "sdjwt-vc-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0xa079f4cd56609a180571173a91b1e9fc47b84b94916d68a060a26bcbc80e4537"
},
{
"id": "sdjwt-vc-presentation/aere-pid.status-list-typ",
"artifact": "sdjwt-vc-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x2ad1585933c5901cec2bdae407374f104e95a279e9ab6a66feb339cba355d2b4"
},
{
"id": "sdjwt-vc-presentation/aere-pid.status-list-no-iat",
"artifact": "sdjwt-vc-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x72a4a8c5085e0c222722413d1e42e71d07a89df6c8fa68067d49fcbcc81a2bd5"
},
{
"id": "sdjwt-vc-presentation/aere-pid.status-index",
"artifact": "sdjwt-vc-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x22fde994e6e073f8e28f7dffdad024917abce8ae3522de2fe5b7c5e7bc40abf2"
},
{
"id": "sdjwt-vc-presentation/aere-pid.status-unjudged",
"artifact": "sdjwt-vc-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x3ad94f9eda82f09dab7505fabba4ed0809428c5d8ba86e0fc2f73402cac076a9"
},
{
"id": "sdjwt-vc-presentation/aere-pid.vct",
"artifact": "sdjwt-vc-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x114f09bf63c5cbe717905385662ab75a3b9fa61e07e779b1168192389d558884"
},
{
"id": "sdjwt-vc-presentation/aere-pid.disclosed-protected",
"artifact": "sdjwt-vc-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0xc8a6be1abaa3dae8f31cf26dad961c812502b2d376988f58ef35cd089892caad"
},
{
"id": "sdjwt-vc-presentation/aere-pid.form-idx",
"artifact": "sdjwt-vc-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x83f5bc27803169753d4ac30ef44d82f66c73ed6e6842650168696cb6397e8459"
},
{
"id": "sdjwt-vc-presentation/aere-pid.form-status",
"artifact": "sdjwt-vc-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x44c5dddb20d400c6091e9deec56b9ebd69a69c6e7f325907e21720603111fddc"
},
{
"id": "sdjwt-vc-presentation/aere-pid.form-integrity",
"artifact": "sdjwt-vc-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0xe6a38bfdfb1ebbd0fea2e1d60ffd6832f3370f927a2bfb3fad03cdd590823f31"
},
{
"id": "sdjwt-vc-presentation/sd-jwt-vc.valid",
"artifact": "sdjwt-vc-presentation",
"verdict": "VALID",
"requires": [],
"sha256": "0x1404a0597db6f869adaf5ff8abedf8670cb63ba48819083908d3572679e72411"
},
{
"id": "sdjwt-vc-presentation/sd-jwt-vc-es256.valid",
"artifact": "sdjwt-vc-presentation",
"verdict": "VALID",
"requires": [],
"sha256": "0xf7b34bf9da366783955d233ad50a17ff7582a04a99532b1cb16d489912dcd372"
},
{
"id": "sdjwt-vc-presentation/sd-jwt-vc-ml-dsa-65.valid",
"artifact": "sdjwt-vc-presentation",
"verdict": "VALID",
"requires": [],
"sha256": "0xdea179ad9cd7ca65e786922c680828a38f0e694ae6c0f263d4fde195982c528f"
},
{
"id": "sdjwt-vc-presentation/sd-jwt-vc-8-bits.valid",
"artifact": "sdjwt-vc-presentation",
"verdict": "VALID",
"requires": [],
"sha256": "0xb8197a79e6faddf9b35fd95754d17dc8aa2d8174fe8d8a3be3239c767bd395ce"
},
{
"id": "sdjwt-vc-presentation/sd-jwt-vc-status-waived.partial",
"artifact": "sdjwt-vc-presentation",
"verdict": "PARTIAL",
"requires": [],
"sha256": "0xa7311135ea7ca068e7bc3f5e95c361f9462bec2b3abf52c30df8475cf9441a43"
},
{
"id": "sdjwt-vc-presentation/sd-jwt-vc.status-revoked",
"artifact": "sdjwt-vc-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0xeb4ac475c2cd1debe08d4dfc29359e6e9f30419b7cd3c4a01e1a227a14996ef8"
},
{
"id": "sdjwt-vc-presentation/sd-jwt-vc.status-suspended",
"artifact": "sdjwt-vc-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x1aa605fd51ecb74c7bf6508f10921112938d672483a942398bc2f3f15a49d423"
},
{
"id": "sdjwt-vc-presentation/sd-jwt-vc.status-list-other-uri",
"artifact": "sdjwt-vc-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x4020a11a308284d3570b98e72c5476b28ccd24bde24afeb00a2366966404154f"
},
{
"id": "sdjwt-vc-presentation/sd-jwt-vc.status-list-expired",
"artifact": "sdjwt-vc-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x25bbd41833ee8d02cb7d046f1c502a16f826316d8ca246271c37e310635a6b0d"
},
{
"id": "sdjwt-vc-presentation/sd-jwt-vc.vct-mismatch",
"artifact": "sdjwt-vc-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x6d245525ebed4580c4d4044712df02acf084f8c39671516b5328eb73904159ee"
},
{
"id": "sdjwt-vc-presentation/sd-jwt-vc.status-unjudged",
"artifact": "sdjwt-vc-presentation",
"verdict": "INVALID",
"requires": [],
"sha256": "0x10fed0db565c3f655e2ba85c08651d31fa42b0f7628b30e3295039aa8f9ac6b1"
},
{
"id": "dataset-record/r5.valid",
"artifact": "dataset-record",

View File

@ -0,0 +1,66 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/aere-issued.alg-none",
"artifact": "sdjwt-presentation",
"title": "alg none, no signature",
"source": "derived from sdjwt-presentation/aere-issued.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/aere-issued.valid",
"mutation": {
"producer": "the payload re-encoded under an alg none header with an empty signature",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJub25lIiwidHlwIjoiYWVyZStzZC1qd3QifQ.eyJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJvR1ZLcV9iYUlSbkdjX0x6S2c3Rjd4R0M2OTdOLXJSWjdNbGJMdk9jMzlvIn0seyIuLi4iOiJYU1BvSVhtdkRMMHY4a3BTZ1NGZ3ZuTWZtcy0zTllLdmtYM0cxd2RCNmg4In1dLCJhZGRyZXNzIjp7ImxvY2FsaXR5IjoiQ2x1aiIsImNvdW50cnkiOiJSTyJ9LCJfc2QiOlsiMGl3bk5fZjRkSGhfcUI0SlhyX201OGdoWFNYRmk3LTk0SDR4QnpOdXBMSSIsIjM1QnNjekpxVEdFNEdWY0ZZa0tEMEY3R0wweUlUdlp5MVpSU0x2Y2tpdTAiLCIzWm5SQk9fMGFZbUZCQUl6Tl9QZmdNYVlacUVYdWNibkg1Y2E5RFNNTFdBIiwiYVptbDlYNUU5cDhxaVJvcExVeGtTeUpsXzgtemEzQVRnRWFEanhBQ2o0OCIsImpLSlJ6WS00NmR5cWFHMnliQkk4OUxuT0ZuQ0xRSl9Ddk5rWnlnOFVxQzAiXSwiX3NkX2FsZyI6InNoYS0yNTYiLCJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiaWF0IjoxNzkyMzAyNTUyLCJleHAiOjE4MjM4Mzg1NTIsImNuZiI6eyJqd2siOnsiY3J2IjoiRWQyNTUxOSIsIngiOiJwZGd3WVJzOEtTdl9ESUJvaEFhaWx4MEoxS01xVGkyd2cwVGY3TmJaOFY0Iiwia3R5IjoiT0tQIn19fQ.~",
"issuerKey": {
"crv": "Ed25519",
"x": "hca9rLOG6cMHfk2weCWFz7wily7iDR_Qvhhs6tTQGjA",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"now": "2026-10-18T05:50:12.000Z",
"requireKeyBinding": false
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.alg"
],
"levels": {
"integrity": "NOT_MEASURED",
"authenticity": "FAILED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,66 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/aere-issued.claim-conflict",
"artifact": "sdjwt-presentation",
"title": "a disclosure that would overwrite a claim the payload has in the clear",
"source": "derived from sdjwt-presentation/aere-issued.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/aere-issued.valid",
"mutation": {
"producer": "the issuer signed a plain claim role and the digest of a disclosure named role",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImFlcmUrc2Qtand0In0.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiaWF0IjoxNzkyMzAyNTUyLCJleHAiOjE4MjM4Mzg1NTIsIl9zZF9hbGciOiJzaGEtMjU2IiwiY25mIjp7Imp3ayI6eyJjcnYiOiJFZDI1NTE5IiwieCI6InBkZ3dZUnM4S1N2X0RJQm9oQWFpbHgwSjFLTXFUaTJ3ZzBUZjdOYlo4VjQiLCJrdHkiOiJPS1AifX0sInJvbGUiOiJ1c2VyIiwiX3NkIjpbImp0U2FaZ256d1paOFJNSjhUNzlCMkNIS0xPV0t2MnVWWWJYSkk1YnVodTQiXX0.VFazRIXy0qzMn9g3b_hLb5q7hq6M5EAcjvs9mETMQ6fT3y36ZLVo9fOq7tOPq32ubVT75Q8GMJEDMhVTkl-dAA~WyJzYWx0LTMiLCJyb2xlIiwiYWRtaW4iXQ~",
"issuerKey": {
"crv": "Ed25519",
"x": "hca9rLOG6cMHfk2weCWFz7wily7iDR_Qvhhs6tTQGjA",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"now": "2026-10-18T05:50:12.000Z",
"requireKeyBinding": false
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.claim-conflict"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,66 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/aere-issued.crit",
"artifact": "sdjwt-presentation",
"title": "the issuer-signed JWT carries a crit header parameter",
"source": "derived from sdjwt-presentation/aere-issued.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/aere-issued.valid",
"mutation": {
"producer": "the issuer signed the header with crit [b64] and b64 false",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImFlcmUrc2Qtand0IiwiY3JpdCI6WyJiNjQiXSwiYjY0IjpmYWxzZX0.eyJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJvR1ZLcV9iYUlSbkdjX0x6S2c3Rjd4R0M2OTdOLXJSWjdNbGJMdk9jMzlvIn0seyIuLi4iOiJYU1BvSVhtdkRMMHY4a3BTZ1NGZ3ZuTWZtcy0zTllLdmtYM0cxd2RCNmg4In1dLCJhZGRyZXNzIjp7ImxvY2FsaXR5IjoiQ2x1aiIsImNvdW50cnkiOiJSTyJ9LCJfc2QiOlsiMGl3bk5fZjRkSGhfcUI0SlhyX201OGdoWFNYRmk3LTk0SDR4QnpOdXBMSSIsIjM1QnNjekpxVEdFNEdWY0ZZa0tEMEY3R0wweUlUdlp5MVpSU0x2Y2tpdTAiLCIzWm5SQk9fMGFZbUZCQUl6Tl9QZmdNYVlacUVYdWNibkg1Y2E5RFNNTFdBIiwiYVptbDlYNUU5cDhxaVJvcExVeGtTeUpsXzgtemEzQVRnRWFEanhBQ2o0OCIsImpLSlJ6WS00NmR5cWFHMnliQkk4OUxuT0ZuQ0xRSl9Ddk5rWnlnOFVxQzAiXSwiX3NkX2FsZyI6InNoYS0yNTYiLCJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiaWF0IjoxNzkyMzAyNTUyLCJleHAiOjE4MjM4Mzg1NTIsImNuZiI6eyJqd2siOnsiY3J2IjoiRWQyNTUxOSIsIngiOiJwZGd3WVJzOEtTdl9ESUJvaEFhaWx4MEoxS01xVGkyd2cwVGY3TmJaOFY0Iiwia3R5IjoiT0tQIn19fQ.81pRXwso1YgaPhC0wcUUxVr-ZVv4R3CK08-A9QzzQ83gN9ahrGFtn5OdXjUhpk5oXuJyQVTGSJEcMr7bO6iWBg~",
"issuerKey": {
"crv": "Ed25519",
"x": "hca9rLOG6cMHfk2weCWFz7wily7iDR_Qvhhs6tTQGjA",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"now": "2026-10-18T05:50:12.000Z",
"requireKeyBinding": false
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.crit"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,66 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/aere-issued.digest-twice",
"artifact": "sdjwt-presentation",
"title": "the issuer signed the same digest twice in _sd",
"source": "derived from sdjwt-presentation/aere-issued.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/aere-issued.valid",
"mutation": {
"producer": "the issuer signed a payload whose _sd repeats a digest",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImFlcmUrc2Qtand0In0.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiaWF0IjoxNzkyMzAyNTUyLCJleHAiOjE4MjM4Mzg1NTIsIl9zZF9hbGciOiJzaGEtMjU2IiwiY25mIjp7Imp3ayI6eyJjcnYiOiJFZDI1NTE5IiwieCI6InBkZ3dZUnM4S1N2X0RJQm9oQWFpbHgwSjFLTXFUaTJ3ZzBUZjdOYlo4VjQiLCJrdHkiOiJPS1AifX0sIl9zZCI6WyJlcTZoZjhaRmpnY1RxdGc3ME9keG5zUElKUkNWZ3ZHLW94Q29CWDBlQXJzIiwiZXE2aGY4WkZqZ2NUcXRnNzBPZHhuc1BJSlJDVmd2Ry1veENvQlgwZUFycyJdfQ.o118pMTuhwUnzcymlJbPobFjK31qoJBWfZ0qkiPdV-WZqpIlrF5eVEVhQy1FYuP1iT8-tpY4LGLP_GvHI4p8Bg~WyJzYWx0LTEiLCJhIiwxXQ~",
"issuerKey": {
"crv": "Ed25519",
"x": "hca9rLOG6cMHfk2weCWFz7wily7iDR_Qvhhs6tTQGjA",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"now": "2026-10-18T05:50:12.000Z",
"requireKeyBinding": false
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.digest-twice"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,66 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/aere-issued.disclosure-form-not-json",
"artifact": "sdjwt-presentation",
"title": "a disclosure that is base64url of text that is not JSON",
"source": "derived from sdjwt-presentation/aere-issued.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/aere-issued.valid",
"mutation": {
"producer": "the issuer signed the digest of a disclosure whose bytes are not JSON",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImFlcmUrc2Qtand0In0.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiaWF0IjoxNzkyMzAyNTUyLCJleHAiOjE4MjM4Mzg1NTIsIl9zZF9hbGciOiJzaGEtMjU2IiwiY25mIjp7Imp3ayI6eyJjcnYiOiJFZDI1NTE5IiwieCI6InBkZ3dZUnM4S1N2X0RJQm9oQWFpbHgwSjFLTXFUaTJ3ZzBUZjdOYlo4VjQiLCJrdHkiOiJPS1AifX0sIl9zZCI6WyI0Wi01OGlEZ1FqQUkwU1dOM0FWYVB2TmhOUEMzLVQ4dDFXQl9fNzEybWlVIl19.ft6nZuVHPQBXFRUi5AI1nopFtRfhB21AjgfDbnsPmqviRXWoC0-a3QoMcONIPdST4MO2Gj652hTQapSvWnTXAQ~bm90LWpzb24~",
"issuerKey": {
"crv": "Ed25519",
"x": "hca9rLOG6cMHfk2weCWFz7wily7iDR_Qvhhs6tTQGjA",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"now": "2026-10-18T05:50:12.000Z",
"requireKeyBinding": false
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.disclosure-form"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,66 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/aere-issued.disclosure-form-sd",
"artifact": "sdjwt-presentation",
"title": "_sd is a string, not a list of digests",
"source": "derived from sdjwt-presentation/aere-issued.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/aere-issued.valid",
"mutation": {
"producer": "the issuer signed a payload whose _sd is a string",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImFlcmUrc2Qtand0In0.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiaWF0IjoxNzkyMzAyNTUyLCJleHAiOjE4MjM4Mzg1NTIsIl9zZF9hbGciOiJzaGEtMjU2IiwiY25mIjp7Imp3ayI6eyJjcnYiOiJFZDI1NTE5IiwieCI6InBkZ3dZUnM4S1N2X0RJQm9oQWFpbHgwSjFLTXFUaTJ3ZzBUZjdOYlo4VjQiLCJrdHkiOiJPS1AifX0sIl9zZCI6IngifQ.JX0bQiY0zje3v_bhU-hqpFB6RPAFLrNS1vYXXKGLp3e6MA8TupBjYutIkOeCg0ZoRUswexj4xCcEbSQllwFyBA~",
"issuerKey": {
"crv": "Ed25519",
"x": "hca9rLOG6cMHfk2weCWFz7wily7iDR_Qvhhs6tTQGjA",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"now": "2026-10-18T05:50:12.000Z",
"requireKeyBinding": false
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.disclosure-form"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,66 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/aere-issued.disclosure-form",
"artifact": "sdjwt-presentation",
"title": "a disclosure that is a one-element list",
"source": "derived from sdjwt-presentation/aere-issued.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/aere-issued.valid",
"mutation": {
"producer": "the issuer signed the digest of a disclosure that is [salt] alone",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImFlcmUrc2Qtand0In0.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiaWF0IjoxNzkyMzAyNTUyLCJleHAiOjE4MjM4Mzg1NTIsIl9zZF9hbGciOiJzaGEtMjU2IiwiY25mIjp7Imp3ayI6eyJjcnYiOiJFZDI1NTE5IiwieCI6InBkZ3dZUnM4S1N2X0RJQm9oQWFpbHgwSjFLTXFUaTJ3ZzBUZjdOYlo4VjQiLCJrdHkiOiJPS1AifX0sIl9zZCI6WyI5SWI0RGhwZVNxbkY5YmEyaXZOeGtQbHNTUzAwYWVxakd4YVFYZ1NPUUpBIl19.c7TNsY2EDEHxk7BF_dlgJ8vxc6p61EXzOvVRtSw-bzlI07lZCiSIS1uTG8sXp7XPGbpTUvVfJRg3qquaKEKiAw~WyJvbmx5LWEtc2FsdCJd~",
"issuerKey": {
"crv": "Ed25519",
"x": "hca9rLOG6cMHfk2weCWFz7wily7iDR_Qvhhs6tTQGjA",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"now": "2026-10-18T05:50:12.000Z",
"requireKeyBinding": false
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.disclosure-form"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,66 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/aere-issued.disclosure-name-proto",
"artifact": "sdjwt-presentation",
"title": "a plain claim named __proto__, signed by the issuer",
"source": "derived from sdjwt-presentation/aere-issued.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/aere-issued.valid",
"mutation": {
"producer": "the issuer signed a payload with a claim named __proto__",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImFlcmUrc2Qtand0In0.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiaWF0IjoxNzkyMzAyNTUyLCJleHAiOjE3OTIzMDM1NTIsIl9zZF9hbGciOiJzaGEtMjU2IiwiX19wcm90b19fIjp7ImFkbWluIjp0cnVlfX0.Pzf8iZOKj7lR6Zdoyp4kZrd9EKCEc0TaSoBiw8ZoMvpovMuWZEfE6KBbpgbdg17mFq_2Z4FNzVLLn87ZQYfPAg~",
"issuerKey": {
"crv": "Ed25519",
"x": "hca9rLOG6cMHfk2weCWFz7wily7iDR_Qvhhs6tTQGjA",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"now": "2026-10-18T05:50:12.000Z",
"requireKeyBinding": false
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.disclosure-name"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,66 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/aere-issued.disclosure-name",
"artifact": "sdjwt-presentation",
"title": "a disclosure named _sd, signed for by the issuer",
"source": "derived from sdjwt-presentation/aere-issued.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/aere-issued.valid",
"mutation": {
"producer": "the issuer put in _sd the digest of a disclosure named _sd",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImFlcmUrc2Qtand0In0.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiaWF0IjoxNzkyMzAyNTUyLCJleHAiOjE4MjM4Mzg1NTIsIl9zZF9hbGciOiJzaGEtMjU2IiwiY25mIjp7Imp3ayI6eyJjcnYiOiJFZDI1NTE5IiwieCI6InBkZ3dZUnM4S1N2X0RJQm9oQWFpbHgwSjFLTXFUaTJ3ZzBUZjdOYlo4VjQiLCJrdHkiOiJPS1AifX0sIl9zZCI6WyJFQmdlQmw5UjJOakQzMEJVaTFHM29jeUdIUERCaUpNd2VHdUtLc3diTWF3Il19.i-lUl2Fl1-I8l4-uwcdcqZom-uuYGZkL7-ZHXDh--z2cIF4vrUpp6Qn2y74bl3jBmxApP20YIm49TqK4_TqkAQ~WyJzYWx0LTIiLCJfc2QiLFsieCJdXQ~",
"issuerKey": {
"crv": "Ed25519",
"x": "hca9rLOG6cMHfk2weCWFz7wily7iDR_Qvhhs6tTQGjA",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"now": "2026-10-18T05:50:12.000Z",
"requireKeyBinding": false
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.disclosure-name"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,66 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/aere-issued.key-confusion",
"artifact": "sdjwt-presentation",
"title": "the header says ES256 and the signature was made with the Ed25519 key (algorithm confusion)",
"source": "derived from sdjwt-presentation/aere-issued.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/aere-issued.valid",
"mutation": {
"producer": "the issuer signed with its Ed25519 key under an ES256 header",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFUzI1NiIsInR5cCI6ImFlcmUrc2Qtand0In0.eyJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJvR1ZLcV9iYUlSbkdjX0x6S2c3Rjd4R0M2OTdOLXJSWjdNbGJMdk9jMzlvIn0seyIuLi4iOiJYU1BvSVhtdkRMMHY4a3BTZ1NGZ3ZuTWZtcy0zTllLdmtYM0cxd2RCNmg4In1dLCJhZGRyZXNzIjp7ImxvY2FsaXR5IjoiQ2x1aiIsImNvdW50cnkiOiJSTyJ9LCJfc2QiOlsiMGl3bk5fZjRkSGhfcUI0SlhyX201OGdoWFNYRmk3LTk0SDR4QnpOdXBMSSIsIjM1QnNjekpxVEdFNEdWY0ZZa0tEMEY3R0wweUlUdlp5MVpSU0x2Y2tpdTAiLCIzWm5SQk9fMGFZbUZCQUl6Tl9QZmdNYVlacUVYdWNibkg1Y2E5RFNNTFdBIiwiYVptbDlYNUU5cDhxaVJvcExVeGtTeUpsXzgtemEzQVRnRWFEanhBQ2o0OCIsImpLSlJ6WS00NmR5cWFHMnliQkk4OUxuT0ZuQ0xRSl9Ddk5rWnlnOFVxQzAiXSwiX3NkX2FsZyI6InNoYS0yNTYiLCJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiaWF0IjoxNzkyMzAyNTUyLCJleHAiOjE4MjM4Mzg1NTIsImNuZiI6eyJqd2siOnsiY3J2IjoiRWQyNTUxOSIsIngiOiJwZGd3WVJzOEtTdl9ESUJvaEFhaWx4MEoxS01xVGkyd2cwVGY3TmJaOFY0Iiwia3R5IjoiT0tQIn19fQ.znkWKtPFFufaaSFVBWKp561hnJj5tXmCxKFg4TMWjemaG8VLJkN22X6GiAqQ7y1urPxuTYgvBH3oOVPNmuV8Ag~",
"issuerKey": {
"crv": "Ed25519",
"x": "hca9rLOG6cMHfk2weCWFz7wily7iDR_Qvhhs6tTQGjA",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"now": "2026-10-18T05:50:12.000Z",
"requireKeyBinding": false
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.key"
],
"levels": {
"integrity": "NOT_MEASURED",
"authenticity": "FAILED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,66 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/aere-issued.sd-alg-nested",
"artifact": "sdjwt-presentation",
"title": "the issuer signed an _sd_alg below the top level (RFC 9901 Section 4.1.1 forbids it)",
"source": "derived from sdjwt-presentation/aere-issued.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/aere-issued.valid",
"mutation": {
"producer": "the issuer signed a payload with _sd_alg inside a nested object",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImFlcmUrc2Qtand0In0.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiaWF0IjoxNzkyMzAyNTUyLCJleHAiOjE4MjM4Mzg1NTIsIl9zZF9hbGciOiJzaGEtMjU2IiwiY25mIjp7Imp3ayI6eyJjcnYiOiJFZDI1NTE5IiwieCI6InBkZ3dZUnM4S1N2X0RJQm9oQWFpbHgwSjFLTXFUaTJ3ZzBUZjdOYlo4VjQiLCJrdHkiOiJPS1AifX0sIm1ldGEiOnsiX3NkX2FsZyI6InNoYS0yNTYiLCJub3RlIjoxfX0.miCZJvF0MrS1F2eldNJRUJfxOD03J4J4whnxNnEavTOTl5DXK1pF85U5_tmprPskVCCVlHSZgYoTiu1P7nohAw~",
"issuerKey": {
"crv": "Ed25519",
"x": "hca9rLOG6cMHfk2weCWFz7wily7iDR_Qvhhs6tTQGjA",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"now": "2026-10-18T05:50:12.000Z",
"requireKeyBinding": false
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.sd-alg"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,66 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/aere-issued.sd-alg",
"artifact": "sdjwt-presentation",
"title": "the issuer signed _sd_alg sha-384, which this verifier does not understand",
"source": "derived from sdjwt-presentation/aere-issued.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/aere-issued.valid",
"mutation": {
"producer": "the issuer signed a payload with _sd_alg sha-384",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImFlcmUrc2Qtand0In0.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiaWF0IjoxNzkyMzAyNTUyLCJleHAiOjE4MjM4Mzg1NTIsIl9zZF9hbGciOiJzaGEtMzg0IiwiY25mIjp7Imp3ayI6eyJjcnYiOiJFZDI1NTE5IiwieCI6InBkZ3dZUnM4S1N2X0RJQm9oQWFpbHgwSjFLTXFUaTJ3ZzBUZjdOYlo4VjQiLCJrdHkiOiJPS1AifX19.Hu8fus-Adj5-Ri-PhCwX248ABzbWhrVZOZTBj4uU-mZLaOPFWUAV5f6l_oqHtP-g5mZ628xHXi-lMPRLGMTWAg~",
"issuerKey": {
"crv": "Ed25519",
"x": "hca9rLOG6cMHfk2weCWFz7wily7iDR_Qvhhs6tTQGjA",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"now": "2026-10-18T05:50:12.000Z",
"requireKeyBinding": false
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.sd-alg"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,66 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/aere-issued.time-no-exp",
"artifact": "sdjwt-presentation",
"title": "the issuer-signed JWT has no exp, and the verifier requires one",
"source": "derived from sdjwt-presentation/aere-issued.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/aere-issued.valid",
"mutation": {
"producer": "the issuer signed a payload without exp",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImFlcmUrc2Qtand0In0.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiaWF0IjoxNzkyMzAyNTUyLCJfc2RfYWxnIjoic2hhLTI1NiIsImNuZiI6eyJqd2siOnsiY3J2IjoiRWQyNTUxOSIsIngiOiJwZGd3WVJzOEtTdl9ESUJvaEFhaWx4MEoxS01xVGkyd2cwVGY3TmJaOFY0Iiwia3R5IjoiT0tQIn19fQ.8NI7L4kZ-4Xkihp0rv2xflQEz4nBahV96wuv1M7t7bCpTX5Oe9-JGaNsHkPUhAv7VjB1qx8oQCrFdgBQZarXBA~",
"issuerKey": {
"crv": "Ed25519",
"x": "hca9rLOG6cMHfk2weCWFz7wily7iDR_Qvhhs6tTQGjA",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"now": "2026-10-18T05:50:12.000Z",
"requireKeyBinding": false
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.time"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,65 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/aere-issued.time-years-later",
"artifact": "sdjwt-presentation",
"title": "the verifier clock is years later: the credential has expired",
"source": "derived from sdjwt-presentation/aere-issued.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/aere-issued.valid",
"mutation": {
"op": "set",
"path": [
"now"
],
"value": "2027-11-22T05:49:12.000Z"
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImFlcmUrc2Qtand0In0.eyJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJvR1ZLcV9iYUlSbkdjX0x6S2c3Rjd4R0M2OTdOLXJSWjdNbGJMdk9jMzlvIn0seyIuLi4iOiJYU1BvSVhtdkRMMHY4a3BTZ1NGZ3ZuTWZtcy0zTllLdmtYM0cxd2RCNmg4In1dLCJhZGRyZXNzIjp7ImxvY2FsaXR5IjoiQ2x1aiIsImNvdW50cnkiOiJSTyJ9LCJfc2QiOlsiMGl3bk5fZjRkSGhfcUI0SlhyX201OGdoWFNYRmk3LTk0SDR4QnpOdXBMSSIsIjM1QnNjekpxVEdFNEdWY0ZZa0tEMEY3R0wweUlUdlp5MVpSU0x2Y2tpdTAiLCIzWm5SQk9fMGFZbUZCQUl6Tl9QZmdNYVlacUVYdWNibkg1Y2E5RFNNTFdBIiwiYVptbDlYNUU5cDhxaVJvcExVeGtTeUpsXzgtemEzQVRnRWFEanhBQ2o0OCIsImpLSlJ6WS00NmR5cWFHMnliQkk4OUxuT0ZuQ0xRSl9Ddk5rWnlnOFVxQzAiXSwiX3NkX2FsZyI6InNoYS0yNTYiLCJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiaWF0IjoxNzkyMzAyNTUyLCJleHAiOjE4MjM4Mzg1NTIsImNuZiI6eyJqd2siOnsiY3J2IjoiRWQyNTUxOSIsIngiOiJwZGd3WVJzOEtTdl9ESUJvaEFhaWx4MEoxS01xVGkyd2cwVGY3TmJaOFY0Iiwia3R5IjoiT0tQIn19fQ.h75vV6jAkI1n0st_TUrGseDJKEk0RScfX5neSm_CSN2GoVjL2Ml2oKmB0szWDCjjlAcq1Tn1B39KNwEE1dWzBw~WyJhcDdQQnplOXZpVnZDNXlGQkp6X2RnIiwiZ2l2ZW5fbmFtZSIsIkFkYSJd~WyJFTUI5Z2JvX21JRk82S0JEaHp3bTlBIiwiZmFtaWx5X25hbWUiLCJFeGFtcGxlIl0~WyJSYTAyRkdCZDJmMW5HRlJPUFNUdURnIiwiYWdlX292ZXJfMTgiLHRydWVd~WyJZUVdma1BBSW1UTUpTU09vNmQ1WVJBIiwiUk8iXQ~WyIxVDEtY0c5Sm5vRWV2OXdQOGxRQkJBIiwiREUiXQ~",
"issuerKey": {
"crv": "Ed25519",
"x": "hca9rLOG6cMHfk2weCWFz7wily7iDR_Qvhhs6tTQGjA",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"now": "2027-11-22T05:49:12.000Z",
"requireKeyBinding": false
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.time"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,66 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/aere-issued.typ",
"artifact": "sdjwt-presentation",
"title": "the issuer-signed JWT is typed JWT, not an explicit SD-JWT type",
"source": "derived from sdjwt-presentation/aere-issued.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/aere-issued.valid",
"mutation": {
"producer": "the issuer signed the header with typ JWT",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJvR1ZLcV9iYUlSbkdjX0x6S2c3Rjd4R0M2OTdOLXJSWjdNbGJMdk9jMzlvIn0seyIuLi4iOiJYU1BvSVhtdkRMMHY4a3BTZ1NGZ3ZuTWZtcy0zTllLdmtYM0cxd2RCNmg4In1dLCJhZGRyZXNzIjp7ImxvY2FsaXR5IjoiQ2x1aiIsImNvdW50cnkiOiJSTyJ9LCJfc2QiOlsiMGl3bk5fZjRkSGhfcUI0SlhyX201OGdoWFNYRmk3LTk0SDR4QnpOdXBMSSIsIjM1QnNjekpxVEdFNEdWY0ZZa0tEMEY3R0wweUlUdlp5MVpSU0x2Y2tpdTAiLCIzWm5SQk9fMGFZbUZCQUl6Tl9QZmdNYVlacUVYdWNibkg1Y2E5RFNNTFdBIiwiYVptbDlYNUU5cDhxaVJvcExVeGtTeUpsXzgtemEzQVRnRWFEanhBQ2o0OCIsImpLSlJ6WS00NmR5cWFHMnliQkk4OUxuT0ZuQ0xRSl9Ddk5rWnlnOFVxQzAiXSwiX3NkX2FsZyI6InNoYS0yNTYiLCJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiaWF0IjoxNzkyMzAyNTUyLCJleHAiOjE4MjM4Mzg1NTIsImNuZiI6eyJqd2siOnsiY3J2IjoiRWQyNTUxOSIsIngiOiJwZGd3WVJzOEtTdl9ESUJvaEFhaWx4MEoxS01xVGkyd2cwVGY3TmJaOFY0Iiwia3R5IjoiT0tQIn19fQ.H_Y6xkCmnk9mMnwgyEz06o6bn7fzLPgltQ8rLvkF70EpIdi8SzqeWldP5FLxdrY2C0kjaYSOFEYgM958K--GDA~",
"issuerKey": {
"crv": "Ed25519",
"x": "hca9rLOG6cMHfk2weCWFz7wily7iDR_Qvhhs6tTQGjA",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"now": "2026-10-18T05:50:12.000Z",
"requireKeyBinding": false
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.typ"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,57 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/aere-issued.valid",
"artifact": "sdjwt-presentation",
"title": "the same SD-JWT as issued (every disclosure, no key binding), judged by a verifier that does not require key binding",
"source": "producers (sdjwt.mjs: issueSdJwt, presentSdJwt), three hybrid key pairs made and discarded at generation",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": null,
"mutation": null,
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImFlcmUrc2Qtand0In0.eyJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJvR1ZLcV9iYUlSbkdjX0x6S2c3Rjd4R0M2OTdOLXJSWjdNbGJMdk9jMzlvIn0seyIuLi4iOiJYU1BvSVhtdkRMMHY4a3BTZ1NGZ3ZuTWZtcy0zTllLdmtYM0cxd2RCNmg4In1dLCJhZGRyZXNzIjp7ImxvY2FsaXR5IjoiQ2x1aiIsImNvdW50cnkiOiJSTyJ9LCJfc2QiOlsiMGl3bk5fZjRkSGhfcUI0SlhyX201OGdoWFNYRmk3LTk0SDR4QnpOdXBMSSIsIjM1QnNjekpxVEdFNEdWY0ZZa0tEMEY3R0wweUlUdlp5MVpSU0x2Y2tpdTAiLCIzWm5SQk9fMGFZbUZCQUl6Tl9QZmdNYVlacUVYdWNibkg1Y2E5RFNNTFdBIiwiYVptbDlYNUU5cDhxaVJvcExVeGtTeUpsXzgtemEzQVRnRWFEanhBQ2o0OCIsImpLSlJ6WS00NmR5cWFHMnliQkk4OUxuT0ZuQ0xRSl9Ddk5rWnlnOFVxQzAiXSwiX3NkX2FsZyI6InNoYS0yNTYiLCJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiaWF0IjoxNzkyMzAyNTUyLCJleHAiOjE4MjM4Mzg1NTIsImNuZiI6eyJqd2siOnsiY3J2IjoiRWQyNTUxOSIsIngiOiJwZGd3WVJzOEtTdl9ESUJvaEFhaWx4MEoxS01xVGkyd2cwVGY3TmJaOFY0Iiwia3R5IjoiT0tQIn19fQ.h75vV6jAkI1n0st_TUrGseDJKEk0RScfX5neSm_CSN2GoVjL2Ml2oKmB0szWDCjjlAcq1Tn1B39KNwEE1dWzBw~WyJhcDdQQnplOXZpVnZDNXlGQkp6X2RnIiwiZ2l2ZW5fbmFtZSIsIkFkYSJd~WyJFTUI5Z2JvX21JRk82S0JEaHp3bTlBIiwiZmFtaWx5X25hbWUiLCJFeGFtcGxlIl0~WyJSYTAyRkdCZDJmMW5HRlJPUFNUdURnIiwiYWdlX292ZXJfMTgiLHRydWVd~WyJZUVdma1BBSW1UTUpTU09vNmQ1WVJBIiwiUk8iXQ~WyIxVDEtY0c5Sm5vRWV2OXdQOGxRQkJBIiwiREUiXQ~",
"issuerKey": {
"crv": "Ed25519",
"x": "hca9rLOG6cMHfk2weCWFz7wily7iDR_Qvhhs6tTQGjA",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"now": "2026-10-18T05:50:12.000Z",
"requireKeyBinding": false
},
"expected": {
"verdict": "VALID",
"failed": [],
"levels": {
"integrity": "PASSED",
"authenticity": "PASSED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,68 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/aere.kb-claims",
"artifact": "sdjwt-presentation",
"title": "the key binding JWT carries no nonce",
"source": "derived from sdjwt-presentation/aere.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/aere.valid",
"mutation": {
"producer": "the holder signed a key binding JWT without the nonce claim",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImFlcmUrc2Qtand0In0.eyJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJvR1ZLcV9iYUlSbkdjX0x6S2c3Rjd4R0M2OTdOLXJSWjdNbGJMdk9jMzlvIn0seyIuLi4iOiJYU1BvSVhtdkRMMHY4a3BTZ1NGZ3ZuTWZtcy0zTllLdmtYM0cxd2RCNmg4In1dLCJhZGRyZXNzIjp7ImxvY2FsaXR5IjoiQ2x1aiIsImNvdW50cnkiOiJSTyJ9LCJfc2QiOlsiMGl3bk5fZjRkSGhfcUI0SlhyX201OGdoWFNYRmk3LTk0SDR4QnpOdXBMSSIsIjM1QnNjekpxVEdFNEdWY0ZZa0tEMEY3R0wweUlUdlp5MVpSU0x2Y2tpdTAiLCIzWm5SQk9fMGFZbUZCQUl6Tl9QZmdNYVlacUVYdWNibkg1Y2E5RFNNTFdBIiwiYVptbDlYNUU5cDhxaVJvcExVeGtTeUpsXzgtemEzQVRnRWFEanhBQ2o0OCIsImpLSlJ6WS00NmR5cWFHMnliQkk4OUxuT0ZuQ0xRSl9Ddk5rWnlnOFVxQzAiXSwiX3NkX2FsZyI6InNoYS0yNTYiLCJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiaWF0IjoxNzkyMzAyNTUyLCJleHAiOjE4MjM4Mzg1NTIsImNuZiI6eyJqd2siOnsiY3J2IjoiRWQyNTUxOSIsIngiOiJwZGd3WVJzOEtTdl9ESUJvaEFhaWx4MEoxS01xVGkyd2cwVGY3TmJaOFY0Iiwia3R5IjoiT0tQIn19fQ.h75vV6jAkI1n0st_TUrGseDJKEk0RScfX5neSm_CSN2GoVjL2Ml2oKmB0szWDCjjlAcq1Tn1B39KNwEE1dWzBw~WyJSYTAyRkdCZDJmMW5HRlJPUFNUdURnIiwiYWdlX292ZXJfMTgiLHRydWVd~WyJZUVdma1BBSW1UTUpTU09vNmQ1WVJBIiwiUk8iXQ~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE3OTIzMDI1NTIsImF1ZCI6Imh0dHBzOi8vdmVyaWZpZXIuZXhhbXBsZSIsInNkX2hhc2giOiJQVmNXc1Q2dUlRYVBwUVFDNUFEMlM0N0N2eUJZaUUwcUNUVWVLaXdGX0ZVIn0.2Xg-c7x8cfyFRyP5Bz4Or74pjvWqUgJgdkF_JlnjRrUfd5-YqrBxcs2GTHQAOOCy55_CBmGdSJf-N-aUxVFSAA",
"issuerKey": {
"crv": "Ed25519",
"x": "hca9rLOG6cMHfk2weCWFz7wily7iDR_Qvhhs6tTQGjA",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-879fc417e331bc80",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.kb-claims"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,68 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/aere.kb-cnf",
"artifact": "sdjwt-presentation",
"title": "the issuer-signed JWT names no holder key, and a key binding JWT is attached anyway",
"source": "derived from sdjwt-presentation/aere.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/aere.valid",
"mutation": {
"producer": "the issuer signed a JWT without cnf; a key binding JWT was attached to it",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImFlcmUrc2Qtand0In0.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiaWF0IjoxNzkyMzAyNTUyLCJleHAiOjE3OTIzMDM1NTIsIl9zZF9hbGciOiJzaGEtMjU2In0.siec0A-CE4I3kL_tWgRWscIb-i-cSNws7MUJgo8it7rgdoI4_wj2hacfV8Pl3GGUL8vft-cUTJp7_-E3QX4HBg~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE3OTIzMDI1NTIsImF1ZCI6Imh0dHBzOi8vdmVyaWZpZXIuZXhhbXBsZSIsIm5vbmNlIjoibi04NzlmYzQxN2UzMzFiYzgwIiwic2RfaGFzaCI6InpSakFUMXdud3E2dWxXMnp4UWNGZkp2SzRPUlladW12VGZfMFBQSEVHNm8ifQ.6BcEj9ctCnkuNJjhs7HqjtwFgRKOXjQRsRbqqzN-IMdI63Nz6C6NO0c__y4EeRp7f4IoNvbqvFL9ImfbxHlKAw",
"issuerKey": {
"crv": "Ed25519",
"x": "hca9rLOG6cMHfk2weCWFz7wily7iDR_Qvhhs6tTQGjA",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-879fc417e331bc80",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.kb-cnf"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,68 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/aere.kb-freshness-exp",
"artifact": "sdjwt-presentation",
"title": "the key binding JWT carries an exp that has passed",
"source": "derived from sdjwt-presentation/aere.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/aere.valid",
"mutation": {
"producer": "the holder signed a key binding JWT with exp in the past",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImFlcmUrc2Qtand0In0.eyJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJvR1ZLcV9iYUlSbkdjX0x6S2c3Rjd4R0M2OTdOLXJSWjdNbGJMdk9jMzlvIn0seyIuLi4iOiJYU1BvSVhtdkRMMHY4a3BTZ1NGZ3ZuTWZtcy0zTllLdmtYM0cxd2RCNmg4In1dLCJhZGRyZXNzIjp7ImxvY2FsaXR5IjoiQ2x1aiIsImNvdW50cnkiOiJSTyJ9LCJfc2QiOlsiMGl3bk5fZjRkSGhfcUI0SlhyX201OGdoWFNYRmk3LTk0SDR4QnpOdXBMSSIsIjM1QnNjekpxVEdFNEdWY0ZZa0tEMEY3R0wweUlUdlp5MVpSU0x2Y2tpdTAiLCIzWm5SQk9fMGFZbUZCQUl6Tl9QZmdNYVlacUVYdWNibkg1Y2E5RFNNTFdBIiwiYVptbDlYNUU5cDhxaVJvcExVeGtTeUpsXzgtemEzQVRnRWFEanhBQ2o0OCIsImpLSlJ6WS00NmR5cWFHMnliQkk4OUxuT0ZuQ0xRSl9Ddk5rWnlnOFVxQzAiXSwiX3NkX2FsZyI6InNoYS0yNTYiLCJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiaWF0IjoxNzkyMzAyNTUyLCJleHAiOjE4MjM4Mzg1NTIsImNuZiI6eyJqd2siOnsiY3J2IjoiRWQyNTUxOSIsIngiOiJwZGd3WVJzOEtTdl9ESUJvaEFhaWx4MEoxS01xVGkyd2cwVGY3TmJaOFY0Iiwia3R5IjoiT0tQIn19fQ.h75vV6jAkI1n0st_TUrGseDJKEk0RScfX5neSm_CSN2GoVjL2Ml2oKmB0szWDCjjlAcq1Tn1B39KNwEE1dWzBw~WyJSYTAyRkdCZDJmMW5HRlJPUFNUdURnIiwiYWdlX292ZXJfMTgiLHRydWVd~WyJZUVdma1BBSW1UTUpTU09vNmQ1WVJBIiwiUk8iXQ~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE3OTIzMDI1NTIsImF1ZCI6Imh0dHBzOi8vdmVyaWZpZXIuZXhhbXBsZSIsIm5vbmNlIjoibi04NzlmYzQxN2UzMzFiYzgwIiwic2RfaGFzaCI6IlBWY1dzVDZ1SVFhUHBRUUM1QUQyUzQ3Q3Z5QllpRTBxQ1RVZUtpd0ZfRlUiLCJleHAiOjE3OTIzMDI0NTJ9.rWeWitBK6pQtGKD6koJkM4TMssJgPMSUa07QfCMnpNuWlj9X8UKV7T_FrtP5xbTcl7BwkcMmbrSxtEvUo8EoCg",
"issuerKey": {
"crv": "Ed25519",
"x": "hca9rLOG6cMHfk2weCWFz7wily7iDR_Qvhhs6tTQGjA",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-879fc417e331bc80",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.kb-freshness"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,68 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/aere.signature-kb",
"artifact": "sdjwt-presentation",
"title": "the key binding JWT is signed by another key than cnf.jwk",
"source": "derived from sdjwt-presentation/aere.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/aere.valid",
"mutation": {
"producer": "a stranger made the key binding JWT with its own key over the holder's SD-JWT",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImFlcmUrc2Qtand0In0.eyJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJvR1ZLcV9iYUlSbkdjX0x6S2c3Rjd4R0M2OTdOLXJSWjdNbGJMdk9jMzlvIn0seyIuLi4iOiJYU1BvSVhtdkRMMHY4a3BTZ1NGZ3ZuTWZtcy0zTllLdmtYM0cxd2RCNmg4In1dLCJhZGRyZXNzIjp7ImxvY2FsaXR5IjoiQ2x1aiIsImNvdW50cnkiOiJSTyJ9LCJfc2QiOlsiMGl3bk5fZjRkSGhfcUI0SlhyX201OGdoWFNYRmk3LTk0SDR4QnpOdXBMSSIsIjM1QnNjekpxVEdFNEdWY0ZZa0tEMEY3R0wweUlUdlp5MVpSU0x2Y2tpdTAiLCIzWm5SQk9fMGFZbUZCQUl6Tl9QZmdNYVlacUVYdWNibkg1Y2E5RFNNTFdBIiwiYVptbDlYNUU5cDhxaVJvcExVeGtTeUpsXzgtemEzQVRnRWFEanhBQ2o0OCIsImpLSlJ6WS00NmR5cWFHMnliQkk4OUxuT0ZuQ0xRSl9Ddk5rWnlnOFVxQzAiXSwiX3NkX2FsZyI6InNoYS0yNTYiLCJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiaWF0IjoxNzkyMzAyNTUyLCJleHAiOjE4MjM4Mzg1NTIsImNuZiI6eyJqd2siOnsiY3J2IjoiRWQyNTUxOSIsIngiOiJwZGd3WVJzOEtTdl9ESUJvaEFhaWx4MEoxS01xVGkyd2cwVGY3TmJaOFY0Iiwia3R5IjoiT0tQIn19fQ.h75vV6jAkI1n0st_TUrGseDJKEk0RScfX5neSm_CSN2GoVjL2Ml2oKmB0szWDCjjlAcq1Tn1B39KNwEE1dWzBw~WyJSYTAyRkdCZDJmMW5HRlJPUFNUdURnIiwiYWdlX292ZXJfMTgiLHRydWVd~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE3OTIzMDI1NTIsImF1ZCI6Imh0dHBzOi8vdmVyaWZpZXIuZXhhbXBsZSIsIm5vbmNlIjoibi04NzlmYzQxN2UzMzFiYzgwIiwic2RfaGFzaCI6Im4tdnRaMy02UkRVeVNmQWEwWFM5Zjd6S1hEdi1NblhmRWhaSXhNSzJmV1UifQ.bDoA14XQGrt_QnBJqIw8SqdhPszP8Mn-nbhVKmifXg-ZNDey7x_NFjVRP7G8or95EZ1k3M3tbtnFM6bysU98AA",
"issuerKey": {
"crv": "Ed25519",
"x": "hca9rLOG6cMHfk2weCWFz7wily7iDR_Qvhhs6tTQGjA",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-879fc417e331bc80",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.signature"
],
"levels": {
"integrity": "NOT_MEASURED",
"authenticity": "FAILED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,68 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/aere.time-expired",
"artifact": "sdjwt-presentation",
"title": "the credential expired a second before the verifier clock",
"source": "derived from sdjwt-presentation/aere.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/aere.valid",
"mutation": {
"producer": "the issuer issued the same claims with exp in the past, the holder presented them",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImFlcmUrc2Qtand0In0.eyJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiI3WnV4b0RhUEJDNnpRLUFoaUFqNEZxdl9MVFpFYVJhblVoVHFXZ2RWZ3FjIn0seyIuLi4iOiItakxQckhtUHkxc1FyRkJ1RHJabzhsYzVjRTdWNjJHQmpKbnFreVJiVEpRIn1dLCJhZGRyZXNzIjp7ImxvY2FsaXR5IjoiQ2x1aiIsImNvdW50cnkiOiJSTyJ9LCJfc2QiOlsiVng5Qk9ha0FGdy1HNXpRaTdQWFpPUEg0UU5sSjBUdzhyY01JRWRydUhNVSIsImFpT1EyMVNSWHJKaTJNbHBZdGZLY2J1Umxjd2ZJVWEyMTlaem9BWUFmNVEiLCJtZEZROTJ2bUF4LXcxUUNpUkxUc01zUmY3ZTY3VUhNZ1R2NXdFMWNnNkpzIiwib1RaQWo0QlBXU0ZQbUtSRzVmaGNrMGNod0d4Sy15eGxWRFhIN1UySkRzTSIsIndrbjI3Q0NFTVhPSVlDZkxNZUEwSXVsYTdlUlRRMXdGUlg0SmZsRy1QcmciXSwiX3NkX2FsZyI6InNoYS0yNTYiLCJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiaWF0IjoxNzkyMzAyNTUyLCJleHAiOjE3OTIzMDI1NTEsImNuZiI6eyJqd2siOnsiY3J2IjoiRWQyNTUxOSIsIngiOiJwZGd3WVJzOEtTdl9ESUJvaEFhaWx4MEoxS01xVGkyd2cwVGY3TmJaOFY0Iiwia3R5IjoiT0tQIn19fQ.SIhp6eXkMpF9dA3qjGuCWs2VMZWDeiZ0NUcGMUEX85bCqPvtqneJYLSqJWJ5Q58BqQVR0mLM7aYqsL7lD_yRBQ~WyJJYWlXZGtiUU14Q3BHYWRyUHZDcEpnIiwiYWdlX292ZXJfMTgiLHRydWVd~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE3OTIzMDI1NTIsImF1ZCI6Imh0dHBzOi8vdmVyaWZpZXIuZXhhbXBsZSIsIm5vbmNlIjoibi04NzlmYzQxN2UzMzFiYzgwIiwic2RfaGFzaCI6InhNdHNFdUxaWTRtY1RpMFpZaElUcnotd0VUV25DZ2t6N3p1ckVIUjgtcmcifQ.uV8nuxzewFxbS5zCIw9eqz_bi3qu-0t4ZAQU90shvQkiDE53LlglTR8zkaHHp--QoqcjlmlZmYwhvjyaIOciAQ",
"issuerKey": {
"crv": "Ed25519",
"x": "hca9rLOG6cMHfk2weCWFz7wily7iDR_Qvhhs6tTQGjA",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-879fc417e331bc80",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.time"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,68 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/aere.time-not-yet",
"artifact": "sdjwt-presentation",
"title": "the credential is not valid for another hour (nbf ahead of the clock by more than the skew)",
"source": "derived from sdjwt-presentation/aere.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/aere.valid",
"mutation": {
"producer": "the issuer issued the same claims with nbf an hour ahead, the holder presented them",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImFlcmUrc2Qtand0In0.eyJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJnREJuVktpRVp2X2wwTWdPUFhveU5XcGxyM0tPSlgwLVQ4S2ZmMDhMMlowIn0seyIuLi4iOiJVOUFxdVNWeE1mTjJpZUtLTnhxNkNDcXVwaEg3M0FMQ3pEMnY3V1F0QjdRIn1dLCJhZGRyZXNzIjp7ImxvY2FsaXR5IjoiQ2x1aiIsImNvdW50cnkiOiJSTyJ9LCJfc2QiOlsiMjlXbEZHeWFEWWJXVzNrZWlMaGYwTFlaQmQ2VGRXY25lWFhkRjk2RkdZOCIsIjYtOThWZy13N2N3aG5kX0lwa3A0YWNxZE5VazF0U3UtbGNrTTlEMVlteTQiLCJGckVnTllsYlc0S25FSzFmdzFhSmJNekJwZmZjTjVCbmlMTUl3SnB5Nlc0IiwiSlZmQVJLdGc5dnZmSGVzVEpDSXJXRW1MMkN4Vkg4QS1HbGJoZnU2aENHRSIsImU1ZE13bkdobnQwTmVFcWw0QlBCTXVCU09qLVl5SFdiSlc2TDhvdVF1VXMiXSwiX3NkX2FsZyI6InNoYS0yNTYiLCJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiaWF0IjoxNzkyMzAyNTUyLCJleHAiOjE4MjM4Mzg1NTIsIm5iZiI6MTc5MjMwNjE1MiwiY25mIjp7Imp3ayI6eyJjcnYiOiJFZDI1NTE5IiwieCI6InBkZ3dZUnM4S1N2X0RJQm9oQWFpbHgwSjFLTXFUaTJ3ZzBUZjdOYlo4VjQiLCJrdHkiOiJPS1AifX19.sy5GRqEhkvQAdNM_C9IMKBpsSF1Nbna1Pq6bR7gxmsBYkwR9_5VWgBW17OwKkhTKxGiS25nGMAIPXmyyqJ9qCQ~WyJiZ21OM0N5Rm1jclF6MzNMcjFBWU53IiwiYWdlX292ZXJfMTgiLHRydWVd~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE3OTIzMDI1NTIsImF1ZCI6Imh0dHBzOi8vdmVyaWZpZXIuZXhhbXBsZSIsIm5vbmNlIjoibi04NzlmYzQxN2UzMzFiYzgwIiwic2RfaGFzaCI6Im9KSDdQeVhnTzJFNVdQMmRGMy13SkNaVXY3UTVpVm9FUFY5MExqeF9fNncifQ.3Q1m2Pjpv2H5mES1aEZRu-Ckh_nrPwP2Bu6U6CVgFL5lMTDDbRoxN18nFcMf0bjAMBODvOAMlnfaXf9rsgMpAA",
"issuerKey": {
"crv": "Ed25519",
"x": "hca9rLOG6cMHfk2weCWFz7wily7iDR_Qvhhs6tTQGjA",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-879fc417e331bc80",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.time"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,68 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/aere.typ-kb",
"artifact": "sdjwt-presentation",
"title": "the key binding JWT is typed JWT, not kb+jwt",
"source": "derived from sdjwt-presentation/aere.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/aere.valid",
"mutation": {
"producer": "the holder signed the key binding JWT with typ JWT",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImFlcmUrc2Qtand0In0.eyJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJvR1ZLcV9iYUlSbkdjX0x6S2c3Rjd4R0M2OTdOLXJSWjdNbGJMdk9jMzlvIn0seyIuLi4iOiJYU1BvSVhtdkRMMHY4a3BTZ1NGZ3ZuTWZtcy0zTllLdmtYM0cxd2RCNmg4In1dLCJhZGRyZXNzIjp7ImxvY2FsaXR5IjoiQ2x1aiIsImNvdW50cnkiOiJSTyJ9LCJfc2QiOlsiMGl3bk5fZjRkSGhfcUI0SlhyX201OGdoWFNYRmk3LTk0SDR4QnpOdXBMSSIsIjM1QnNjekpxVEdFNEdWY0ZZa0tEMEY3R0wweUlUdlp5MVpSU0x2Y2tpdTAiLCIzWm5SQk9fMGFZbUZCQUl6Tl9QZmdNYVlacUVYdWNibkg1Y2E5RFNNTFdBIiwiYVptbDlYNUU5cDhxaVJvcExVeGtTeUpsXzgtemEzQVRnRWFEanhBQ2o0OCIsImpLSlJ6WS00NmR5cWFHMnliQkk4OUxuT0ZuQ0xRSl9Ddk5rWnlnOFVxQzAiXSwiX3NkX2FsZyI6InNoYS0yNTYiLCJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiaWF0IjoxNzkyMzAyNTUyLCJleHAiOjE4MjM4Mzg1NTIsImNuZiI6eyJqd2siOnsiY3J2IjoiRWQyNTUxOSIsIngiOiJwZGd3WVJzOEtTdl9ESUJvaEFhaWx4MEoxS01xVGkyd2cwVGY3TmJaOFY0Iiwia3R5IjoiT0tQIn19fQ.h75vV6jAkI1n0st_TUrGseDJKEk0RScfX5neSm_CSN2GoVjL2Ml2oKmB0szWDCjjlAcq1Tn1B39KNwEE1dWzBw~WyJSYTAyRkdCZDJmMW5HRlJPUFNUdURnIiwiYWdlX292ZXJfMTgiLHRydWVd~WyJZUVdma1BBSW1UTUpTU09vNmQ1WVJBIiwiUk8iXQ~eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3OTIzMDI1NTIsImF1ZCI6Imh0dHBzOi8vdmVyaWZpZXIuZXhhbXBsZSIsIm5vbmNlIjoibi04NzlmYzQxN2UzMzFiYzgwIiwic2RfaGFzaCI6IlBWY1dzVDZ1SVFhUHBRUUM1QUQyUzQ3Q3Z5QllpRTBxQ1RVZUtpd0ZfRlUifQ.M9nBOLw7TTvwyvSIN4MSiq_kXalf7oEVM9VjNC7ijyzRAQeLSj8PYCb6MQul6OzAL5WD6lHVbI9HemGpDnpODA",
"issuerKey": {
"crv": "Ed25519",
"x": "hca9rLOG6cMHfk2weCWFz7wily7iDR_Qvhhs6tTQGjA",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-879fc417e331bc80",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.typ"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,59 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/aere.valid",
"artifact": "sdjwt-presentation",
"title": "an SD-JWT issued with AERE keys (EdDSA): two of three disclosable claims and one list element shown, two decoy digests, a key binding JWT for this verifier",
"source": "producers (sdjwt.mjs: issueSdJwt, presentSdJwt), three hybrid key pairs made and discarded at generation",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": null,
"mutation": null,
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImFlcmUrc2Qtand0In0.eyJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJvR1ZLcV9iYUlSbkdjX0x6S2c3Rjd4R0M2OTdOLXJSWjdNbGJMdk9jMzlvIn0seyIuLi4iOiJYU1BvSVhtdkRMMHY4a3BTZ1NGZ3ZuTWZtcy0zTllLdmtYM0cxd2RCNmg4In1dLCJhZGRyZXNzIjp7ImxvY2FsaXR5IjoiQ2x1aiIsImNvdW50cnkiOiJSTyJ9LCJfc2QiOlsiMGl3bk5fZjRkSGhfcUI0SlhyX201OGdoWFNYRmk3LTk0SDR4QnpOdXBMSSIsIjM1QnNjekpxVEdFNEdWY0ZZa0tEMEY3R0wweUlUdlp5MVpSU0x2Y2tpdTAiLCIzWm5SQk9fMGFZbUZCQUl6Tl9QZmdNYVlacUVYdWNibkg1Y2E5RFNNTFdBIiwiYVptbDlYNUU5cDhxaVJvcExVeGtTeUpsXzgtemEzQVRnRWFEanhBQ2o0OCIsImpLSlJ6WS00NmR5cWFHMnliQkk4OUxuT0ZuQ0xRSl9Ddk5rWnlnOFVxQzAiXSwiX3NkX2FsZyI6InNoYS0yNTYiLCJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiaWF0IjoxNzkyMzAyNTUyLCJleHAiOjE4MjM4Mzg1NTIsImNuZiI6eyJqd2siOnsiY3J2IjoiRWQyNTUxOSIsIngiOiJwZGd3WVJzOEtTdl9ESUJvaEFhaWx4MEoxS01xVGkyd2cwVGY3TmJaOFY0Iiwia3R5IjoiT0tQIn19fQ.h75vV6jAkI1n0st_TUrGseDJKEk0RScfX5neSm_CSN2GoVjL2Ml2oKmB0szWDCjjlAcq1Tn1B39KNwEE1dWzBw~WyJSYTAyRkdCZDJmMW5HRlJPUFNUdURnIiwiYWdlX292ZXJfMTgiLHRydWVd~WyJZUVdma1BBSW1UTUpTU09vNmQ1WVJBIiwiUk8iXQ~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE3OTIzMDI1NTIsImF1ZCI6Imh0dHBzOi8vdmVyaWZpZXIuZXhhbXBsZSIsIm5vbmNlIjoibi04NzlmYzQxN2UzMzFiYzgwIiwic2RfaGFzaCI6IlBWY1dzVDZ1SVFhUHBRUUM1QUQyUzQ3Q3Z5QllpRTBxQ1RVZUtpd0ZfRlUifQ.i8LKIVBV7X67veBsk-vyyCHouKBFEXP5uLl927e3m3-_JE1hOHuyv0KX2gioAO81kI1FY1TV6xHOiQVF-UyBBg",
"issuerKey": {
"crv": "Ed25519",
"x": "hca9rLOG6cMHfk2weCWFz7wily7iDR_Qvhhs6tTQGjA",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-879fc417e331bc80",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example"
},
"expected": {
"verdict": "VALID",
"failed": [],
"levels": {
"integrity": "PASSED",
"authenticity": "PASSED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,66 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/rfc9901-issued.disclosure-twice",
"artifact": "sdjwt-presentation",
"title": "the same disclosure given twice",
"source": "derived from sdjwt-presentation/rfc9901-issued.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/rfc9901-issued.valid",
"mutation": {
"op": "set",
"path": [
"sdJwt"
],
"value": "eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBbIkNyUWU3UzVrcUJBSHQtbk1ZWGdjNmJkdDJTSDVhVFkxc1VfTS1QZ2tqUEkiLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVadTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFVQTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAiWFFfM2tQS3QxWHlYN0tBTmtxVlI2eVoyVmE1TnJQSXZQWWJ5TXZSS0JNTSIsICJYekZyendzY002R242Q0pEYzZ2Vks4QmtNbmZHOHZPU0tmcFBJWmRBZmRFIiwgImdiT3NJNEVkcTJ4Mkt3LXc1d1BFemFrb2I5aFYxY1JEMEFUTjNvUUw5Sk0iLCAianN1OXlWdWx3UVFsaEZsTV8zSmx6TWFTRnpnbGhRRzBEcGZheVF3TFVLNCJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwgImlhdCI6IDE2ODMwMDAwMDAsICJleHAiOiAxODgzMDAwMDAwLCAic3ViIjogInVzZXJfNDIiLCAibmF0aW9uYWxpdGllcyI6IFt7Ii4uLiI6ICJwRm5kamtaX1ZDem15VGE2VWpsWm8zZGgta284YUlLUWM5RGxHemhhVllvIn0sIHsiLi4uIjogIjdDZjZKa1B1ZHJ5M2xjYndIZ2VaOGtoQXYxVTFPU2xlclAwVmtCSnJXWjAifV0sICJfc2RfYWxnIjogInNoYS0yNTYiLCAiY25mIjogeyJqd2siOiB7Imt0eSI6ICJFQyIsICJjcnYiOiAiUC0yNTYiLCAieCI6ICJUQ0FFUjE5WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwgInkiOiAiWnhqaVdXYlpNUUdIVldLVlE0aGJTSWlyc1ZmdWVjQ0U2dDRqVDlGMkhaUSJ9fX0.MczwjBFGtzf-6WMT-hIvYbkb11NrV1WMO-jTijpMPNbswNzZ87wY2uHz-CXo6R04b7jYrpj9mNRAvVssXou1iw~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImdpdmVuX25hbWUiLCAiSm9obiJd~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImdpdmVuX25hbWUiLCAiSm9obiJd~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd~WyI2SWo3dE0tYTVpVlBHYm9TNXRtdlZBIiwgImVtYWlsIiwgImpvaG5kb2VAZXhhbXBsZS5jb20iXQ~WyJlSThaV205UW5LUHBOUGVOZW5IZGhRIiwgInBob25lX251bWJlciIsICIrMS0yMDItNTU1LTAxMDEiXQ~WyJRZ19PNjR6cUF4ZTQxMmExMDhpcm9BIiwgInBob25lX251bWJlcl92ZXJpZmllZCIsIHRydWVd~WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCAicmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0~WyJQYzMzSk0yTGNoY1VfbEhnZ3ZfdWZRIiwgImJpcnRoZGF0ZSIsICIxOTQwLTAxLTAxIl0~WyJHMDJOU3JRZmpGWFE3SW8wOXN5YWpBIiwgInVwZGF0ZWRfYXQiLCAxNTcwMDAwMDAwXQ~WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgIlVTIl0~WyJuUHVvUW5rUkZxM0JJZUFtN0FuWEZBIiwgIkRFIl0~"
},
"input": {
"sdJwt": "eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBbIkNyUWU3UzVrcUJBSHQtbk1ZWGdjNmJkdDJTSDVhVFkxc1VfTS1QZ2tqUEkiLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVadTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFVQTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAiWFFfM2tQS3QxWHlYN0tBTmtxVlI2eVoyVmE1TnJQSXZQWWJ5TXZSS0JNTSIsICJYekZyendzY002R242Q0pEYzZ2Vks4QmtNbmZHOHZPU0tmcFBJWmRBZmRFIiwgImdiT3NJNEVkcTJ4Mkt3LXc1d1BFemFrb2I5aFYxY1JEMEFUTjNvUUw5Sk0iLCAianN1OXlWdWx3UVFsaEZsTV8zSmx6TWFTRnpnbGhRRzBEcGZheVF3TFVLNCJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwgImlhdCI6IDE2ODMwMDAwMDAsICJleHAiOiAxODgzMDAwMDAwLCAic3ViIjogInVzZXJfNDIiLCAibmF0aW9uYWxpdGllcyI6IFt7Ii4uLiI6ICJwRm5kamtaX1ZDem15VGE2VWpsWm8zZGgta284YUlLUWM5RGxHemhhVllvIn0sIHsiLi4uIjogIjdDZjZKa1B1ZHJ5M2xjYndIZ2VaOGtoQXYxVTFPU2xlclAwVmtCSnJXWjAifV0sICJfc2RfYWxnIjogInNoYS0yNTYiLCAiY25mIjogeyJqd2siOiB7Imt0eSI6ICJFQyIsICJjcnYiOiAiUC0yNTYiLCAieCI6ICJUQ0FFUjE5WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwgInkiOiAiWnhqaVdXYlpNUUdIVldLVlE0aGJTSWlyc1ZmdWVjQ0U2dDRqVDlGMkhaUSJ9fX0.MczwjBFGtzf-6WMT-hIvYbkb11NrV1WMO-jTijpMPNbswNzZ87wY2uHz-CXo6R04b7jYrpj9mNRAvVssXou1iw~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImdpdmVuX25hbWUiLCAiSm9obiJd~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImdpdmVuX25hbWUiLCAiSm9obiJd~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd~WyI2SWo3dE0tYTVpVlBHYm9TNXRtdlZBIiwgImVtYWlsIiwgImpvaG5kb2VAZXhhbXBsZS5jb20iXQ~WyJlSThaV205UW5LUHBOUGVOZW5IZGhRIiwgInBob25lX251bWJlciIsICIrMS0yMDItNTU1LTAxMDEiXQ~WyJRZ19PNjR6cUF4ZTQxMmExMDhpcm9BIiwgInBob25lX251bWJlcl92ZXJpZmllZCIsIHRydWVd~WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCAicmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0~WyJQYzMzSk0yTGNoY1VfbEhnZ3ZfdWZRIiwgImJpcnRoZGF0ZSIsICIxOTQwLTAxLTAxIl0~WyJHMDJOU3JRZmpGWFE3SW8wOXN5YWpBIiwgInVwZGF0ZWRfYXQiLCAxNTcwMDAwMDAwXQ~WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgIlVTIl0~WyJuUHVvUW5rUkZxM0JJZUFtN0FuWEZBIiwgIkRFIl0~",
"issuerKey": {
"kty": "EC",
"crv": "P-256",
"x": "b28d4MwZMjw8-00CG4xfnn9SLMVMM19SlqZpVb_uNtQ",
"y": "Xv5zWwuoaTgdS6hV43yI6gBwTnjukmFQQnJ_kCxzqk8"
},
"issuerAlg": "ES256",
"now": "2025-05-29T16:47:24.000Z",
"requireKeyBinding": false
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.disclosure-twice"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,66 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/rfc9901-issued.form-empty",
"artifact": "sdjwt-presentation",
"title": "an empty disclosure between two ~",
"source": "derived from sdjwt-presentation/rfc9901-issued.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/rfc9901-issued.valid",
"mutation": {
"op": "set",
"path": [
"sdJwt"
],
"value": "eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBbIkNyUWU3UzVrcUJBSHQtbk1ZWGdjNmJkdDJTSDVhVFkxc1VfTS1QZ2tqUEkiLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVadTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFVQTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAiWFFfM2tQS3QxWHlYN0tBTmtxVlI2eVoyVmE1TnJQSXZQWWJ5TXZSS0JNTSIsICJYekZyendzY002R242Q0pEYzZ2Vks4QmtNbmZHOHZPU0tmcFBJWmRBZmRFIiwgImdiT3NJNEVkcTJ4Mkt3LXc1d1BFemFrb2I5aFYxY1JEMEFUTjNvUUw5Sk0iLCAianN1OXlWdWx3UVFsaEZsTV8zSmx6TWFTRnpnbGhRRzBEcGZheVF3TFVLNCJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwgImlhdCI6IDE2ODMwMDAwMDAsICJleHAiOiAxODgzMDAwMDAwLCAic3ViIjogInVzZXJfNDIiLCAibmF0aW9uYWxpdGllcyI6IFt7Ii4uLiI6ICJwRm5kamtaX1ZDem15VGE2VWpsWm8zZGgta284YUlLUWM5RGxHemhhVllvIn0sIHsiLi4uIjogIjdDZjZKa1B1ZHJ5M2xjYndIZ2VaOGtoQXYxVTFPU2xlclAwVmtCSnJXWjAifV0sICJfc2RfYWxnIjogInNoYS0yNTYiLCAiY25mIjogeyJqd2siOiB7Imt0eSI6ICJFQyIsICJjcnYiOiAiUC0yNTYiLCAieCI6ICJUQ0FFUjE5WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwgInkiOiAiWnhqaVdXYlpNUUdIVldLVlE0aGJTSWlyc1ZmdWVjQ0U2dDRqVDlGMkhaUSJ9fX0.MczwjBFGtzf-6WMT-hIvYbkb11NrV1WMO-jTijpMPNbswNzZ87wY2uHz-CXo6R04b7jYrpj9mNRAvVssXou1iw~~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImdpdmVuX25hbWUiLCAiSm9obiJd~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd~WyI2SWo3dE0tYTVpVlBHYm9TNXRtdlZBIiwgImVtYWlsIiwgImpvaG5kb2VAZXhhbXBsZS5jb20iXQ~WyJlSThaV205UW5LUHBOUGVOZW5IZGhRIiwgInBob25lX251bWJlciIsICIrMS0yMDItNTU1LTAxMDEiXQ~WyJRZ19PNjR6cUF4ZTQxMmExMDhpcm9BIiwgInBob25lX251bWJlcl92ZXJpZmllZCIsIHRydWVd~WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCAicmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0~WyJQYzMzSk0yTGNoY1VfbEhnZ3ZfdWZRIiwgImJpcnRoZGF0ZSIsICIxOTQwLTAxLTAxIl0~WyJHMDJOU3JRZmpGWFE3SW8wOXN5YWpBIiwgInVwZGF0ZWRfYXQiLCAxNTcwMDAwMDAwXQ~WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgIlVTIl0~WyJuUHVvUW5rUkZxM0JJZUFtN0FuWEZBIiwgIkRFIl0~"
},
"input": {
"sdJwt": "eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBbIkNyUWU3UzVrcUJBSHQtbk1ZWGdjNmJkdDJTSDVhVFkxc1VfTS1QZ2tqUEkiLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVadTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFVQTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAiWFFfM2tQS3QxWHlYN0tBTmtxVlI2eVoyVmE1TnJQSXZQWWJ5TXZSS0JNTSIsICJYekZyendzY002R242Q0pEYzZ2Vks4QmtNbmZHOHZPU0tmcFBJWmRBZmRFIiwgImdiT3NJNEVkcTJ4Mkt3LXc1d1BFemFrb2I5aFYxY1JEMEFUTjNvUUw5Sk0iLCAianN1OXlWdWx3UVFsaEZsTV8zSmx6TWFTRnpnbGhRRzBEcGZheVF3TFVLNCJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwgImlhdCI6IDE2ODMwMDAwMDAsICJleHAiOiAxODgzMDAwMDAwLCAic3ViIjogInVzZXJfNDIiLCAibmF0aW9uYWxpdGllcyI6IFt7Ii4uLiI6ICJwRm5kamtaX1ZDem15VGE2VWpsWm8zZGgta284YUlLUWM5RGxHemhhVllvIn0sIHsiLi4uIjogIjdDZjZKa1B1ZHJ5M2xjYndIZ2VaOGtoQXYxVTFPU2xlclAwVmtCSnJXWjAifV0sICJfc2RfYWxnIjogInNoYS0yNTYiLCAiY25mIjogeyJqd2siOiB7Imt0eSI6ICJFQyIsICJjcnYiOiAiUC0yNTYiLCAieCI6ICJUQ0FFUjE5WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwgInkiOiAiWnhqaVdXYlpNUUdIVldLVlE0aGJTSWlyc1ZmdWVjQ0U2dDRqVDlGMkhaUSJ9fX0.MczwjBFGtzf-6WMT-hIvYbkb11NrV1WMO-jTijpMPNbswNzZ87wY2uHz-CXo6R04b7jYrpj9mNRAvVssXou1iw~~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImdpdmVuX25hbWUiLCAiSm9obiJd~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd~WyI2SWo3dE0tYTVpVlBHYm9TNXRtdlZBIiwgImVtYWlsIiwgImpvaG5kb2VAZXhhbXBsZS5jb20iXQ~WyJlSThaV205UW5LUHBOUGVOZW5IZGhRIiwgInBob25lX251bWJlciIsICIrMS0yMDItNTU1LTAxMDEiXQ~WyJRZ19PNjR6cUF4ZTQxMmExMDhpcm9BIiwgInBob25lX251bWJlcl92ZXJpZmllZCIsIHRydWVd~WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCAicmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0~WyJQYzMzSk0yTGNoY1VfbEhnZ3ZfdWZRIiwgImJpcnRoZGF0ZSIsICIxOTQwLTAxLTAxIl0~WyJHMDJOU3JRZmpGWFE3SW8wOXN5YWpBIiwgInVwZGF0ZWRfYXQiLCAxNTcwMDAwMDAwXQ~WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgIlVTIl0~WyJuUHVvUW5rUkZxM0JJZUFtN0FuWEZBIiwgIkRFIl0~",
"issuerKey": {
"kty": "EC",
"crv": "P-256",
"x": "b28d4MwZMjw8-00CG4xfnn9SLMVMM19SlqZpVb_uNtQ",
"y": "Xv5zWwuoaTgdS6hV43yI6gBwTnjukmFQQnJ_kCxzqk8"
},
"issuerAlg": "ES256",
"now": "2025-05-29T16:47:24.000Z",
"requireKeyBinding": false
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.form"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,66 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/rfc9901-issued.unreferenced",
"artifact": "sdjwt-presentation",
"title": "the value of the first disclosure changed: its digest is in no _sd",
"source": "derived from sdjwt-presentation/rfc9901-issued.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/rfc9901-issued.valid",
"mutation": {
"op": "set",
"path": [
"sdJwt"
],
"value": "eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBbIkNyUWU3UzVrcUJBSHQtbk1ZWGdjNmJkdDJTSDVhVFkxc1VfTS1QZ2tqUEkiLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVadTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFVQTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAiWFFfM2tQS3QxWHlYN0tBTmtxVlI2eVoyVmE1TnJQSXZQWWJ5TXZSS0JNTSIsICJYekZyendzY002R242Q0pEYzZ2Vks4QmtNbmZHOHZPU0tmcFBJWmRBZmRFIiwgImdiT3NJNEVkcTJ4Mkt3LXc1d1BFemFrb2I5aFYxY1JEMEFUTjNvUUw5Sk0iLCAianN1OXlWdWx3UVFsaEZsTV8zSmx6TWFTRnpnbGhRRzBEcGZheVF3TFVLNCJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwgImlhdCI6IDE2ODMwMDAwMDAsICJleHAiOiAxODgzMDAwMDAwLCAic3ViIjogInVzZXJfNDIiLCAibmF0aW9uYWxpdGllcyI6IFt7Ii4uLiI6ICJwRm5kamtaX1ZDem15VGE2VWpsWm8zZGgta284YUlLUWM5RGxHemhhVllvIn0sIHsiLi4uIjogIjdDZjZKa1B1ZHJ5M2xjYndIZ2VaOGtoQXYxVTFPU2xlclAwVmtCSnJXWjAifV0sICJfc2RfYWxnIjogInNoYS0yNTYiLCAiY25mIjogeyJqd2siOiB7Imt0eSI6ICJFQyIsICJjcnYiOiAiUC0yNTYiLCAieCI6ICJUQ0FFUjE5WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwgInkiOiAiWnhqaVdXYlpNUUdIVldLVlE0aGJTSWlyc1ZmdWVjQ0U2dDRqVDlGMkhaUSJ9fX0.MczwjBFGtzf-6WMT-hIvYbkb11NrV1WMO-jTijpMPNbswNzZ87wY2uHz-CXo6R04b7jYrpj9mNRAvVssXou1iw~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwiZ2l2ZW5fbmFtZSIsIkpvaG54Il0~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd~WyI2SWo3dE0tYTVpVlBHYm9TNXRtdlZBIiwgImVtYWlsIiwgImpvaG5kb2VAZXhhbXBsZS5jb20iXQ~WyJlSThaV205UW5LUHBOUGVOZW5IZGhRIiwgInBob25lX251bWJlciIsICIrMS0yMDItNTU1LTAxMDEiXQ~WyJRZ19PNjR6cUF4ZTQxMmExMDhpcm9BIiwgInBob25lX251bWJlcl92ZXJpZmllZCIsIHRydWVd~WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCAicmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0~WyJQYzMzSk0yTGNoY1VfbEhnZ3ZfdWZRIiwgImJpcnRoZGF0ZSIsICIxOTQwLTAxLTAxIl0~WyJHMDJOU3JRZmpGWFE3SW8wOXN5YWpBIiwgInVwZGF0ZWRfYXQiLCAxNTcwMDAwMDAwXQ~WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgIlVTIl0~WyJuUHVvUW5rUkZxM0JJZUFtN0FuWEZBIiwgIkRFIl0~"
},
"input": {
"sdJwt": "eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBbIkNyUWU3UzVrcUJBSHQtbk1ZWGdjNmJkdDJTSDVhVFkxc1VfTS1QZ2tqUEkiLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVadTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFVQTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAiWFFfM2tQS3QxWHlYN0tBTmtxVlI2eVoyVmE1TnJQSXZQWWJ5TXZSS0JNTSIsICJYekZyendzY002R242Q0pEYzZ2Vks4QmtNbmZHOHZPU0tmcFBJWmRBZmRFIiwgImdiT3NJNEVkcTJ4Mkt3LXc1d1BFemFrb2I5aFYxY1JEMEFUTjNvUUw5Sk0iLCAianN1OXlWdWx3UVFsaEZsTV8zSmx6TWFTRnpnbGhRRzBEcGZheVF3TFVLNCJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwgImlhdCI6IDE2ODMwMDAwMDAsICJleHAiOiAxODgzMDAwMDAwLCAic3ViIjogInVzZXJfNDIiLCAibmF0aW9uYWxpdGllcyI6IFt7Ii4uLiI6ICJwRm5kamtaX1ZDem15VGE2VWpsWm8zZGgta284YUlLUWM5RGxHemhhVllvIn0sIHsiLi4uIjogIjdDZjZKa1B1ZHJ5M2xjYndIZ2VaOGtoQXYxVTFPU2xlclAwVmtCSnJXWjAifV0sICJfc2RfYWxnIjogInNoYS0yNTYiLCAiY25mIjogeyJqd2siOiB7Imt0eSI6ICJFQyIsICJjcnYiOiAiUC0yNTYiLCAieCI6ICJUQ0FFUjE5WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwgInkiOiAiWnhqaVdXYlpNUUdIVldLVlE0aGJTSWlyc1ZmdWVjQ0U2dDRqVDlGMkhaUSJ9fX0.MczwjBFGtzf-6WMT-hIvYbkb11NrV1WMO-jTijpMPNbswNzZ87wY2uHz-CXo6R04b7jYrpj9mNRAvVssXou1iw~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwiZ2l2ZW5fbmFtZSIsIkpvaG54Il0~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd~WyI2SWo3dE0tYTVpVlBHYm9TNXRtdlZBIiwgImVtYWlsIiwgImpvaG5kb2VAZXhhbXBsZS5jb20iXQ~WyJlSThaV205UW5LUHBOUGVOZW5IZGhRIiwgInBob25lX251bWJlciIsICIrMS0yMDItNTU1LTAxMDEiXQ~WyJRZ19PNjR6cUF4ZTQxMmExMDhpcm9BIiwgInBob25lX251bWJlcl92ZXJpZmllZCIsIHRydWVd~WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCAicmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0~WyJQYzMzSk0yTGNoY1VfbEhnZ3ZfdWZRIiwgImJpcnRoZGF0ZSIsICIxOTQwLTAxLTAxIl0~WyJHMDJOU3JRZmpGWFE3SW8wOXN5YWpBIiwgInVwZGF0ZWRfYXQiLCAxNTcwMDAwMDAwXQ~WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgIlVTIl0~WyJuUHVvUW5rUkZxM0JJZUFtN0FuWEZBIiwgIkRFIl0~",
"issuerKey": {
"kty": "EC",
"crv": "P-256",
"x": "b28d4MwZMjw8-00CG4xfnn9SLMVMM19SlqZpVb_uNtQ",
"y": "Xv5zWwuoaTgdS6hV43yI6gBwTnjukmFQQnJ_kCxzqk8"
},
"issuerAlg": "ES256",
"now": "2025-05-29T16:47:24.000Z",
"requireKeyBinding": false
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.unreferenced"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,58 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/rfc9901-issued.valid",
"artifact": "sdjwt-presentation",
"title": "the SD-JWT of RFC 9901 Section 5.1 as issued, every disclosure, no key binding (the verifier does not require one)",
"source": "IETF RFC 9901 Section 5 and Appendix A.5 (code components, Revised BSD License), via fixturi-rfc9901.json of the identity component",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": null,
"mutation": null,
"input": {
"sdJwt": "eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBbIkNyUWU3UzVrcUJBSHQtbk1ZWGdjNmJkdDJTSDVhVFkxc1VfTS1QZ2tqUEkiLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVadTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFVQTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAiWFFfM2tQS3QxWHlYN0tBTmtxVlI2eVoyVmE1TnJQSXZQWWJ5TXZSS0JNTSIsICJYekZyendzY002R242Q0pEYzZ2Vks4QmtNbmZHOHZPU0tmcFBJWmRBZmRFIiwgImdiT3NJNEVkcTJ4Mkt3LXc1d1BFemFrb2I5aFYxY1JEMEFUTjNvUUw5Sk0iLCAianN1OXlWdWx3UVFsaEZsTV8zSmx6TWFTRnpnbGhRRzBEcGZheVF3TFVLNCJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwgImlhdCI6IDE2ODMwMDAwMDAsICJleHAiOiAxODgzMDAwMDAwLCAic3ViIjogInVzZXJfNDIiLCAibmF0aW9uYWxpdGllcyI6IFt7Ii4uLiI6ICJwRm5kamtaX1ZDem15VGE2VWpsWm8zZGgta284YUlLUWM5RGxHemhhVllvIn0sIHsiLi4uIjogIjdDZjZKa1B1ZHJ5M2xjYndIZ2VaOGtoQXYxVTFPU2xlclAwVmtCSnJXWjAifV0sICJfc2RfYWxnIjogInNoYS0yNTYiLCAiY25mIjogeyJqd2siOiB7Imt0eSI6ICJFQyIsICJjcnYiOiAiUC0yNTYiLCAieCI6ICJUQ0FFUjE5WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwgInkiOiAiWnhqaVdXYlpNUUdIVldLVlE0aGJTSWlyc1ZmdWVjQ0U2dDRqVDlGMkhaUSJ9fX0.MczwjBFGtzf-6WMT-hIvYbkb11NrV1WMO-jTijpMPNbswNzZ87wY2uHz-CXo6R04b7jYrpj9mNRAvVssXou1iw~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImdpdmVuX25hbWUiLCAiSm9obiJd~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd~WyI2SWo3dE0tYTVpVlBHYm9TNXRtdlZBIiwgImVtYWlsIiwgImpvaG5kb2VAZXhhbXBsZS5jb20iXQ~WyJlSThaV205UW5LUHBOUGVOZW5IZGhRIiwgInBob25lX251bWJlciIsICIrMS0yMDItNTU1LTAxMDEiXQ~WyJRZ19PNjR6cUF4ZTQxMmExMDhpcm9BIiwgInBob25lX251bWJlcl92ZXJpZmllZCIsIHRydWVd~WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCAicmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0~WyJQYzMzSk0yTGNoY1VfbEhnZ3ZfdWZRIiwgImJpcnRoZGF0ZSIsICIxOTQwLTAxLTAxIl0~WyJHMDJOU3JRZmpGWFE3SW8wOXN5YWpBIiwgInVwZGF0ZWRfYXQiLCAxNTcwMDAwMDAwXQ~WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgIlVTIl0~WyJuUHVvUW5rUkZxM0JJZUFtN0FuWEZBIiwgIkRFIl0~",
"issuerKey": {
"kty": "EC",
"crv": "P-256",
"x": "b28d4MwZMjw8-00CG4xfnn9SLMVMM19SlqZpVb_uNtQ",
"y": "Xv5zWwuoaTgdS6hV43yI6gBwTnjukmFQQnJ_kCxzqk8"
},
"issuerAlg": "ES256",
"now": "2025-05-29T16:47:24.000Z",
"requireKeyBinding": false
},
"expected": {
"verdict": "VALID",
"failed": [],
"levels": {
"integrity": "PASSED",
"authenticity": "PASSED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,67 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/rfc9901.form-clock",
"artifact": "sdjwt-presentation",
"title": "the verifier clock is not a time",
"source": "derived from sdjwt-presentation/rfc9901.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/rfc9901.valid",
"mutation": {
"op": "set",
"path": [
"now"
],
"value": "yesterday"
},
"input": {
"sdJwt": "eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBbIkNyUWU3UzVrcUJBSHQtbk1ZWGdjNmJkdDJTSDVhVFkxc1VfTS1QZ2tqUEkiLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVadTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFVQTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAiWFFfM2tQS3QxWHlYN0tBTmtxVlI2eVoyVmE1TnJQSXZQWWJ5TXZSS0JNTSIsICJYekZyendzY002R242Q0pEYzZ2Vks4QmtNbmZHOHZPU0tmcFBJWmRBZmRFIiwgImdiT3NJNEVkcTJ4Mkt3LXc1d1BFemFrb2I5aFYxY1JEMEFUTjNvUUw5Sk0iLCAianN1OXlWdWx3UVFsaEZsTV8zSmx6TWFTRnpnbGhRRzBEcGZheVF3TFVLNCJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwgImlhdCI6IDE2ODMwMDAwMDAsICJleHAiOiAxODgzMDAwMDAwLCAic3ViIjogInVzZXJfNDIiLCAibmF0aW9uYWxpdGllcyI6IFt7Ii4uLiI6ICJwRm5kamtaX1ZDem15VGE2VWpsWm8zZGgta284YUlLUWM5RGxHemhhVllvIn0sIHsiLi4uIjogIjdDZjZKa1B1ZHJ5M2xjYndIZ2VaOGtoQXYxVTFPU2xlclAwVmtCSnJXWjAifV0sICJfc2RfYWxnIjogInNoYS0yNTYiLCAiY25mIjogeyJqd2siOiB7Imt0eSI6ICJFQyIsICJjcnYiOiAiUC0yNTYiLCAieCI6ICJUQ0FFUjE5WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwgInkiOiAiWnhqaVdXYlpNUUdIVldLVlE0aGJTSWlyc1ZmdWVjQ0U2dDRqVDlGMkhaUSJ9fX0.MczwjBFGtzf-6WMT-hIvYbkb11NrV1WMO-jTijpMPNbswNzZ87wY2uHz-CXo6R04b7jYrpj9mNRAvVssXou1iw~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd~WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCAicmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImdpdmVuX25hbWUiLCAiSm9obiJd~WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgIlVTIl0~eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImtiK2p3dCJ9.eyJub25jZSI6ICIxMjM0NTY3ODkwIiwgImF1ZCI6ICJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUub3JnIiwgImlhdCI6IDE3NDg1MzcyNDQsICJzZF9oYXNoIjogIjBfQWYtMkItRWhMV1g1eWRoX3cyeHp3bU82aU02NkJfMlFDRWFuSTRmVVkifQ.T3SIus2OidNl41nmVkTZVCKKhOAX97aOldMyHFiYjHm261eLiJ1YiuONFiMN8QlCmYzDlBLAdPvrXh52KaLgUQ",
"issuerKey": {
"kty": "EC",
"crv": "P-256",
"x": "b28d4MwZMjw8-00CG4xfnn9SLMVMM19SlqZpVb_uNtQ",
"y": "Xv5zWwuoaTgdS6hV43yI6gBwTnjukmFQQnJ_kCxzqk8"
},
"issuerAlg": "ES256",
"audience": "https://verifier.example.org",
"nonce": "1234567890",
"now": "yesterday"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.form"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,67 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/rfc9901.form",
"artifact": "sdjwt-presentation",
"title": "the token has no ~ at all (not an SD-JWT)",
"source": "derived from sdjwt-presentation/rfc9901.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/rfc9901.valid",
"mutation": {
"op": "set",
"path": [
"sdJwt"
],
"value": "eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBbIkNyUWU3UzVrcUJBSHQtbk1ZWGdjNmJkdDJTSDVhVFkxc1VfTS1QZ2tqUEkiLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVadTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFVQTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAiWFFfM2tQS3QxWHlYN0tBTmtxVlI2eVoyVmE1TnJQSXZQWWJ5TXZSS0JNTSIsICJYekZyendzY002R242Q0pEYzZ2Vks4QmtNbmZHOHZPU0tmcFBJWmRBZmRFIiwgImdiT3NJNEVkcTJ4Mkt3LXc1d1BFemFrb2I5aFYxY1JEMEFUTjNvUUw5Sk0iLCAianN1OXlWdWx3UVFsaEZsTV8zSmx6TWFTRnpnbGhRRzBEcGZheVF3TFVLNCJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwgImlhdCI6IDE2ODMwMDAwMDAsICJleHAiOiAxODgzMDAwMDAwLCAic3ViIjogInVzZXJfNDIiLCAibmF0aW9uYWxpdGllcyI6IFt7Ii4uLiI6ICJwRm5kamtaX1ZDem15VGE2VWpsWm8zZGgta284YUlLUWM5RGxHemhhVllvIn0sIHsiLi4uIjogIjdDZjZKa1B1ZHJ5M2xjYndIZ2VaOGtoQXYxVTFPU2xlclAwVmtCSnJXWjAifV0sICJfc2RfYWxnIjogInNoYS0yNTYiLCAiY25mIjogeyJqd2siOiB7Imt0eSI6ICJFQyIsICJjcnYiOiAiUC0yNTYiLCAieCI6ICJUQ0FFUjE5WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwgInkiOiAiWnhqaVdXYlpNUUdIVldLVlE0aGJTSWlyc1ZmdWVjQ0U2dDRqVDlGMkhaUSJ9fX0.MczwjBFGtzf-6WMT-hIvYbkb11NrV1WMO-jTijpMPNbswNzZ87wY2uHz-CXo6R04b7jYrpj9mNRAvVssXou1iw"
},
"input": {
"sdJwt": "eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBbIkNyUWU3UzVrcUJBSHQtbk1ZWGdjNmJkdDJTSDVhVFkxc1VfTS1QZ2tqUEkiLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVadTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFVQTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAiWFFfM2tQS3QxWHlYN0tBTmtxVlI2eVoyVmE1TnJQSXZQWWJ5TXZSS0JNTSIsICJYekZyendzY002R242Q0pEYzZ2Vks4QmtNbmZHOHZPU0tmcFBJWmRBZmRFIiwgImdiT3NJNEVkcTJ4Mkt3LXc1d1BFemFrb2I5aFYxY1JEMEFUTjNvUUw5Sk0iLCAianN1OXlWdWx3UVFsaEZsTV8zSmx6TWFTRnpnbGhRRzBEcGZheVF3TFVLNCJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwgImlhdCI6IDE2ODMwMDAwMDAsICJleHAiOiAxODgzMDAwMDAwLCAic3ViIjogInVzZXJfNDIiLCAibmF0aW9uYWxpdGllcyI6IFt7Ii4uLiI6ICJwRm5kamtaX1ZDem15VGE2VWpsWm8zZGgta284YUlLUWM5RGxHemhhVllvIn0sIHsiLi4uIjogIjdDZjZKa1B1ZHJ5M2xjYndIZ2VaOGtoQXYxVTFPU2xlclAwVmtCSnJXWjAifV0sICJfc2RfYWxnIjogInNoYS0yNTYiLCAiY25mIjogeyJqd2siOiB7Imt0eSI6ICJFQyIsICJjcnYiOiAiUC0yNTYiLCAieCI6ICJUQ0FFUjE5WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwgInkiOiAiWnhqaVdXYlpNUUdIVldLVlE0aGJTSWlyc1ZmdWVjQ0U2dDRqVDlGMkhaUSJ9fX0.MczwjBFGtzf-6WMT-hIvYbkb11NrV1WMO-jTijpMPNbswNzZ87wY2uHz-CXo6R04b7jYrpj9mNRAvVssXou1iw",
"issuerKey": {
"kty": "EC",
"crv": "P-256",
"x": "b28d4MwZMjw8-00CG4xfnn9SLMVMM19SlqZpVb_uNtQ",
"y": "Xv5zWwuoaTgdS6hV43yI6gBwTnjukmFQQnJ_kCxzqk8"
},
"issuerAlg": "ES256",
"audience": "https://verifier.example.org",
"nonce": "1234567890",
"now": "2025-05-29T16:47:24.000Z"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.form"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,68 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/rfc9901.issuer",
"artifact": "sdjwt-presentation",
"title": "the verifier expects another issuer",
"source": "derived from sdjwt-presentation/rfc9901.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/rfc9901.valid",
"mutation": {
"op": "add",
"path": [
"expectedIssuer"
],
"value": "https://other-issuer.example"
},
"input": {
"sdJwt": "eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBbIkNyUWU3UzVrcUJBSHQtbk1ZWGdjNmJkdDJTSDVhVFkxc1VfTS1QZ2tqUEkiLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVadTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFVQTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAiWFFfM2tQS3QxWHlYN0tBTmtxVlI2eVoyVmE1TnJQSXZQWWJ5TXZSS0JNTSIsICJYekZyendzY002R242Q0pEYzZ2Vks4QmtNbmZHOHZPU0tmcFBJWmRBZmRFIiwgImdiT3NJNEVkcTJ4Mkt3LXc1d1BFemFrb2I5aFYxY1JEMEFUTjNvUUw5Sk0iLCAianN1OXlWdWx3UVFsaEZsTV8zSmx6TWFTRnpnbGhRRzBEcGZheVF3TFVLNCJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwgImlhdCI6IDE2ODMwMDAwMDAsICJleHAiOiAxODgzMDAwMDAwLCAic3ViIjogInVzZXJfNDIiLCAibmF0aW9uYWxpdGllcyI6IFt7Ii4uLiI6ICJwRm5kamtaX1ZDem15VGE2VWpsWm8zZGgta284YUlLUWM5RGxHemhhVllvIn0sIHsiLi4uIjogIjdDZjZKa1B1ZHJ5M2xjYndIZ2VaOGtoQXYxVTFPU2xlclAwVmtCSnJXWjAifV0sICJfc2RfYWxnIjogInNoYS0yNTYiLCAiY25mIjogeyJqd2siOiB7Imt0eSI6ICJFQyIsICJjcnYiOiAiUC0yNTYiLCAieCI6ICJUQ0FFUjE5WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwgInkiOiAiWnhqaVdXYlpNUUdIVldLVlE0aGJTSWlyc1ZmdWVjQ0U2dDRqVDlGMkhaUSJ9fX0.MczwjBFGtzf-6WMT-hIvYbkb11NrV1WMO-jTijpMPNbswNzZ87wY2uHz-CXo6R04b7jYrpj9mNRAvVssXou1iw~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd~WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCAicmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImdpdmVuX25hbWUiLCAiSm9obiJd~WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgIlVTIl0~eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImtiK2p3dCJ9.eyJub25jZSI6ICIxMjM0NTY3ODkwIiwgImF1ZCI6ICJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUub3JnIiwgImlhdCI6IDE3NDg1MzcyNDQsICJzZF9oYXNoIjogIjBfQWYtMkItRWhMV1g1eWRoX3cyeHp3bU82aU02NkJfMlFDRWFuSTRmVVkifQ.T3SIus2OidNl41nmVkTZVCKKhOAX97aOldMyHFiYjHm261eLiJ1YiuONFiMN8QlCmYzDlBLAdPvrXh52KaLgUQ",
"issuerKey": {
"kty": "EC",
"crv": "P-256",
"x": "b28d4MwZMjw8-00CG4xfnn9SLMVMM19SlqZpVb_uNtQ",
"y": "Xv5zWwuoaTgdS6hV43yI6gBwTnjukmFQQnJ_kCxzqk8"
},
"issuerAlg": "ES256",
"audience": "https://verifier.example.org",
"nonce": "1234567890",
"now": "2025-05-29T16:47:24.000Z",
"expectedIssuer": "https://other-issuer.example"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.issuer"
],
"levels": {
"integrity": "NOT_MEASURED",
"authenticity": "FAILED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,67 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/rfc9901.kb-audience",
"artifact": "sdjwt-presentation",
"title": "the same presentation shown to another verifier",
"source": "derived from sdjwt-presentation/rfc9901.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/rfc9901.valid",
"mutation": {
"op": "set",
"path": [
"audience"
],
"value": "https://other.example"
},
"input": {
"sdJwt": "eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBbIkNyUWU3UzVrcUJBSHQtbk1ZWGdjNmJkdDJTSDVhVFkxc1VfTS1QZ2tqUEkiLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVadTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFVQTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAiWFFfM2tQS3QxWHlYN0tBTmtxVlI2eVoyVmE1TnJQSXZQWWJ5TXZSS0JNTSIsICJYekZyendzY002R242Q0pEYzZ2Vks4QmtNbmZHOHZPU0tmcFBJWmRBZmRFIiwgImdiT3NJNEVkcTJ4Mkt3LXc1d1BFemFrb2I5aFYxY1JEMEFUTjNvUUw5Sk0iLCAianN1OXlWdWx3UVFsaEZsTV8zSmx6TWFTRnpnbGhRRzBEcGZheVF3TFVLNCJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwgImlhdCI6IDE2ODMwMDAwMDAsICJleHAiOiAxODgzMDAwMDAwLCAic3ViIjogInVzZXJfNDIiLCAibmF0aW9uYWxpdGllcyI6IFt7Ii4uLiI6ICJwRm5kamtaX1ZDem15VGE2VWpsWm8zZGgta284YUlLUWM5RGxHemhhVllvIn0sIHsiLi4uIjogIjdDZjZKa1B1ZHJ5M2xjYndIZ2VaOGtoQXYxVTFPU2xlclAwVmtCSnJXWjAifV0sICJfc2RfYWxnIjogInNoYS0yNTYiLCAiY25mIjogeyJqd2siOiB7Imt0eSI6ICJFQyIsICJjcnYiOiAiUC0yNTYiLCAieCI6ICJUQ0FFUjE5WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwgInkiOiAiWnhqaVdXYlpNUUdIVldLVlE0aGJTSWlyc1ZmdWVjQ0U2dDRqVDlGMkhaUSJ9fX0.MczwjBFGtzf-6WMT-hIvYbkb11NrV1WMO-jTijpMPNbswNzZ87wY2uHz-CXo6R04b7jYrpj9mNRAvVssXou1iw~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd~WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCAicmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImdpdmVuX25hbWUiLCAiSm9obiJd~WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgIlVTIl0~eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImtiK2p3dCJ9.eyJub25jZSI6ICIxMjM0NTY3ODkwIiwgImF1ZCI6ICJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUub3JnIiwgImlhdCI6IDE3NDg1MzcyNDQsICJzZF9oYXNoIjogIjBfQWYtMkItRWhMV1g1eWRoX3cyeHp3bU82aU02NkJfMlFDRWFuSTRmVVkifQ.T3SIus2OidNl41nmVkTZVCKKhOAX97aOldMyHFiYjHm261eLiJ1YiuONFiMN8QlCmYzDlBLAdPvrXh52KaLgUQ",
"issuerKey": {
"kty": "EC",
"crv": "P-256",
"x": "b28d4MwZMjw8-00CG4xfnn9SLMVMM19SlqZpVb_uNtQ",
"y": "Xv5zWwuoaTgdS6hV43yI6gBwTnjukmFQQnJ_kCxzqk8"
},
"issuerAlg": "ES256",
"audience": "https://other.example",
"nonce": "1234567890",
"now": "2025-05-29T16:47:24.000Z"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.kb-audience"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,65 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/rfc9901.kb-context",
"artifact": "sdjwt-presentation",
"title": "the verifier gives no audience: a key binding cannot be judged, and the presentation is refused rather than taken on trust",
"source": "derived from sdjwt-presentation/rfc9901.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/rfc9901.valid",
"mutation": {
"op": "remove",
"path": [
"audience"
]
},
"input": {
"sdJwt": "eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBbIkNyUWU3UzVrcUJBSHQtbk1ZWGdjNmJkdDJTSDVhVFkxc1VfTS1QZ2tqUEkiLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVadTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFVQTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAiWFFfM2tQS3QxWHlYN0tBTmtxVlI2eVoyVmE1TnJQSXZQWWJ5TXZSS0JNTSIsICJYekZyendzY002R242Q0pEYzZ2Vks4QmtNbmZHOHZPU0tmcFBJWmRBZmRFIiwgImdiT3NJNEVkcTJ4Mkt3LXc1d1BFemFrb2I5aFYxY1JEMEFUTjNvUUw5Sk0iLCAianN1OXlWdWx3UVFsaEZsTV8zSmx6TWFTRnpnbGhRRzBEcGZheVF3TFVLNCJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwgImlhdCI6IDE2ODMwMDAwMDAsICJleHAiOiAxODgzMDAwMDAwLCAic3ViIjogInVzZXJfNDIiLCAibmF0aW9uYWxpdGllcyI6IFt7Ii4uLiI6ICJwRm5kamtaX1ZDem15VGE2VWpsWm8zZGgta284YUlLUWM5RGxHemhhVllvIn0sIHsiLi4uIjogIjdDZjZKa1B1ZHJ5M2xjYndIZ2VaOGtoQXYxVTFPU2xlclAwVmtCSnJXWjAifV0sICJfc2RfYWxnIjogInNoYS0yNTYiLCAiY25mIjogeyJqd2siOiB7Imt0eSI6ICJFQyIsICJjcnYiOiAiUC0yNTYiLCAieCI6ICJUQ0FFUjE5WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwgInkiOiAiWnhqaVdXYlpNUUdIVldLVlE0aGJTSWlyc1ZmdWVjQ0U2dDRqVDlGMkhaUSJ9fX0.MczwjBFGtzf-6WMT-hIvYbkb11NrV1WMO-jTijpMPNbswNzZ87wY2uHz-CXo6R04b7jYrpj9mNRAvVssXou1iw~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd~WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCAicmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImdpdmVuX25hbWUiLCAiSm9obiJd~WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgIlVTIl0~eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImtiK2p3dCJ9.eyJub25jZSI6ICIxMjM0NTY3ODkwIiwgImF1ZCI6ICJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUub3JnIiwgImlhdCI6IDE3NDg1MzcyNDQsICJzZF9oYXNoIjogIjBfQWYtMkItRWhMV1g1eWRoX3cyeHp3bU82aU02NkJfMlFDRWFuSTRmVVkifQ.T3SIus2OidNl41nmVkTZVCKKhOAX97aOldMyHFiYjHm261eLiJ1YiuONFiMN8QlCmYzDlBLAdPvrXh52KaLgUQ",
"issuerKey": {
"kty": "EC",
"crv": "P-256",
"x": "b28d4MwZMjw8-00CG4xfnn9SLMVMM19SlqZpVb_uNtQ",
"y": "Xv5zWwuoaTgdS6hV43yI6gBwTnjukmFQQnJ_kCxzqk8"
},
"issuerAlg": "ES256",
"nonce": "1234567890",
"now": "2025-05-29T16:47:24.000Z"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.kb-context"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,67 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/rfc9901.kb-freshness",
"artifact": "sdjwt-presentation",
"title": "the verifier clock is an hour after the key binding JWT was made",
"source": "derived from sdjwt-presentation/rfc9901.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/rfc9901.valid",
"mutation": {
"op": "set",
"path": [
"now"
],
"value": "2025-05-29T17:47:24.000Z"
},
"input": {
"sdJwt": "eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBbIkNyUWU3UzVrcUJBSHQtbk1ZWGdjNmJkdDJTSDVhVFkxc1VfTS1QZ2tqUEkiLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVadTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFVQTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAiWFFfM2tQS3QxWHlYN0tBTmtxVlI2eVoyVmE1TnJQSXZQWWJ5TXZSS0JNTSIsICJYekZyendzY002R242Q0pEYzZ2Vks4QmtNbmZHOHZPU0tmcFBJWmRBZmRFIiwgImdiT3NJNEVkcTJ4Mkt3LXc1d1BFemFrb2I5aFYxY1JEMEFUTjNvUUw5Sk0iLCAianN1OXlWdWx3UVFsaEZsTV8zSmx6TWFTRnpnbGhRRzBEcGZheVF3TFVLNCJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwgImlhdCI6IDE2ODMwMDAwMDAsICJleHAiOiAxODgzMDAwMDAwLCAic3ViIjogInVzZXJfNDIiLCAibmF0aW9uYWxpdGllcyI6IFt7Ii4uLiI6ICJwRm5kamtaX1ZDem15VGE2VWpsWm8zZGgta284YUlLUWM5RGxHemhhVllvIn0sIHsiLi4uIjogIjdDZjZKa1B1ZHJ5M2xjYndIZ2VaOGtoQXYxVTFPU2xlclAwVmtCSnJXWjAifV0sICJfc2RfYWxnIjogInNoYS0yNTYiLCAiY25mIjogeyJqd2siOiB7Imt0eSI6ICJFQyIsICJjcnYiOiAiUC0yNTYiLCAieCI6ICJUQ0FFUjE5WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwgInkiOiAiWnhqaVdXYlpNUUdIVldLVlE0aGJTSWlyc1ZmdWVjQ0U2dDRqVDlGMkhaUSJ9fX0.MczwjBFGtzf-6WMT-hIvYbkb11NrV1WMO-jTijpMPNbswNzZ87wY2uHz-CXo6R04b7jYrpj9mNRAvVssXou1iw~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd~WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCAicmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImdpdmVuX25hbWUiLCAiSm9obiJd~WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgIlVTIl0~eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImtiK2p3dCJ9.eyJub25jZSI6ICIxMjM0NTY3ODkwIiwgImF1ZCI6ICJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUub3JnIiwgImlhdCI6IDE3NDg1MzcyNDQsICJzZF9oYXNoIjogIjBfQWYtMkItRWhMV1g1eWRoX3cyeHp3bU82aU02NkJfMlFDRWFuSTRmVVkifQ.T3SIus2OidNl41nmVkTZVCKKhOAX97aOldMyHFiYjHm261eLiJ1YiuONFiMN8QlCmYzDlBLAdPvrXh52KaLgUQ",
"issuerKey": {
"kty": "EC",
"crv": "P-256",
"x": "b28d4MwZMjw8-00CG4xfnn9SLMVMM19SlqZpVb_uNtQ",
"y": "Xv5zWwuoaTgdS6hV43yI6gBwTnjukmFQQnJ_kCxzqk8"
},
"issuerAlg": "ES256",
"audience": "https://verifier.example.org",
"nonce": "1234567890",
"now": "2025-05-29T17:47:24.000Z"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.kb-freshness"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,67 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/rfc9901.kb-nonce",
"artifact": "sdjwt-presentation",
"title": "the verifier gave another nonce (a replay)",
"source": "derived from sdjwt-presentation/rfc9901.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/rfc9901.valid",
"mutation": {
"op": "set",
"path": [
"nonce"
],
"value": "another-nonce"
},
"input": {
"sdJwt": "eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBbIkNyUWU3UzVrcUJBSHQtbk1ZWGdjNmJkdDJTSDVhVFkxc1VfTS1QZ2tqUEkiLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVadTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFVQTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAiWFFfM2tQS3QxWHlYN0tBTmtxVlI2eVoyVmE1TnJQSXZQWWJ5TXZSS0JNTSIsICJYekZyendzY002R242Q0pEYzZ2Vks4QmtNbmZHOHZPU0tmcFBJWmRBZmRFIiwgImdiT3NJNEVkcTJ4Mkt3LXc1d1BFemFrb2I5aFYxY1JEMEFUTjNvUUw5Sk0iLCAianN1OXlWdWx3UVFsaEZsTV8zSmx6TWFTRnpnbGhRRzBEcGZheVF3TFVLNCJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwgImlhdCI6IDE2ODMwMDAwMDAsICJleHAiOiAxODgzMDAwMDAwLCAic3ViIjogInVzZXJfNDIiLCAibmF0aW9uYWxpdGllcyI6IFt7Ii4uLiI6ICJwRm5kamtaX1ZDem15VGE2VWpsWm8zZGgta284YUlLUWM5RGxHemhhVllvIn0sIHsiLi4uIjogIjdDZjZKa1B1ZHJ5M2xjYndIZ2VaOGtoQXYxVTFPU2xlclAwVmtCSnJXWjAifV0sICJfc2RfYWxnIjogInNoYS0yNTYiLCAiY25mIjogeyJqd2siOiB7Imt0eSI6ICJFQyIsICJjcnYiOiAiUC0yNTYiLCAieCI6ICJUQ0FFUjE5WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwgInkiOiAiWnhqaVdXYlpNUUdIVldLVlE0aGJTSWlyc1ZmdWVjQ0U2dDRqVDlGMkhaUSJ9fX0.MczwjBFGtzf-6WMT-hIvYbkb11NrV1WMO-jTijpMPNbswNzZ87wY2uHz-CXo6R04b7jYrpj9mNRAvVssXou1iw~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd~WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCAicmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImdpdmVuX25hbWUiLCAiSm9obiJd~WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgIlVTIl0~eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImtiK2p3dCJ9.eyJub25jZSI6ICIxMjM0NTY3ODkwIiwgImF1ZCI6ICJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUub3JnIiwgImlhdCI6IDE3NDg1MzcyNDQsICJzZF9oYXNoIjogIjBfQWYtMkItRWhMV1g1eWRoX3cyeHp3bU82aU02NkJfMlFDRWFuSTRmVVkifQ.T3SIus2OidNl41nmVkTZVCKKhOAX97aOldMyHFiYjHm261eLiJ1YiuONFiMN8QlCmYzDlBLAdPvrXh52KaLgUQ",
"issuerKey": {
"kty": "EC",
"crv": "P-256",
"x": "b28d4MwZMjw8-00CG4xfnn9SLMVMM19SlqZpVb_uNtQ",
"y": "Xv5zWwuoaTgdS6hV43yI6gBwTnjukmFQQnJ_kCxzqk8"
},
"issuerAlg": "ES256",
"audience": "https://verifier.example.org",
"nonce": "another-nonce",
"now": "2025-05-29T16:47:24.000Z"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.kb-nonce"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,67 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/rfc9901.kb-required",
"artifact": "sdjwt-presentation",
"title": "the SD-JWT as issued, no key binding, shown to a verifier that requires one",
"source": "derived from sdjwt-presentation/rfc9901.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/rfc9901.valid",
"mutation": {
"op": "set",
"path": [
"sdJwt"
],
"value": "eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBbIkNyUWU3UzVrcUJBSHQtbk1ZWGdjNmJkdDJTSDVhVFkxc1VfTS1QZ2tqUEkiLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVadTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFVQTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAiWFFfM2tQS3QxWHlYN0tBTmtxVlI2eVoyVmE1TnJQSXZQWWJ5TXZSS0JNTSIsICJYekZyendzY002R242Q0pEYzZ2Vks4QmtNbmZHOHZPU0tmcFBJWmRBZmRFIiwgImdiT3NJNEVkcTJ4Mkt3LXc1d1BFemFrb2I5aFYxY1JEMEFUTjNvUUw5Sk0iLCAianN1OXlWdWx3UVFsaEZsTV8zSmx6TWFTRnpnbGhRRzBEcGZheVF3TFVLNCJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwgImlhdCI6IDE2ODMwMDAwMDAsICJleHAiOiAxODgzMDAwMDAwLCAic3ViIjogInVzZXJfNDIiLCAibmF0aW9uYWxpdGllcyI6IFt7Ii4uLiI6ICJwRm5kamtaX1ZDem15VGE2VWpsWm8zZGgta284YUlLUWM5RGxHemhhVllvIn0sIHsiLi4uIjogIjdDZjZKa1B1ZHJ5M2xjYndIZ2VaOGtoQXYxVTFPU2xlclAwVmtCSnJXWjAifV0sICJfc2RfYWxnIjogInNoYS0yNTYiLCAiY25mIjogeyJqd2siOiB7Imt0eSI6ICJFQyIsICJjcnYiOiAiUC0yNTYiLCAieCI6ICJUQ0FFUjE5WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwgInkiOiAiWnhqaVdXYlpNUUdIVldLVlE0aGJTSWlyc1ZmdWVjQ0U2dDRqVDlGMkhaUSJ9fX0.MczwjBFGtzf-6WMT-hIvYbkb11NrV1WMO-jTijpMPNbswNzZ87wY2uHz-CXo6R04b7jYrpj9mNRAvVssXou1iw~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImdpdmVuX25hbWUiLCAiSm9obiJd~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd~WyI2SWo3dE0tYTVpVlBHYm9TNXRtdlZBIiwgImVtYWlsIiwgImpvaG5kb2VAZXhhbXBsZS5jb20iXQ~WyJlSThaV205UW5LUHBOUGVOZW5IZGhRIiwgInBob25lX251bWJlciIsICIrMS0yMDItNTU1LTAxMDEiXQ~WyJRZ19PNjR6cUF4ZTQxMmExMDhpcm9BIiwgInBob25lX251bWJlcl92ZXJpZmllZCIsIHRydWVd~WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCAicmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0~WyJQYzMzSk0yTGNoY1VfbEhnZ3ZfdWZRIiwgImJpcnRoZGF0ZSIsICIxOTQwLTAxLTAxIl0~WyJHMDJOU3JRZmpGWFE3SW8wOXN5YWpBIiwgInVwZGF0ZWRfYXQiLCAxNTcwMDAwMDAwXQ~WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgIlVTIl0~WyJuUHVvUW5rUkZxM0JJZUFtN0FuWEZBIiwgIkRFIl0~"
},
"input": {
"sdJwt": "eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBbIkNyUWU3UzVrcUJBSHQtbk1ZWGdjNmJkdDJTSDVhVFkxc1VfTS1QZ2tqUEkiLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVadTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFVQTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAiWFFfM2tQS3QxWHlYN0tBTmtxVlI2eVoyVmE1TnJQSXZQWWJ5TXZSS0JNTSIsICJYekZyendzY002R242Q0pEYzZ2Vks4QmtNbmZHOHZPU0tmcFBJWmRBZmRFIiwgImdiT3NJNEVkcTJ4Mkt3LXc1d1BFemFrb2I5aFYxY1JEMEFUTjNvUUw5Sk0iLCAianN1OXlWdWx3UVFsaEZsTV8zSmx6TWFTRnpnbGhRRzBEcGZheVF3TFVLNCJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwgImlhdCI6IDE2ODMwMDAwMDAsICJleHAiOiAxODgzMDAwMDAwLCAic3ViIjogInVzZXJfNDIiLCAibmF0aW9uYWxpdGllcyI6IFt7Ii4uLiI6ICJwRm5kamtaX1ZDem15VGE2VWpsWm8zZGgta284YUlLUWM5RGxHemhhVllvIn0sIHsiLi4uIjogIjdDZjZKa1B1ZHJ5M2xjYndIZ2VaOGtoQXYxVTFPU2xlclAwVmtCSnJXWjAifV0sICJfc2RfYWxnIjogInNoYS0yNTYiLCAiY25mIjogeyJqd2siOiB7Imt0eSI6ICJFQyIsICJjcnYiOiAiUC0yNTYiLCAieCI6ICJUQ0FFUjE5WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwgInkiOiAiWnhqaVdXYlpNUUdIVldLVlE0aGJTSWlyc1ZmdWVjQ0U2dDRqVDlGMkhaUSJ9fX0.MczwjBFGtzf-6WMT-hIvYbkb11NrV1WMO-jTijpMPNbswNzZ87wY2uHz-CXo6R04b7jYrpj9mNRAvVssXou1iw~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImdpdmVuX25hbWUiLCAiSm9obiJd~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd~WyI2SWo3dE0tYTVpVlBHYm9TNXRtdlZBIiwgImVtYWlsIiwgImpvaG5kb2VAZXhhbXBsZS5jb20iXQ~WyJlSThaV205UW5LUHBOUGVOZW5IZGhRIiwgInBob25lX251bWJlciIsICIrMS0yMDItNTU1LTAxMDEiXQ~WyJRZ19PNjR6cUF4ZTQxMmExMDhpcm9BIiwgInBob25lX251bWJlcl92ZXJpZmllZCIsIHRydWVd~WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCAicmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0~WyJQYzMzSk0yTGNoY1VfbEhnZ3ZfdWZRIiwgImJpcnRoZGF0ZSIsICIxOTQwLTAxLTAxIl0~WyJHMDJOU3JRZmpGWFE3SW8wOXN5YWpBIiwgInVwZGF0ZWRfYXQiLCAxNTcwMDAwMDAwXQ~WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgIlVTIl0~WyJuUHVvUW5rUkZxM0JJZUFtN0FuWEZBIiwgIkRFIl0~",
"issuerKey": {
"kty": "EC",
"crv": "P-256",
"x": "b28d4MwZMjw8-00CG4xfnn9SLMVMM19SlqZpVb_uNtQ",
"y": "Xv5zWwuoaTgdS6hV43yI6gBwTnjukmFQQnJ_kCxzqk8"
},
"issuerAlg": "ES256",
"audience": "https://verifier.example.org",
"nonce": "1234567890",
"now": "2025-05-29T16:47:24.000Z"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.kb-required"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,67 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/rfc9901.kb-sd-hash",
"artifact": "sdjwt-presentation",
"title": "a disclosure taken out after the key binding JWT was signed",
"source": "derived from sdjwt-presentation/rfc9901.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/rfc9901.valid",
"mutation": {
"op": "set",
"path": [
"sdJwt"
],
"value": "eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBbIkNyUWU3UzVrcUJBSHQtbk1ZWGdjNmJkdDJTSDVhVFkxc1VfTS1QZ2tqUEkiLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVadTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFVQTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAiWFFfM2tQS3QxWHlYN0tBTmtxVlI2eVoyVmE1TnJQSXZQWWJ5TXZSS0JNTSIsICJYekZyendzY002R242Q0pEYzZ2Vks4QmtNbmZHOHZPU0tmcFBJWmRBZmRFIiwgImdiT3NJNEVkcTJ4Mkt3LXc1d1BFemFrb2I5aFYxY1JEMEFUTjNvUUw5Sk0iLCAianN1OXlWdWx3UVFsaEZsTV8zSmx6TWFTRnpnbGhRRzBEcGZheVF3TFVLNCJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwgImlhdCI6IDE2ODMwMDAwMDAsICJleHAiOiAxODgzMDAwMDAwLCAic3ViIjogInVzZXJfNDIiLCAibmF0aW9uYWxpdGllcyI6IFt7Ii4uLiI6ICJwRm5kamtaX1ZDem15VGE2VWpsWm8zZGgta284YUlLUWM5RGxHemhhVllvIn0sIHsiLi4uIjogIjdDZjZKa1B1ZHJ5M2xjYndIZ2VaOGtoQXYxVTFPU2xlclAwVmtCSnJXWjAifV0sICJfc2RfYWxnIjogInNoYS0yNTYiLCAiY25mIjogeyJqd2siOiB7Imt0eSI6ICJFQyIsICJjcnYiOiAiUC0yNTYiLCAieCI6ICJUQ0FFUjE5WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwgInkiOiAiWnhqaVdXYlpNUUdIVldLVlE0aGJTSWlyc1ZmdWVjQ0U2dDRqVDlGMkhaUSJ9fX0.MczwjBFGtzf-6WMT-hIvYbkb11NrV1WMO-jTijpMPNbswNzZ87wY2uHz-CXo6R04b7jYrpj9mNRAvVssXou1iw~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImdpdmVuX25hbWUiLCAiSm9obiJd~WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgIlVTIl0~eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImtiK2p3dCJ9.eyJub25jZSI6ICIxMjM0NTY3ODkwIiwgImF1ZCI6ICJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUub3JnIiwgImlhdCI6IDE3NDg1MzcyNDQsICJzZF9oYXNoIjogIjBfQWYtMkItRWhMV1g1eWRoX3cyeHp3bU82aU02NkJfMlFDRWFuSTRmVVkifQ.T3SIus2OidNl41nmVkTZVCKKhOAX97aOldMyHFiYjHm261eLiJ1YiuONFiMN8QlCmYzDlBLAdPvrXh52KaLgUQ"
},
"input": {
"sdJwt": "eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBbIkNyUWU3UzVrcUJBSHQtbk1ZWGdjNmJkdDJTSDVhVFkxc1VfTS1QZ2tqUEkiLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVadTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFVQTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAiWFFfM2tQS3QxWHlYN0tBTmtxVlI2eVoyVmE1TnJQSXZQWWJ5TXZSS0JNTSIsICJYekZyendzY002R242Q0pEYzZ2Vks4QmtNbmZHOHZPU0tmcFBJWmRBZmRFIiwgImdiT3NJNEVkcTJ4Mkt3LXc1d1BFemFrb2I5aFYxY1JEMEFUTjNvUUw5Sk0iLCAianN1OXlWdWx3UVFsaEZsTV8zSmx6TWFTRnpnbGhRRzBEcGZheVF3TFVLNCJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwgImlhdCI6IDE2ODMwMDAwMDAsICJleHAiOiAxODgzMDAwMDAwLCAic3ViIjogInVzZXJfNDIiLCAibmF0aW9uYWxpdGllcyI6IFt7Ii4uLiI6ICJwRm5kamtaX1ZDem15VGE2VWpsWm8zZGgta284YUlLUWM5RGxHemhhVllvIn0sIHsiLi4uIjogIjdDZjZKa1B1ZHJ5M2xjYndIZ2VaOGtoQXYxVTFPU2xlclAwVmtCSnJXWjAifV0sICJfc2RfYWxnIjogInNoYS0yNTYiLCAiY25mIjogeyJqd2siOiB7Imt0eSI6ICJFQyIsICJjcnYiOiAiUC0yNTYiLCAieCI6ICJUQ0FFUjE5WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwgInkiOiAiWnhqaVdXYlpNUUdIVldLVlE0aGJTSWlyc1ZmdWVjQ0U2dDRqVDlGMkhaUSJ9fX0.MczwjBFGtzf-6WMT-hIvYbkb11NrV1WMO-jTijpMPNbswNzZ87wY2uHz-CXo6R04b7jYrpj9mNRAvVssXou1iw~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImdpdmVuX25hbWUiLCAiSm9obiJd~WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgIlVTIl0~eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImtiK2p3dCJ9.eyJub25jZSI6ICIxMjM0NTY3ODkwIiwgImF1ZCI6ICJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUub3JnIiwgImlhdCI6IDE3NDg1MzcyNDQsICJzZF9oYXNoIjogIjBfQWYtMkItRWhMV1g1eWRoX3cyeHp3bU82aU02NkJfMlFDRWFuSTRmVVkifQ.T3SIus2OidNl41nmVkTZVCKKhOAX97aOldMyHFiYjHm261eLiJ1YiuONFiMN8QlCmYzDlBLAdPvrXh52KaLgUQ",
"issuerKey": {
"kty": "EC",
"crv": "P-256",
"x": "b28d4MwZMjw8-00CG4xfnn9SLMVMM19SlqZpVb_uNtQ",
"y": "Xv5zWwuoaTgdS6hV43yI6gBwTnjukmFQQnJ_kCxzqk8"
},
"issuerAlg": "ES256",
"audience": "https://verifier.example.org",
"nonce": "1234567890",
"now": "2025-05-29T16:47:24.000Z"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.kb-sd-hash"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,70 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/rfc9901.key",
"artifact": "sdjwt-presentation",
"title": "the issuer key given is an RSA JWK, which this verifier does not take",
"source": "derived from sdjwt-presentation/rfc9901.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/rfc9901.valid",
"mutation": {
"op": "set",
"path": [
"issuerKey"
],
"value": {
"kty": "RSA",
"n": "AQAB",
"e": "AQAB"
}
},
"input": {
"sdJwt": "eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBbIkNyUWU3UzVrcUJBSHQtbk1ZWGdjNmJkdDJTSDVhVFkxc1VfTS1QZ2tqUEkiLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVadTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFVQTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAiWFFfM2tQS3QxWHlYN0tBTmtxVlI2eVoyVmE1TnJQSXZQWWJ5TXZSS0JNTSIsICJYekZyendzY002R242Q0pEYzZ2Vks4QmtNbmZHOHZPU0tmcFBJWmRBZmRFIiwgImdiT3NJNEVkcTJ4Mkt3LXc1d1BFemFrb2I5aFYxY1JEMEFUTjNvUUw5Sk0iLCAianN1OXlWdWx3UVFsaEZsTV8zSmx6TWFTRnpnbGhRRzBEcGZheVF3TFVLNCJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwgImlhdCI6IDE2ODMwMDAwMDAsICJleHAiOiAxODgzMDAwMDAwLCAic3ViIjogInVzZXJfNDIiLCAibmF0aW9uYWxpdGllcyI6IFt7Ii4uLiI6ICJwRm5kamtaX1ZDem15VGE2VWpsWm8zZGgta284YUlLUWM5RGxHemhhVllvIn0sIHsiLi4uIjogIjdDZjZKa1B1ZHJ5M2xjYndIZ2VaOGtoQXYxVTFPU2xlclAwVmtCSnJXWjAifV0sICJfc2RfYWxnIjogInNoYS0yNTYiLCAiY25mIjogeyJqd2siOiB7Imt0eSI6ICJFQyIsICJjcnYiOiAiUC0yNTYiLCAieCI6ICJUQ0FFUjE5WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwgInkiOiAiWnhqaVdXYlpNUUdIVldLVlE0aGJTSWlyc1ZmdWVjQ0U2dDRqVDlGMkhaUSJ9fX0.MczwjBFGtzf-6WMT-hIvYbkb11NrV1WMO-jTijpMPNbswNzZ87wY2uHz-CXo6R04b7jYrpj9mNRAvVssXou1iw~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd~WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCAicmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImdpdmVuX25hbWUiLCAiSm9obiJd~WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgIlVTIl0~eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImtiK2p3dCJ9.eyJub25jZSI6ICIxMjM0NTY3ODkwIiwgImF1ZCI6ICJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUub3JnIiwgImlhdCI6IDE3NDg1MzcyNDQsICJzZF9oYXNoIjogIjBfQWYtMkItRWhMV1g1eWRoX3cyeHp3bU82aU02NkJfMlFDRWFuSTRmVVkifQ.T3SIus2OidNl41nmVkTZVCKKhOAX97aOldMyHFiYjHm261eLiJ1YiuONFiMN8QlCmYzDlBLAdPvrXh52KaLgUQ",
"issuerKey": {
"kty": "RSA",
"n": "AQAB",
"e": "AQAB"
},
"issuerAlg": "ES256",
"audience": "https://verifier.example.org",
"nonce": "1234567890",
"now": "2025-05-29T16:47:24.000Z"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.key"
],
"levels": {
"integrity": "NOT_MEASURED",
"authenticity": "FAILED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,72 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/rfc9901.signature",
"artifact": "sdjwt-presentation",
"title": "the issuer key given is the holder key of the example (cnf.jwk): the issuer signature does not verify with it",
"source": "derived from sdjwt-presentation/rfc9901.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/rfc9901.valid",
"mutation": {
"op": "set",
"path": [
"issuerKey"
],
"value": {
"kty": "EC",
"crv": "P-256",
"x": "TCAER19Zvu3OHF4j4W4vfSVoHIP1ILilDls7vCeGemc",
"y": "ZxjiWWbZMQGHVWKVQ4hbSIirsVfuecCE6t4jT9F2HZQ"
}
},
"input": {
"sdJwt": "eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBbIkNyUWU3UzVrcUJBSHQtbk1ZWGdjNmJkdDJTSDVhVFkxc1VfTS1QZ2tqUEkiLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVadTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFVQTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAiWFFfM2tQS3QxWHlYN0tBTmtxVlI2eVoyVmE1TnJQSXZQWWJ5TXZSS0JNTSIsICJYekZyendzY002R242Q0pEYzZ2Vks4QmtNbmZHOHZPU0tmcFBJWmRBZmRFIiwgImdiT3NJNEVkcTJ4Mkt3LXc1d1BFemFrb2I5aFYxY1JEMEFUTjNvUUw5Sk0iLCAianN1OXlWdWx3UVFsaEZsTV8zSmx6TWFTRnpnbGhRRzBEcGZheVF3TFVLNCJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwgImlhdCI6IDE2ODMwMDAwMDAsICJleHAiOiAxODgzMDAwMDAwLCAic3ViIjogInVzZXJfNDIiLCAibmF0aW9uYWxpdGllcyI6IFt7Ii4uLiI6ICJwRm5kamtaX1ZDem15VGE2VWpsWm8zZGgta284YUlLUWM5RGxHemhhVllvIn0sIHsiLi4uIjogIjdDZjZKa1B1ZHJ5M2xjYndIZ2VaOGtoQXYxVTFPU2xlclAwVmtCSnJXWjAifV0sICJfc2RfYWxnIjogInNoYS0yNTYiLCAiY25mIjogeyJqd2siOiB7Imt0eSI6ICJFQyIsICJjcnYiOiAiUC0yNTYiLCAieCI6ICJUQ0FFUjE5WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwgInkiOiAiWnhqaVdXYlpNUUdIVldLVlE0aGJTSWlyc1ZmdWVjQ0U2dDRqVDlGMkhaUSJ9fX0.MczwjBFGtzf-6WMT-hIvYbkb11NrV1WMO-jTijpMPNbswNzZ87wY2uHz-CXo6R04b7jYrpj9mNRAvVssXou1iw~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd~WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCAicmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImdpdmVuX25hbWUiLCAiSm9obiJd~WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgIlVTIl0~eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImtiK2p3dCJ9.eyJub25jZSI6ICIxMjM0NTY3ODkwIiwgImF1ZCI6ICJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUub3JnIiwgImlhdCI6IDE3NDg1MzcyNDQsICJzZF9oYXNoIjogIjBfQWYtMkItRWhMV1g1eWRoX3cyeHp3bU82aU02NkJfMlFDRWFuSTRmVVkifQ.T3SIus2OidNl41nmVkTZVCKKhOAX97aOldMyHFiYjHm261eLiJ1YiuONFiMN8QlCmYzDlBLAdPvrXh52KaLgUQ",
"issuerKey": {
"kty": "EC",
"crv": "P-256",
"x": "TCAER19Zvu3OHF4j4W4vfSVoHIP1ILilDls7vCeGemc",
"y": "ZxjiWWbZMQGHVWKVQ4hbSIirsVfuecCE6t4jT9F2HZQ"
},
"issuerAlg": "ES256",
"audience": "https://verifier.example.org",
"nonce": "1234567890",
"now": "2025-05-29T16:47:24.000Z"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.signature"
],
"levels": {
"integrity": "NOT_MEASURED",
"authenticity": "FAILED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,68 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/rfc9901.typ",
"artifact": "sdjwt-presentation",
"title": "the verifier expects another explicit type",
"source": "derived from sdjwt-presentation/rfc9901.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/rfc9901.valid",
"mutation": {
"op": "add",
"path": [
"expectedTyp"
],
"value": "other+sd-jwt"
},
"input": {
"sdJwt": "eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBbIkNyUWU3UzVrcUJBSHQtbk1ZWGdjNmJkdDJTSDVhVFkxc1VfTS1QZ2tqUEkiLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVadTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFVQTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAiWFFfM2tQS3QxWHlYN0tBTmtxVlI2eVoyVmE1TnJQSXZQWWJ5TXZSS0JNTSIsICJYekZyendzY002R242Q0pEYzZ2Vks4QmtNbmZHOHZPU0tmcFBJWmRBZmRFIiwgImdiT3NJNEVkcTJ4Mkt3LXc1d1BFemFrb2I5aFYxY1JEMEFUTjNvUUw5Sk0iLCAianN1OXlWdWx3UVFsaEZsTV8zSmx6TWFTRnpnbGhRRzBEcGZheVF3TFVLNCJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwgImlhdCI6IDE2ODMwMDAwMDAsICJleHAiOiAxODgzMDAwMDAwLCAic3ViIjogInVzZXJfNDIiLCAibmF0aW9uYWxpdGllcyI6IFt7Ii4uLiI6ICJwRm5kamtaX1ZDem15VGE2VWpsWm8zZGgta284YUlLUWM5RGxHemhhVllvIn0sIHsiLi4uIjogIjdDZjZKa1B1ZHJ5M2xjYndIZ2VaOGtoQXYxVTFPU2xlclAwVmtCSnJXWjAifV0sICJfc2RfYWxnIjogInNoYS0yNTYiLCAiY25mIjogeyJqd2siOiB7Imt0eSI6ICJFQyIsICJjcnYiOiAiUC0yNTYiLCAieCI6ICJUQ0FFUjE5WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwgInkiOiAiWnhqaVdXYlpNUUdIVldLVlE0aGJTSWlyc1ZmdWVjQ0U2dDRqVDlGMkhaUSJ9fX0.MczwjBFGtzf-6WMT-hIvYbkb11NrV1WMO-jTijpMPNbswNzZ87wY2uHz-CXo6R04b7jYrpj9mNRAvVssXou1iw~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd~WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCAicmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImdpdmVuX25hbWUiLCAiSm9obiJd~WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgIlVTIl0~eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImtiK2p3dCJ9.eyJub25jZSI6ICIxMjM0NTY3ODkwIiwgImF1ZCI6ICJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUub3JnIiwgImlhdCI6IDE3NDg1MzcyNDQsICJzZF9oYXNoIjogIjBfQWYtMkItRWhMV1g1eWRoX3cyeHp3bU82aU02NkJfMlFDRWFuSTRmVVkifQ.T3SIus2OidNl41nmVkTZVCKKhOAX97aOldMyHFiYjHm261eLiJ1YiuONFiMN8QlCmYzDlBLAdPvrXh52KaLgUQ",
"issuerKey": {
"kty": "EC",
"crv": "P-256",
"x": "b28d4MwZMjw8-00CG4xfnn9SLMVMM19SlqZpVb_uNtQ",
"y": "Xv5zWwuoaTgdS6hV43yI6gBwTnjukmFQQnJ_kCxzqk8"
},
"issuerAlg": "ES256",
"audience": "https://verifier.example.org",
"nonce": "1234567890",
"now": "2025-05-29T16:47:24.000Z",
"expectedTyp": "other+sd-jwt"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.typ"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,59 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/rfc9901.valid",
"artifact": "sdjwt-presentation",
"title": "the presentation of RFC 9901 Section 5.2 (ES256, the issuer key of Appendix A.5) with its Key Binding JWT, judged at the time of that JWT with its audience and nonce",
"source": "IETF RFC 9901 Section 5 and Appendix A.5 (code components, Revised BSD License), via fixturi-rfc9901.json of the identity component",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": null,
"mutation": null,
"input": {
"sdJwt": "eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBbIkNyUWU3UzVrcUJBSHQtbk1ZWGdjNmJkdDJTSDVhVFkxc1VfTS1QZ2tqUEkiLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVadTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFVQTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAiWFFfM2tQS3QxWHlYN0tBTmtxVlI2eVoyVmE1TnJQSXZQWWJ5TXZSS0JNTSIsICJYekZyendzY002R242Q0pEYzZ2Vks4QmtNbmZHOHZPU0tmcFBJWmRBZmRFIiwgImdiT3NJNEVkcTJ4Mkt3LXc1d1BFemFrb2I5aFYxY1JEMEFUTjNvUUw5Sk0iLCAianN1OXlWdWx3UVFsaEZsTV8zSmx6TWFTRnpnbGhRRzBEcGZheVF3TFVLNCJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwgImlhdCI6IDE2ODMwMDAwMDAsICJleHAiOiAxODgzMDAwMDAwLCAic3ViIjogInVzZXJfNDIiLCAibmF0aW9uYWxpdGllcyI6IFt7Ii4uLiI6ICJwRm5kamtaX1ZDem15VGE2VWpsWm8zZGgta284YUlLUWM5RGxHemhhVllvIn0sIHsiLi4uIjogIjdDZjZKa1B1ZHJ5M2xjYndIZ2VaOGtoQXYxVTFPU2xlclAwVmtCSnJXWjAifV0sICJfc2RfYWxnIjogInNoYS0yNTYiLCAiY25mIjogeyJqd2siOiB7Imt0eSI6ICJFQyIsICJjcnYiOiAiUC0yNTYiLCAieCI6ICJUQ0FFUjE5WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwgInkiOiAiWnhqaVdXYlpNUUdIVldLVlE0aGJTSWlyc1ZmdWVjQ0U2dDRqVDlGMkhaUSJ9fX0.MczwjBFGtzf-6WMT-hIvYbkb11NrV1WMO-jTijpMPNbswNzZ87wY2uHz-CXo6R04b7jYrpj9mNRAvVssXou1iw~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd~WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCAicmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImdpdmVuX25hbWUiLCAiSm9obiJd~WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgIlVTIl0~eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImtiK2p3dCJ9.eyJub25jZSI6ICIxMjM0NTY3ODkwIiwgImF1ZCI6ICJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUub3JnIiwgImlhdCI6IDE3NDg1MzcyNDQsICJzZF9oYXNoIjogIjBfQWYtMkItRWhMV1g1eWRoX3cyeHp3bU82aU02NkJfMlFDRWFuSTRmVVkifQ.T3SIus2OidNl41nmVkTZVCKKhOAX97aOldMyHFiYjHm261eLiJ1YiuONFiMN8QlCmYzDlBLAdPvrXh52KaLgUQ",
"issuerKey": {
"kty": "EC",
"crv": "P-256",
"x": "b28d4MwZMjw8-00CG4xfnn9SLMVMM19SlqZpVb_uNtQ",
"y": "Xv5zWwuoaTgdS6hV43yI6gBwTnjukmFQQnJ_kCxzqk8"
},
"issuerAlg": "ES256",
"audience": "https://verifier.example.org",
"nonce": "1234567890",
"now": "2025-05-29T16:47:24.000Z"
},
"expected": {
"verdict": "VALID",
"failed": [],
"levels": {
"integrity": "PASSED",
"authenticity": "PASSED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,60 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/sd-jwt-core-es256.valid",
"artifact": "sdjwt-presentation",
"title": "the same from @sd-jwt/core with ES256 (P-256) keys",
"source": "@sd-jwt/core 0.23.0 with jose 6.2.12 (interop/fixturi-interop-sdjwt.json of the identity component, generated 2026-10-18; its test keys made and discarded at generation)",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": null,
"mutation": null,
"input": {
"sdJwt": "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJodHRwczovL2lzc3Vlci5sb3IuZXhhbXBsZSIsImlhdCI6MTc5MjI4MTYwMCwiZXhwIjoxODIzODE3NjAwLCJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJ5Snp4elppdXBULVlER2szcUM3ejNoVmt1NmZtcUdHQnIxZkEyUHl4b2ZBIn0seyIuLi4iOiJaRXIyakxZdGhoWDhYTHdmTy1ISWtfMnRTNm1mRmwxeW9fRDU5NmFRaWVNIn1dLCJjbmYiOnsiandrIjp7Imt0eSI6IkVDIiwieCI6Ijh3cjJKX1RTdHVLZHo1LUlYQ3dIUGhSaGYwLVU5d3pWLXphd1J4R3FsQVEiLCJ5IjoieVRDeXhlYmtaQUNhM2dLR21MMjVzWjVQWmtuM2g0T0Jkb2FxLWdtc3owcyIsImNydiI6IlAtMjU2In19LCJfc2QiOlsiLW1ORUJ1MkVfUm90aUxEWW9aNWpRN05hUDhUMGZxOUhtOENUUG1GTmRzcyIsIjJqRDRrTWw5cDdwdkdJNW1ONGlnRzZpOGM3RmoxWVNlQ3pWSWpxMEYtY2siLCIzTmE1NUtBNzFPNUlHVW9mRHpSZXozY3B2bUVCUFh1X1pqZm5vdG9xbFd3IiwiRVA4a0p0NEVwUTZNTzhMZ2RJRDhFM0dvS1QzUUQzZ01RVjI3LXF1dEFVUSIsIkhxLTFtdmhJbi1EQjh1aTBaSEpNdlNYOTVpMjRCbDlZRWRjLURuXy00eDgiLCJSQkJMRnUxYVVGck9xMnpoRnJDOW9DNF9oN21BVnBKZ0NmcHZQYUFJV2NvIl0sIl9zZF9hbGciOiJzaGEtMjU2In0.pVRO7rycFsVU67grJdAQy2sGCFG_8TeTDPWCN8BXoQ8S14D3CllLSMbHzzRKtV0ShLS3AIJ1y3H6IQbbKC5rcQ~WyI1NmUwZjk3MzlmYjhjN2NhIiwiYWdlX292ZXJfMTgiLHRydWVd~WyI1ZTg5ZGM2YzE4YTRhY2U3IiwiYWRkcmVzcyIseyJjb3VudHJ5IjoiUk8iLCJfc2QiOlsiV0JFYmlSUXJmdzd5Z0o3dHMtWi1DOF93LUQ2N1hmTEVob2d6dDJFSDl3YyIsIm83SV9VRWpYaVlwaXhDUVRpaklINldaVldlZ3RzcF9GM3JWQU1CdXVEcFkiXX1d~WyIyZTQwZjQwNGY3MjRiNWFlIiwibG9jYWxpdHkiLCJDbHVqIl0~WyJlN2VjYmU0MjBjMWUyMzkwIiwiUk8iXQ~eyJ0eXAiOiJrYitqd3QiLCJhbGciOiJFUzI1NiJ9.eyJhdWQiOiJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUiLCJub25jZSI6ImludGVyb3AtYzM4MmM5OWJjMjgwIiwiaWF0IjoxNzkyMjgxNjAwLCJzZF9oYXNoIjoiRms5NUlyM3d2cUV2ZzF0TnFZUHA5ZGNzOW5XY2tZc3ZkQkRTbnY1UE1EZyJ9.9q3SQVmhEiiaoFq36fHnuH-DBr7myT9ACMu1eY-3754X0KO-kT0E5VxKUUViVji5vVVV5Pb3cjTeUf0Ppu9X7w",
"issuerKey": {
"kty": "EC",
"x": "MwvcAG7Qwg-mknZRXu-JS7VHkZzVLlYjvXzYj4TeLPY",
"y": "fLuSX-6-_njH4b6GGbwwmkgPzD7nBZu04TzG0v0A1j8",
"crv": "P-256"
},
"issuerAlg": "ES256",
"audience": "https://verifier.example",
"nonce": "interop-c382c99bc280",
"now": "2026-10-18T00:01:00.000Z",
"expectedTyp": null
},
"expected": {
"verdict": "VALID",
"failed": [],
"levels": {
"integrity": "PASSED",
"authenticity": "PASSED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,58 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/sd-jwt-core-typed.valid",
"artifact": "sdjwt-presentation",
"title": "an SD-JWT from @sd-jwt/core issued with typ example+sd-jwt, taken by the default type of the verifier",
"source": "@sd-jwt/core 0.23.0 with jose 6.2.12 (interop/fixturi-interop-sdjwt.json of the identity component, generated 2026-10-18; its test keys made and discarded at generation)",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": null,
"mutation": null,
"input": {
"sdJwt": "eyJ0eXAiOiJleGFtcGxlK3NkLWp3dCIsImFsZyI6IkVkRFNBIn0.eyJpc3MiOiJodHRwczovL2lzc3Vlci5sb3IuZXhhbXBsZSIsImlhdCI6MTc5MjI4MTYwMCwiZXhwIjoxODIzODE3NjAwLCJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJlM2dSeEkzMmRtQ0duMjR3SkxPY3lPMmpDcU40U3NQZFFYbkROSHU0Nkp3In0seyIuLi4iOiJrLUdyZVZWcWtIUFNWZGotdWxqMDQ5UFlYOHk5T0JsOV9DOFBjbmJFb0pBIn1dLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4IjoiZDBrY3VxS3FoQmp1MGM5cXRhOVhCNzdwY2x2Z085b01yQW9lVFhxaVJZMCIsImt0eSI6Ik9LUCJ9fSwiX3NkIjpbIjhBYzFQZTItVUxYMElvR255dzJJT0g4Wk1WbVFEWHhyVEw5WTVLcUFwZDQiLCJBSW9VMDh0Z0hrYTBrYU1uT0RqS1ZKeXlQX3k1V1NyRGxQc3ZxZzVRZ0NFIiwiYjZTR09mSVZhQzJEaFhsUkFNZjVYT2pwZlJPYm5Bb3J6d1FqcjhRQ3ZCSSIsImx0T1Y0R0NIUzQwc2pHZ2tpZW5aVGJ2UGNsc0draGtlcUJxSS1jRi0xa2ciLCJtLVVzSlNuQjlnc3VSMjFNaXl6SGdSN3JvWUEtVG83YmNTSlFmUFhGUWhRIiwibzg2UnRhQTd4eXZrOWNCQ3NycE5nd3p4Mmg2RE1wdjc3aVJLUmFPUGxiOCJdLCJfc2RfYWxnIjoic2hhLTI1NiJ9.7hhpGxaCJG0GpqDOfHXECP22qYC10FBzZE-CVSWwueA16naH0RtCwQlHMhIXnvIdPNrDuPji_L4YGxG96zm4AA~WyIzYTE1ZmNhNGQ2MzE2OTNjIiwiYWdlX292ZXJfMTgiLHRydWVd~WyJiMzVlNzFjNTI1ODhkMTdiIiwiYWRkcmVzcyIseyJjb3VudHJ5IjoiUk8iLCJfc2QiOlsiOVJwNktjR3F0Tk1MdVF3QTFmTmEzSFZhM2ZLM2ZOTXBoQk44dnFKbVNRSSIsInlDendIVEFVSWVqZ0NKN0FqQlRvZkhWTGJ4VG9FcGNUelNucVB4d2diTGMiXX1d~WyIzMTZjOTQzMjM0ZTdhZGEwIiwibG9jYWxpdHkiLCJDbHVqIl0~WyI0OGZlNDgwNmNkZTY2MDZkIiwiUk8iXQ~eyJ0eXAiOiJrYitqd3QiLCJhbGciOiJFZERTQSJ9.eyJhdWQiOiJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUiLCJub25jZSI6ImludGVyb3AtYzM4MmM5OWJjMjgwIiwiaWF0IjoxNzkyMjgxNjAwLCJzZF9oYXNoIjoiMjl1UTR4Ul9RQVJXbUNId1JtbVRENDcwcGdmZGhnMTgwX08zc09mWDBOWSJ9.iCOcidDsT_n-KZteZtnt1-3oJ4v7FlZpk3g03wnCc-shcjIzBv9xh2X1ZLGJaHtxbF8oeJ3q5rUCV0TEr7o3Bw",
"issuerKey": {
"crv": "Ed25519",
"x": "nE6yYyZSwKuaQaf0UWpjTfPKu4bRh65eOWSm1teOO0w",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "interop-c382c99bc280",
"now": "2026-10-18T00:01:00.000Z"
},
"expected": {
"verdict": "VALID",
"failed": [],
"levels": {
"integrity": "PASSED",
"authenticity": "PASSED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,68 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/sd-jwt-core.alg",
"artifact": "sdjwt-presentation",
"title": "the @sd-jwt/core payload under alg none",
"source": "derived from sdjwt-presentation/sd-jwt-core.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/sd-jwt-core.valid",
"mutation": {
"producer": "the issuer-signed payload of @sd-jwt/core re-encoded under alg none",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJub25lIn0.eyJpc3MiOiJodHRwczovL2lzc3Vlci5sb3IuZXhhbXBsZSIsImlhdCI6MTc5MjI4MTYwMCwiZXhwIjoxODIzODE3NjAwLCJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJjVWJRWHNNaU9jTGxoTlNmaVo1MW5UaWdUaVRwY2xhQ1lsYy1Uc3JHWVhBIn0seyIuLi4iOiJSNjRmdGNLMW50Mnl1TktiVmJBRjg1M1dUelYyaWg3clRUS0NwNU00QmxnIn1dLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4IjoiSEZ5MHZ6dDNhWHhEZU1EbjY0Y2JYN3owdXVDbDh2MlZBb0VPTzNkd25kTSIsImt0eSI6Ik9LUCJ9fSwiX3NkIjpbIkNLdE5BaGFvTlMyY0h1U1hCeUJzclJHcTE2dmZBUTF6Tk1TUGs4ZktkTkkiLCJGQnlGeXlZWkUwMjdWU1NZeUVLTS03dUZMNTFSY09fdk9jUFdZWHVpU09vIiwiUGNEY2l0S0dJbm0wQmpBR0x5Q3ptaU52YU5aSGZZVl9GNmRWeUM1LWd1NCIsIlNyS3JyYk1wNWM2OG5FVnFmNmJ0VWFTYWwxV3dCc0J0OENJcUJHTGFTYmciLCJXajlCTkc4ZVhnWU1zd0tJVEhOd3kzQXdyV1hXVC1XMGRGbjFpSWdGdXRNIiwiblo0aUZuSlB2OTkyb2lGLVFJaFMwT1g5WDllM2FqODVKb0o0bnVzVU1jTSJdLCJfc2RfYWxnIjoic2hhLTI1NiJ9.~",
"issuerKey": {
"crv": "Ed25519",
"x": "-aHX28vHzHZU6u5ottr9OKLK2dDhU3l50i21w_Ry7Zw",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "interop-c382c99bc280",
"now": "2026-10-18T00:01:00.000Z",
"expectedTyp": null
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.alg"
],
"levels": {
"integrity": "NOT_MEASURED",
"authenticity": "FAILED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,68 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/sd-jwt-core.digest-twice",
"artifact": "sdjwt-presentation",
"title": "the @sd-jwt/core payload with a digest repeated in _sd, signed again by its issuer key",
"source": "derived from sdjwt-presentation/sd-jwt-core.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/sd-jwt-core.valid",
"mutation": {
"producer": "the @sd-jwt/core issuer key signed its payload with the first digest of _sd repeated",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSJ9.eyJpc3MiOiJodHRwczovL2lzc3Vlci5sb3IuZXhhbXBsZSIsImlhdCI6MTc5MjI4MTYwMCwiZXhwIjoxODIzODE3NjAwLCJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJjVWJRWHNNaU9jTGxoTlNmaVo1MW5UaWdUaVRwY2xhQ1lsYy1Uc3JHWVhBIn0seyIuLi4iOiJSNjRmdGNLMW50Mnl1TktiVmJBRjg1M1dUelYyaWg3clRUS0NwNU00QmxnIn1dLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4IjoiSEZ5MHZ6dDNhWHhEZU1EbjY0Y2JYN3owdXVDbDh2MlZBb0VPTzNkd25kTSIsImt0eSI6Ik9LUCJ9fSwiX3NkIjpbIkNLdE5BaGFvTlMyY0h1U1hCeUJzclJHcTE2dmZBUTF6Tk1TUGs4ZktkTkkiLCJGQnlGeXlZWkUwMjdWU1NZeUVLTS03dUZMNTFSY09fdk9jUFdZWHVpU09vIiwiUGNEY2l0S0dJbm0wQmpBR0x5Q3ptaU52YU5aSGZZVl9GNmRWeUM1LWd1NCIsIlNyS3JyYk1wNWM2OG5FVnFmNmJ0VWFTYWwxV3dCc0J0OENJcUJHTGFTYmciLCJXajlCTkc4ZVhnWU1zd0tJVEhOd3kzQXdyV1hXVC1XMGRGbjFpSWdGdXRNIiwiblo0aUZuSlB2OTkyb2lGLVFJaFMwT1g5WDllM2FqODVKb0o0bnVzVU1jTSIsIkNLdE5BaGFvTlMyY0h1U1hCeUJzclJHcTE2dmZBUTF6Tk1TUGs4ZktkTkkiXSwiX3NkX2FsZyI6InNoYS0yNTYifQ.bnB_QWkrH4IGE4RkrBrwoy-sIS1hSL0f4azdh2DlZ-obGdZKFvz_w76VW_x2PEMKugH01HYgAnDGqHqt0cCLDg~WyI2NjQxOGNlZWY4M2VkODY4Iiwic3RyZWV0X2FkZHJlc3MiLCJTdHIuIEx1bmdhIDEiXQ~WyJiNDhkMDc1YzExZGE2ZDAwIiwibG9jYWxpdHkiLCJDbHVqIl0~WyIwYTQwZTZjZDg0ZmJjNGU2IiwiUk8iXQ~WyIzMjc5ZTM1NjI4ZDZlYTVjIiwiREUiXQ~WyI3ZTBkNmNkYTliMmFkYzc1IiwiZ2l2ZW5fbmFtZSIsIkFuYSJd~WyJhYzBlZjNhZWU0N2QwZjlkIiwiZmFtaWx5X25hbWUiLCJQb3AiXQ~WyIzNjQxOGIzNjIzZDM2Zjc2IiwiYWdlX292ZXJfMTgiLHRydWVd~WyJjNTU0ODYyODA2MzVmZTRlIiwiYWRkcmVzcyIseyJjb3VudHJ5IjoiUk8iLCJfc2QiOlsiTGw0SnlHS2hCNFpZZGdkZy05LU5iTGZlaDVBQkdnYmRNVUpsZHNGVUJlOCIsIlpKc1NmZTVMWEFmVTQyYVBEMU9SdU1IblNqVWZ3NHVqeWZPdXhuaExDQ28iXX1d~",
"issuerKey": {
"crv": "Ed25519",
"x": "-aHX28vHzHZU6u5ottr9OKLK2dDhU3l50i21w_Ry7Zw",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "interop-c382c99bc280",
"now": "2026-10-18T00:01:00.000Z",
"expectedTyp": null
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.digest-twice"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,68 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/sd-jwt-core.kb-audience",
"artifact": "sdjwt-presentation",
"title": "presented by @sd-jwt/core for another audience",
"source": "derived from sdjwt-presentation/sd-jwt-core.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/sd-jwt-core.valid",
"mutation": {
"producer": "@sd-jwt/core presented the token with a key binding JWT for https://other.example",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSJ9.eyJpc3MiOiJodHRwczovL2lzc3Vlci5sb3IuZXhhbXBsZSIsImlhdCI6MTc5MjI4MTYwMCwiZXhwIjoxODIzODE3NjAwLCJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJjVWJRWHNNaU9jTGxoTlNmaVo1MW5UaWdUaVRwY2xhQ1lsYy1Uc3JHWVhBIn0seyIuLi4iOiJSNjRmdGNLMW50Mnl1TktiVmJBRjg1M1dUelYyaWg3clRUS0NwNU00QmxnIn1dLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4IjoiSEZ5MHZ6dDNhWHhEZU1EbjY0Y2JYN3owdXVDbDh2MlZBb0VPTzNkd25kTSIsImt0eSI6Ik9LUCJ9fSwiX3NkIjpbIkNLdE5BaGFvTlMyY0h1U1hCeUJzclJHcTE2dmZBUTF6Tk1TUGs4ZktkTkkiLCJGQnlGeXlZWkUwMjdWU1NZeUVLTS03dUZMNTFSY09fdk9jUFdZWHVpU09vIiwiUGNEY2l0S0dJbm0wQmpBR0x5Q3ptaU52YU5aSGZZVl9GNmRWeUM1LWd1NCIsIlNyS3JyYk1wNWM2OG5FVnFmNmJ0VWFTYWwxV3dCc0J0OENJcUJHTGFTYmciLCJXajlCTkc4ZVhnWU1zd0tJVEhOd3kzQXdyV1hXVC1XMGRGbjFpSWdGdXRNIiwiblo0aUZuSlB2OTkyb2lGLVFJaFMwT1g5WDllM2FqODVKb0o0bnVzVU1jTSJdLCJfc2RfYWxnIjoic2hhLTI1NiJ9.Pqsg-0U-7cVdQqkjJ7qDg6e9fQpCa-EbhRwR9PpWszZkAxterCEgzsYk0dtC-REgTCuSRew50ZuAQQmiwE18Aw~WyIzNjQxOGIzNjIzZDM2Zjc2IiwiYWdlX292ZXJfMTgiLHRydWVd~WyJjNTU0ODYyODA2MzVmZTRlIiwiYWRkcmVzcyIseyJjb3VudHJ5IjoiUk8iLCJfc2QiOlsiTGw0SnlHS2hCNFpZZGdkZy05LU5iTGZlaDVBQkdnYmRNVUpsZHNGVUJlOCIsIlpKc1NmZTVMWEFmVTQyYVBEMU9SdU1IblNqVWZ3NHVqeWZPdXhuaExDQ28iXX1d~WyJiNDhkMDc1YzExZGE2ZDAwIiwibG9jYWxpdHkiLCJDbHVqIl0~WyIwYTQwZTZjZDg0ZmJjNGU2IiwiUk8iXQ~eyJ0eXAiOiJrYitqd3QiLCJhbGciOiJFZERTQSJ9.eyJhdWQiOiJodHRwczovL290aGVyLmV4YW1wbGUiLCJub25jZSI6ImludGVyb3AtYzM4MmM5OWJjMjgwIiwiaWF0IjoxNzkyMjgxNjAwLCJzZF9oYXNoIjoiM243Q1hEQmk2T2FRYmg0YUQ2R3lxaHZWWGF5YXhfZFJNdjNZeHNZME5mTSJ9.NmNA2UuLcu2CkbufwjC4GcipNF9EwR5Di43bsRk-RXjPE-cWVS2eljbadOkZU1yQDkQH-yiYDh6e1fDsQXRYAg",
"issuerKey": {
"crv": "Ed25519",
"x": "-aHX28vHzHZU6u5ottr9OKLK2dDhU3l50i21w_Ry7Zw",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "interop-c382c99bc280",
"now": "2026-10-18T00:01:00.000Z",
"expectedTyp": null
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.kb-audience"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,68 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/sd-jwt-core.kb-sd-hash",
"artifact": "sdjwt-presentation",
"title": "a disclosure removed from the @sd-jwt/core presentation after key binding",
"source": "derived from sdjwt-presentation/sd-jwt-core.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/sd-jwt-core.valid",
"mutation": {
"producer": "a disclosure taken out of the @sd-jwt/core presentation after its key binding JWT was signed",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSJ9.eyJpc3MiOiJodHRwczovL2lzc3Vlci5sb3IuZXhhbXBsZSIsImlhdCI6MTc5MjI4MTYwMCwiZXhwIjoxODIzODE3NjAwLCJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJjVWJRWHNNaU9jTGxoTlNmaVo1MW5UaWdUaVRwY2xhQ1lsYy1Uc3JHWVhBIn0seyIuLi4iOiJSNjRmdGNLMW50Mnl1TktiVmJBRjg1M1dUelYyaWg3clRUS0NwNU00QmxnIn1dLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4IjoiSEZ5MHZ6dDNhWHhEZU1EbjY0Y2JYN3owdXVDbDh2MlZBb0VPTzNkd25kTSIsImt0eSI6Ik9LUCJ9fSwiX3NkIjpbIkNLdE5BaGFvTlMyY0h1U1hCeUJzclJHcTE2dmZBUTF6Tk1TUGs4ZktkTkkiLCJGQnlGeXlZWkUwMjdWU1NZeUVLTS03dUZMNTFSY09fdk9jUFdZWHVpU09vIiwiUGNEY2l0S0dJbm0wQmpBR0x5Q3ptaU52YU5aSGZZVl9GNmRWeUM1LWd1NCIsIlNyS3JyYk1wNWM2OG5FVnFmNmJ0VWFTYWwxV3dCc0J0OENJcUJHTGFTYmciLCJXajlCTkc4ZVhnWU1zd0tJVEhOd3kzQXdyV1hXVC1XMGRGbjFpSWdGdXRNIiwiblo0aUZuSlB2OTkyb2lGLVFJaFMwT1g5WDllM2FqODVKb0o0bnVzVU1jTSJdLCJfc2RfYWxnIjoic2hhLTI1NiJ9.Pqsg-0U-7cVdQqkjJ7qDg6e9fQpCa-EbhRwR9PpWszZkAxterCEgzsYk0dtC-REgTCuSRew50ZuAQQmiwE18Aw~WyIzNjQxOGIzNjIzZDM2Zjc2IiwiYWdlX292ZXJfMTgiLHRydWVd~WyJjNTU0ODYyODA2MzVmZTRlIiwiYWRkcmVzcyIseyJjb3VudHJ5IjoiUk8iLCJfc2QiOlsiTGw0SnlHS2hCNFpZZGdkZy05LU5iTGZlaDVBQkdnYmRNVUpsZHNGVUJlOCIsIlpKc1NmZTVMWEFmVTQyYVBEMU9SdU1IblNqVWZ3NHVqeWZPdXhuaExDQ28iXX1d~WyJiNDhkMDc1YzExZGE2ZDAwIiwibG9jYWxpdHkiLCJDbHVqIl0~eyJ0eXAiOiJrYitqd3QiLCJhbGciOiJFZERTQSJ9.eyJhdWQiOiJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUiLCJub25jZSI6ImludGVyb3AtYzM4MmM5OWJjMjgwIiwiaWF0IjoxNzkyMjgxNjAwLCJzZF9oYXNoIjoiM243Q1hEQmk2T2FRYmg0YUQ2R3lxaHZWWGF5YXhfZFJNdjNZeHNZME5mTSJ9.Rr9sBYmA9BEp-uSt_d4w854OLSM7S6Sm-L_UHPGTHwVLpY_hVmLilgbZ9KF-X6Mk29KSQEIanQKOW1dzGcQFAg",
"issuerKey": {
"crv": "Ed25519",
"x": "-aHX28vHzHZU6u5ottr9OKLK2dDhU3l50i21w_Ry7Zw",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "interop-c382c99bc280",
"now": "2026-10-18T00:01:00.000Z",
"expectedTyp": null
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.kb-sd-hash"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,71 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/sd-jwt-core.sd-alg",
"artifact": "sdjwt-presentation",
"title": "a token @sd-jwt/core issued with _sd_alg sha-384, which this verifier does not understand",
"source": "derived from sdjwt-presentation/sd-jwt-core.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/sd-jwt-core.valid",
"mutation": {
"producer": "@sd-jwt/core issued and presented the same claims with hashAlg sha-384 (another issuer key of its own)",
"changed": [
[
"issuerKey"
],
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSJ9.eyJpc3MiOiJodHRwczovL2lzc3Vlci5sb3IuZXhhbXBsZSIsImlhdCI6MTc5MjI4MTYwMCwiZXhwIjoxODIzODE3NjAwLCJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJUcURkRFVvX0pNa3NGT3J3Q3ZPS3JjajZaZXRWeC1qTkVHa0xhTVlGS0lZM3lmVDNkSzBWanlPRTBubWNESUZXIn0seyIuLi4iOiJWQ1RERXVkcUQxRHdlUTRfV1JFSHh5SWZFQzl1Z2hzODZKMGtYUEcwem5JUE1Sbm9vcnJYaVNhUTVVZXY5eFpSIn1dLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4IjoiaWhmNi1BVlhLdlpTTlo5bjZaU1ByWUtzTzZfNVdaQ3g2bHo4THRfM3FuYyIsImt0eSI6Ik9LUCJ9fSwiX3NkIjpbIjZOT0luMkU4NEpUbkJlZWpmZ1FfN3otakZqWWM0aWZWVGI1Y1FxYjhZajh6ZFFiQlB2QnNpZnNuNXBvS3N1cGwiLCJCbXlmRDZ0cHRrZDMtSXo4RTVtdjhQWmN3UWJYLURsSHljVVFyLVliU0VRNlZlTzRCVGdYdkE2aFlIekY5YVNqIiwiQnZjelJTOFl0cU93bkVLNEk5UTgyelpLUUw1clh0SU9tOEdEZE5tYThoVE5wb0d5TnBmTW9RZW9CdWJEZHBtUyIsIkNscmFHR3BlYVJHR0JpLTlPcThpN2RrSEhpbjhzbGxaWkc3VWE5bVc2a2I5NmNFM0dqR21RRFdDX3lqY0hESksiLCJfUTF2VkQ3bW1sQ1IySXhpUDR0WGJKM3pqQ3VGWGNOUjJ2X2hYVldWak1DMHRweFlfRzc5dm15UGNCRk1CV1FLIiwiZ1g4TU55MWIxd3dBajQwSk5oVzl0Qk1ickMxbjdjcXJyWVVWTFJnOXZ1c2szaGdrM0RYSnF2T1FnZW1haUJYaCJdLCJfc2RfYWxnIjoic2hhLTM4NCJ9.AZsWqI-NY3-ce3xfH3Fjt1z7nsF2F6eQMaNVfZb7zhEk3OclAfWlZ2kA9XyeBvaFWSLuy695ktSU0MxaCGwnBQ~WyJiZDdmODdlMjljNjRmZmFjIiwiYWdlX292ZXJfMTgiLHRydWVd~WyJiYjBjZDkxMzg2ZWZkNGI1IiwiYWRkcmVzcyIseyJjb3VudHJ5IjoiUk8iLCJfc2QiOlsiaFQwV0VOdUFJZE5PaUpfYUNMYnZQeG1YZmxHcEZqbTR2eTRvVTBCcUdOYkg0VnA3TW9rQ0VQb0JLWFBnSFM5QiIsInB0SzZTOUE1WlJzbnB0UWZ4QjBBZEdHbXc1YnFTalhkTjRvWkNJU0JLZjRUR0daVFJUUnlRWVdYYjlzeXROai0iXX1d~WyIwNzQ5Yjc5ZTVjMjVmY2RhIiwibG9jYWxpdHkiLCJDbHVqIl0~WyI4MTgwZTVjNDQyMzQyZjVlIiwiUk8iXQ~eyJ0eXAiOiJrYitqd3QiLCJhbGciOiJFZERTQSJ9.eyJhdWQiOiJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUiLCJub25jZSI6ImludGVyb3AtYzM4MmM5OWJjMjgwIiwiaWF0IjoxNzkyMjgxNjAwLCJzZF9oYXNoIjoiTlFRdGRHdVc3QmRadWpQUjBRYWRaQ21PMERaSTY3ZDBBMFd4TEZrOTRSaE5KYkd4ZXJhcXM2WDBDalQ3NVEwaSJ9.7yJQbLknl6-Miy4ITnhBhHCWXpslFPhMZewEQyC3bl20cB6QEG6C1SQtl9X7RKe5u3CVCGyFmrydYQ-bSfA7Cg",
"issuerKey": {
"crv": "Ed25519",
"x": "AxyFfp5Ynr1Ag33qsjnaN0R_mILDj8J10x-1vPCEgl8",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "interop-c382c99bc280",
"now": "2026-10-18T00:01:00.000Z",
"expectedTyp": null
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.sd-alg"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,68 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/sd-jwt-core.signature-kb",
"artifact": "sdjwt-presentation",
"title": "presented by @sd-jwt/core with a key binding JWT signed by another key than cnf.jwk",
"source": "derived from sdjwt-presentation/sd-jwt-core.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/sd-jwt-core.valid",
"mutation": {
"producer": "@sd-jwt/core presented the token with a key binding JWT of another key",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSJ9.eyJpc3MiOiJodHRwczovL2lzc3Vlci5sb3IuZXhhbXBsZSIsImlhdCI6MTc5MjI4MTYwMCwiZXhwIjoxODIzODE3NjAwLCJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJjVWJRWHNNaU9jTGxoTlNmaVo1MW5UaWdUaVRwY2xhQ1lsYy1Uc3JHWVhBIn0seyIuLi4iOiJSNjRmdGNLMW50Mnl1TktiVmJBRjg1M1dUelYyaWg3clRUS0NwNU00QmxnIn1dLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4IjoiSEZ5MHZ6dDNhWHhEZU1EbjY0Y2JYN3owdXVDbDh2MlZBb0VPTzNkd25kTSIsImt0eSI6Ik9LUCJ9fSwiX3NkIjpbIkNLdE5BaGFvTlMyY0h1U1hCeUJzclJHcTE2dmZBUTF6Tk1TUGs4ZktkTkkiLCJGQnlGeXlZWkUwMjdWU1NZeUVLTS03dUZMNTFSY09fdk9jUFdZWHVpU09vIiwiUGNEY2l0S0dJbm0wQmpBR0x5Q3ptaU52YU5aSGZZVl9GNmRWeUM1LWd1NCIsIlNyS3JyYk1wNWM2OG5FVnFmNmJ0VWFTYWwxV3dCc0J0OENJcUJHTGFTYmciLCJXajlCTkc4ZVhnWU1zd0tJVEhOd3kzQXdyV1hXVC1XMGRGbjFpSWdGdXRNIiwiblo0aUZuSlB2OTkyb2lGLVFJaFMwT1g5WDllM2FqODVKb0o0bnVzVU1jTSJdLCJfc2RfYWxnIjoic2hhLTI1NiJ9.Pqsg-0U-7cVdQqkjJ7qDg6e9fQpCa-EbhRwR9PpWszZkAxterCEgzsYk0dtC-REgTCuSRew50ZuAQQmiwE18Aw~WyIzNjQxOGIzNjIzZDM2Zjc2IiwiYWdlX292ZXJfMTgiLHRydWVd~WyJjNTU0ODYyODA2MzVmZTRlIiwiYWRkcmVzcyIseyJjb3VudHJ5IjoiUk8iLCJfc2QiOlsiTGw0SnlHS2hCNFpZZGdkZy05LU5iTGZlaDVBQkdnYmRNVUpsZHNGVUJlOCIsIlpKc1NmZTVMWEFmVTQyYVBEMU9SdU1IblNqVWZ3NHVqeWZPdXhuaExDQ28iXX1d~WyJiNDhkMDc1YzExZGE2ZDAwIiwibG9jYWxpdHkiLCJDbHVqIl0~WyIwYTQwZTZjZDg0ZmJjNGU2IiwiUk8iXQ~eyJ0eXAiOiJrYitqd3QiLCJhbGciOiJFZERTQSJ9.eyJhdWQiOiJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUiLCJub25jZSI6ImludGVyb3AtYzM4MmM5OWJjMjgwIiwiaWF0IjoxNzkyMjgxNjAwLCJzZF9oYXNoIjoiM243Q1hEQmk2T2FRYmg0YUQ2R3lxaHZWWGF5YXhfZFJNdjNZeHNZME5mTSJ9.rEJpb_jkTpXEe0iDbhE8KNPo2LWzRwdaFg88pJzE7nUqSx16N7TxK-rcIabqavi1NsFbPdUcW2mkn604zjYWDg",
"issuerKey": {
"crv": "Ed25519",
"x": "-aHX28vHzHZU6u5ottr9OKLK2dDhU3l50i21w_Ry7Zw",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "interop-c382c99bc280",
"now": "2026-10-18T00:01:00.000Z",
"expectedTyp": null
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.signature"
],
"levels": {
"integrity": "NOT_MEASURED",
"authenticity": "FAILED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,65 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/sd-jwt-core.typ",
"artifact": "sdjwt-presentation",
"title": "the untyped token of @sd-jwt/core under the default type of the verifier (an explicit ...+sd-jwt is required)",
"source": "derived from sdjwt-presentation/sd-jwt-core.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/sd-jwt-core.valid",
"mutation": {
"op": "remove",
"path": [
"expectedTyp"
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSJ9.eyJpc3MiOiJodHRwczovL2lzc3Vlci5sb3IuZXhhbXBsZSIsImlhdCI6MTc5MjI4MTYwMCwiZXhwIjoxODIzODE3NjAwLCJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJjVWJRWHNNaU9jTGxoTlNmaVo1MW5UaWdUaVRwY2xhQ1lsYy1Uc3JHWVhBIn0seyIuLi4iOiJSNjRmdGNLMW50Mnl1TktiVmJBRjg1M1dUelYyaWg3clRUS0NwNU00QmxnIn1dLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4IjoiSEZ5MHZ6dDNhWHhEZU1EbjY0Y2JYN3owdXVDbDh2MlZBb0VPTzNkd25kTSIsImt0eSI6Ik9LUCJ9fSwiX3NkIjpbIkNLdE5BaGFvTlMyY0h1U1hCeUJzclJHcTE2dmZBUTF6Tk1TUGs4ZktkTkkiLCJGQnlGeXlZWkUwMjdWU1NZeUVLTS03dUZMNTFSY09fdk9jUFdZWHVpU09vIiwiUGNEY2l0S0dJbm0wQmpBR0x5Q3ptaU52YU5aSGZZVl9GNmRWeUM1LWd1NCIsIlNyS3JyYk1wNWM2OG5FVnFmNmJ0VWFTYWwxV3dCc0J0OENJcUJHTGFTYmciLCJXajlCTkc4ZVhnWU1zd0tJVEhOd3kzQXdyV1hXVC1XMGRGbjFpSWdGdXRNIiwiblo0aUZuSlB2OTkyb2lGLVFJaFMwT1g5WDllM2FqODVKb0o0bnVzVU1jTSJdLCJfc2RfYWxnIjoic2hhLTI1NiJ9.Pqsg-0U-7cVdQqkjJ7qDg6e9fQpCa-EbhRwR9PpWszZkAxterCEgzsYk0dtC-REgTCuSRew50ZuAQQmiwE18Aw~WyIzNjQxOGIzNjIzZDM2Zjc2IiwiYWdlX292ZXJfMTgiLHRydWVd~WyJjNTU0ODYyODA2MzVmZTRlIiwiYWRkcmVzcyIseyJjb3VudHJ5IjoiUk8iLCJfc2QiOlsiTGw0SnlHS2hCNFpZZGdkZy05LU5iTGZlaDVBQkdnYmRNVUpsZHNGVUJlOCIsIlpKc1NmZTVMWEFmVTQyYVBEMU9SdU1IblNqVWZ3NHVqeWZPdXhuaExDQ28iXX1d~WyJiNDhkMDc1YzExZGE2ZDAwIiwibG9jYWxpdHkiLCJDbHVqIl0~WyIwYTQwZTZjZDg0ZmJjNGU2IiwiUk8iXQ~eyJ0eXAiOiJrYitqd3QiLCJhbGciOiJFZERTQSJ9.eyJhdWQiOiJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUiLCJub25jZSI6ImludGVyb3AtYzM4MmM5OWJjMjgwIiwiaWF0IjoxNzkyMjgxNjAwLCJzZF9oYXNoIjoiM243Q1hEQmk2T2FRYmg0YUQ2R3lxaHZWWGF5YXhfZFJNdjNZeHNZME5mTSJ9.Rr9sBYmA9BEp-uSt_d4w854OLSM7S6Sm-L_UHPGTHwVLpY_hVmLilgbZ9KF-X6Mk29KSQEIanQKOW1dzGcQFAg",
"issuerKey": {
"crv": "Ed25519",
"x": "-aHX28vHzHZU6u5ottr9OKLK2dDhU3l50i21w_Ry7Zw",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "interop-c382c99bc280",
"now": "2026-10-18T00:01:00.000Z"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.typ"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,68 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/sd-jwt-core.unreferenced",
"artifact": "sdjwt-presentation",
"title": "the value of a disclosure of @sd-jwt/core changed",
"source": "derived from sdjwt-presentation/sd-jwt-core.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": "sdjwt-presentation/sd-jwt-core.valid",
"mutation": {
"producer": "a disclosure of the @sd-jwt/core token with its value changed (no key binding in that presentation)",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSJ9.eyJpc3MiOiJodHRwczovL2lzc3Vlci5sb3IuZXhhbXBsZSIsImlhdCI6MTc5MjI4MTYwMCwiZXhwIjoxODIzODE3NjAwLCJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJjVWJRWHNNaU9jTGxoTlNmaVo1MW5UaWdUaVRwY2xhQ1lsYy1Uc3JHWVhBIn0seyIuLi4iOiJSNjRmdGNLMW50Mnl1TktiVmJBRjg1M1dUelYyaWg3clRUS0NwNU00QmxnIn1dLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4IjoiSEZ5MHZ6dDNhWHhEZU1EbjY0Y2JYN3owdXVDbDh2MlZBb0VPTzNkd25kTSIsImt0eSI6Ik9LUCJ9fSwiX3NkIjpbIkNLdE5BaGFvTlMyY0h1U1hCeUJzclJHcTE2dmZBUTF6Tk1TUGs4ZktkTkkiLCJGQnlGeXlZWkUwMjdWU1NZeUVLTS03dUZMNTFSY09fdk9jUFdZWHVpU09vIiwiUGNEY2l0S0dJbm0wQmpBR0x5Q3ptaU52YU5aSGZZVl9GNmRWeUM1LWd1NCIsIlNyS3JyYk1wNWM2OG5FVnFmNmJ0VWFTYWwxV3dCc0J0OENJcUJHTGFTYmciLCJXajlCTkc4ZVhnWU1zd0tJVEhOd3kzQXdyV1hXVC1XMGRGbjFpSWdGdXRNIiwiblo0aUZuSlB2OTkyb2lGLVFJaFMwT1g5WDllM2FqODVKb0o0bnVzVU1jTSJdLCJfc2RfYWxnIjoic2hhLTI1NiJ9.Pqsg-0U-7cVdQqkjJ7qDg6e9fQpCa-EbhRwR9PpWszZkAxterCEgzsYk0dtC-REgTCuSRew50ZuAQQmiwE18Aw~WyIzNjQxOGIzNjIzZDM2Zjc2IiwiYWdlX292ZXJfMTgiLGZhbHNlXQ~",
"issuerKey": {
"crv": "Ed25519",
"x": "-aHX28vHzHZU6u5ottr9OKLK2dDhU3l50i21w_Ry7Zw",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "interop-c382c99bc280",
"now": "2026-10-18T00:01:00.000Z",
"expectedTyp": null
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwt.unreferenced"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,59 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-presentation/sd-jwt-core.valid",
"artifact": "sdjwt-presentation",
"title": "an SD-JWT issued and presented by @sd-jwt/core (EdDSA): nested disclosures (address.locality), a list element, two decoys, a key binding JWT; the token carries no typ, so the verifier takes any (expectedTyp null)",
"source": "@sd-jwt/core 0.23.0 with jose 6.2.12 (interop/fixturi-interop-sdjwt.json of the identity component, generated 2026-10-18; its test keys made and discarded at generation)",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced"
],
"base": null,
"mutation": null,
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSJ9.eyJpc3MiOiJodHRwczovL2lzc3Vlci5sb3IuZXhhbXBsZSIsImlhdCI6MTc5MjI4MTYwMCwiZXhwIjoxODIzODE3NjAwLCJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJjVWJRWHNNaU9jTGxoTlNmaVo1MW5UaWdUaVRwY2xhQ1lsYy1Uc3JHWVhBIn0seyIuLi4iOiJSNjRmdGNLMW50Mnl1TktiVmJBRjg1M1dUelYyaWg3clRUS0NwNU00QmxnIn1dLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4IjoiSEZ5MHZ6dDNhWHhEZU1EbjY0Y2JYN3owdXVDbDh2MlZBb0VPTzNkd25kTSIsImt0eSI6Ik9LUCJ9fSwiX3NkIjpbIkNLdE5BaGFvTlMyY0h1U1hCeUJzclJHcTE2dmZBUTF6Tk1TUGs4ZktkTkkiLCJGQnlGeXlZWkUwMjdWU1NZeUVLTS03dUZMNTFSY09fdk9jUFdZWHVpU09vIiwiUGNEY2l0S0dJbm0wQmpBR0x5Q3ptaU52YU5aSGZZVl9GNmRWeUM1LWd1NCIsIlNyS3JyYk1wNWM2OG5FVnFmNmJ0VWFTYWwxV3dCc0J0OENJcUJHTGFTYmciLCJXajlCTkc4ZVhnWU1zd0tJVEhOd3kzQXdyV1hXVC1XMGRGbjFpSWdGdXRNIiwiblo0aUZuSlB2OTkyb2lGLVFJaFMwT1g5WDllM2FqODVKb0o0bnVzVU1jTSJdLCJfc2RfYWxnIjoic2hhLTI1NiJ9.Pqsg-0U-7cVdQqkjJ7qDg6e9fQpCa-EbhRwR9PpWszZkAxterCEgzsYk0dtC-REgTCuSRew50ZuAQQmiwE18Aw~WyIzNjQxOGIzNjIzZDM2Zjc2IiwiYWdlX292ZXJfMTgiLHRydWVd~WyJjNTU0ODYyODA2MzVmZTRlIiwiYWRkcmVzcyIseyJjb3VudHJ5IjoiUk8iLCJfc2QiOlsiTGw0SnlHS2hCNFpZZGdkZy05LU5iTGZlaDVBQkdnYmRNVUpsZHNGVUJlOCIsIlpKc1NmZTVMWEFmVTQyYVBEMU9SdU1IblNqVWZ3NHVqeWZPdXhuaExDQ28iXX1d~WyJiNDhkMDc1YzExZGE2ZDAwIiwibG9jYWxpdHkiLCJDbHVqIl0~WyIwYTQwZTZjZDg0ZmJjNGU2IiwiUk8iXQ~eyJ0eXAiOiJrYitqd3QiLCJhbGciOiJFZERTQSJ9.eyJhdWQiOiJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUiLCJub25jZSI6ImludGVyb3AtYzM4MmM5OWJjMjgwIiwiaWF0IjoxNzkyMjgxNjAwLCJzZF9oYXNoIjoiM243Q1hEQmk2T2FRYmg0YUQ2R3lxaHZWWGF5YXhfZFJNdjNZeHNZME5mTSJ9.Rr9sBYmA9BEp-uSt_d4w854OLSM7S6Sm-L_UHPGTHwVLpY_hVmLilgbZ9KF-X6Mk29KSQEIanQKOW1dzGcQFAg",
"issuerKey": {
"crv": "Ed25519",
"x": "-aHX28vHzHZU6u5ottr9OKLK2dDhU3l50i21w_Ry7Zw",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "interop-c382c99bc280",
"now": "2026-10-18T00:01:00.000Z",
"expectedTyp": null
},
"expected": {
"verdict": "VALID",
"failed": [],
"levels": {
"integrity": "PASSED",
"authenticity": "PASSED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,69 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/aere-no-status.valid",
"artifact": "sdjwt-vc-presentation",
"title": "a credential that names no status, judged without a list",
"source": "producers (sdjwt-vc.mjs: issueSdJwtVc, presentSdJwtVc, issueStatusListJwt), three hybrid key pairs made and discarded at generation",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": null,
"mutation": null,
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImRjK3NkLWp3dCJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsImdpdmVuX25hbWUiOiJBZGEiLCJmYW1pbHlfbmFtZSI6IkV4YW1wbGUiLCJhZ2Vfb3Zlcl8xOCI6dHJ1ZSwibmF0aW9uYWxpdGllcyI6WyJSTyIsIkRFIl0sImFkZHJlc3MiOnsibG9jYWxpdHkiOiJDbHVqIiwiY291bnRyeSI6IlJPIn0sImlzc3VpbmdfYXV0aG9yaXR5IjoiRXhhbXBsZSBBdXRob3JpdHkiLCJpc3N1aW5nX2NvdW50cnkiOiJSTyIsIl9zZCI6WyI0VXV2UWZmMHl4aGo0QTBCb01fVENZbVoxNnRER1hoQ25DbjMteWZKdl9vIl0sIl9zZF9hbGciOiJzaGEtMjU2IiwiaXNzIjoiaHR0cHM6Ly9pc3N1ZXIuZXhhbXBsZSIsImlhdCI6MTc5MjMwMjU1MiwiZXhwIjoxODIzODM4NTUyLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4Ijoid3NfOVdBVGxJdDNXOTZKVS02Y1ByLWNhbGt6SGZNSTZhdWVrM0s1OVZEUSIsImt0eSI6Ik9LUCJ9fX0.mB0Tj6473oyfbSJfzoMViYIOuV6nc-6zpQK2FkNOpGGFDMDD_DIey_EiU0aGSsyBrjRL2GV4bUPQHcx7OiObCg~WyJKVExRdThVWkdDV2lZLU5LYlB6bFdRIiwiYmlydGhkYXRlIiwiMTk5MC0wMS0wMSJd~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE3OTIzMDI1NTIsImF1ZCI6Imh0dHBzOi8vdmVyaWZpZXIuZXhhbXBsZSIsIm5vbmNlIjoibi1hOWRkNzRhMDM5NzBhY2RiIiwic2RfaGFzaCI6ImFGYmZGMFRPa3JfV0pHTFlXZ2FEQkdFY3M2QUVTUFVGSEZOUGtZOFo0VTQifQ.UXnc093aVrHMIfdNIewXXsoX_MhO_2G_Qba8RZ9G6vF7iTdUUX_VkclxlhjgfJOzz0z6M4fOrKDTFtn_LUYLCA",
"issuerKey": {
"crv": "Ed25519",
"x": "xWqc4dXP9LHY_Ia09ijwYuMFxHUjbo2HZOvcquHT0eE",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-a9dd74a03970acdb",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example",
"expectedVct": "urn:eudi:pid:1"
},
"expected": {
"verdict": "VALID",
"failed": [],
"levels": {
"integrity": "PASSED",
"authenticity": "PASSED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,76 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/aere-pid-8-bits.valid",
"artifact": "sdjwt-vc-presentation",
"title": "the same credential with a status list of 8 bits per entry (all VALID)",
"source": "producers (sdjwt-vc.mjs: issueSdJwtVc, presentSdJwtVc, issueStatusListJwt), three hybrid key pairs made and discarded at generation",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": "sdjwt-vc-presentation/aere-pid.valid",
"mutation": {
"op": "set",
"path": [
"statusListJwt"
],
"value": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjMwMjU1MiwiZXhwIjoxNzkyMzA2MTUyLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjo4LCJsc3QiOiJlTnBqWUVBRkFBQVFBQUUifX0.uFiiS91zq-P5V66asGF9tl98Kejm8sfHK2y0EjlSn8NCXvpF7g3oQueidvGR8hFzzXlrrFCey6eq7FWrsKVpCw"
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImRjK3NkLWp3dCJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsInN0YXR1cyI6eyJzdGF0dXNfbGlzdCI6eyJpZHgiOjUsInVyaSI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUvc3RhdHVzL3BpZC8xIn19LCJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJtZlVYbmZPYWlKNXlSbVNuMjZMYmVrV1F5TGFJZnRlVFQ0ckJBZ1FEZU9BIn0seyIuLi4iOiJqaG1kQVhKZ213dVhNbHZIVXI5NXRXUFFISVJlNmRiRkI2c2FmN09qUXdFIn1dLCJpc3N1aW5nX2F1dGhvcml0eSI6IkV4YW1wbGUgQXV0aG9yaXR5IiwiaXNzdWluZ19jb3VudHJ5IjoiUk8iLCJfc2QiOlsiMFluYktwU0hQeDgySDlfcFlFd2pIR2trRDZsYTZzT0lXMDI2VUR3bm5KSSIsIjBld2puX2x5UTExZHFlbDZZYWpDYXA4MzMyU0JKRzAtdWgySmx1UUFrZTQiLCJBNWlQMVFHREVUOHR6VnJvQ2oza1h1c0w5VFJDVzh0Wjdzdy1Fek1ob3l3IiwiQkswSzM3V3ZYVVotcy1CTE5ZQ0tYdmdtUkV3TFFvQi0wSGwyQkxkMDVudyIsImJ5R3d1ZGlONXdoUWpRSGZQQmZHLWhubGFnWkd2S1hXS2VqcXEtMmpsU00iLCJoTTZ2U3Q0NkEtVFVlbDFqT3B2OGplTV96WnRDZklnS1BRdFpQcHRHMzVZIiwidjloYXQ5YUw1elNUejVSem81RGloZ1NEUEpSeWVZaXV2Ykd0R3Vmb2dDRSJdLCJfc2RfYWxnIjoic2hhLTI1NiIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUiLCJpYXQiOjE3OTIzMDI1NTIsImV4cCI6MTgyMzgzODU1MiwibmJmIjoxNzkyMzAyNTUyLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4Ijoid3NfOVdBVGxJdDNXOTZKVS02Y1ByLWNhbGt6SGZNSTZhdWVrM0s1OVZEUSIsImt0eSI6Ik9LUCJ9fX0.xQWADsMnzqfN1Vdk-GFoBy5EuJ1uKCH58pg_8bg6cA2cZyFO0OQlmiEaoj-996ZpRWriNA-obPdhtsg3Ov3iCQ~WyJRSVY1ZUJweEtiTVhEMkQyaTZYRVFRIiwiYmlydGhkYXRlIiwiMTk5MC0wMS0wMSJd~WyJ1Q3Rhbnd3eFh1ajN0ZHc0LWo0U01BIiwiYWdlX292ZXJfMTgiLHRydWVd~WyJQZGNUVFNUU3FDRXZwZnh5UXdUZ1d3IiwiUk8iXQ~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE3OTIzMDI1NTIsImF1ZCI6Imh0dHBzOi8vdmVyaWZpZXIuZXhhbXBsZSIsIm5vbmNlIjoibi1hOWRkNzRhMDM5NzBhY2RiIiwic2RfaGFzaCI6IkN0VWxlVmYzS1lHdGNkOU8xS0pzNzZCcTdHaUJqTm56eldhSVk0SmJvMW8ifQ.rF1INd7UF2UUIgw3DWkzI524ASp80-I_VTlMwbvbNVmVmGz9z4zL47aTIfl0AE9tUWrp4EUzk94XbqbTEyr4Cw",
"issuerKey": {
"crv": "Ed25519",
"x": "xWqc4dXP9LHY_Ia09ijwYuMFxHUjbo2HZOvcquHT0eE",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-a9dd74a03970acdb",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example",
"expectedVct": "urn:eudi:pid:1",
"statusListJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjMwMjU1MiwiZXhwIjoxNzkyMzA2MTUyLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjo4LCJsc3QiOiJlTnBqWUVBRkFBQVFBQUUifX0.uFiiS91zq-P5V66asGF9tl98Kejm8sfHK2y0EjlSn8NCXvpF7g3oQueidvGR8hFzzXlrrFCey6eq7FWrsKVpCw"
},
"expected": {
"verdict": "VALID",
"failed": [],
"levels": {
"integrity": "PASSED",
"authenticity": "PASSED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,70 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/aere-pid-status-waived.partial",
"artifact": "sdjwt-vc-presentation",
"title": "the same credential without its list, the verifier waiving the status (requireStatus false): nothing fails, the status it names was not judged, so it is not VALID",
"source": "producers (sdjwt-vc.mjs: issueSdJwtVc, presentSdJwtVc, issueStatusListJwt), three hybrid key pairs made and discarded at generation",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": null,
"mutation": null,
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImRjK3NkLWp3dCJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsInN0YXR1cyI6eyJzdGF0dXNfbGlzdCI6eyJpZHgiOjUsInVyaSI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUvc3RhdHVzL3BpZC8xIn19LCJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJtZlVYbmZPYWlKNXlSbVNuMjZMYmVrV1F5TGFJZnRlVFQ0ckJBZ1FEZU9BIn0seyIuLi4iOiJqaG1kQVhKZ213dVhNbHZIVXI5NXRXUFFISVJlNmRiRkI2c2FmN09qUXdFIn1dLCJpc3N1aW5nX2F1dGhvcml0eSI6IkV4YW1wbGUgQXV0aG9yaXR5IiwiaXNzdWluZ19jb3VudHJ5IjoiUk8iLCJfc2QiOlsiMFluYktwU0hQeDgySDlfcFlFd2pIR2trRDZsYTZzT0lXMDI2VUR3bm5KSSIsIjBld2puX2x5UTExZHFlbDZZYWpDYXA4MzMyU0JKRzAtdWgySmx1UUFrZTQiLCJBNWlQMVFHREVUOHR6VnJvQ2oza1h1c0w5VFJDVzh0Wjdzdy1Fek1ob3l3IiwiQkswSzM3V3ZYVVotcy1CTE5ZQ0tYdmdtUkV3TFFvQi0wSGwyQkxkMDVudyIsImJ5R3d1ZGlONXdoUWpRSGZQQmZHLWhubGFnWkd2S1hXS2VqcXEtMmpsU00iLCJoTTZ2U3Q0NkEtVFVlbDFqT3B2OGplTV96WnRDZklnS1BRdFpQcHRHMzVZIiwidjloYXQ5YUw1elNUejVSem81RGloZ1NEUEpSeWVZaXV2Ykd0R3Vmb2dDRSJdLCJfc2RfYWxnIjoic2hhLTI1NiIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUiLCJpYXQiOjE3OTIzMDI1NTIsImV4cCI6MTgyMzgzODU1MiwibmJmIjoxNzkyMzAyNTUyLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4Ijoid3NfOVdBVGxJdDNXOTZKVS02Y1ByLWNhbGt6SGZNSTZhdWVrM0s1OVZEUSIsImt0eSI6Ik9LUCJ9fX0.xQWADsMnzqfN1Vdk-GFoBy5EuJ1uKCH58pg_8bg6cA2cZyFO0OQlmiEaoj-996ZpRWriNA-obPdhtsg3Ov3iCQ~WyJRSVY1ZUJweEtiTVhEMkQyaTZYRVFRIiwiYmlydGhkYXRlIiwiMTk5MC0wMS0wMSJd~WyJ1Q3Rhbnd3eFh1ajN0ZHc0LWo0U01BIiwiYWdlX292ZXJfMTgiLHRydWVd~WyJQZGNUVFNUU3FDRXZwZnh5UXdUZ1d3IiwiUk8iXQ~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE3OTIzMDI1NTIsImF1ZCI6Imh0dHBzOi8vdmVyaWZpZXIuZXhhbXBsZSIsIm5vbmNlIjoibi1hOWRkNzRhMDM5NzBhY2RiIiwic2RfaGFzaCI6IkN0VWxlVmYzS1lHdGNkOU8xS0pzNzZCcTdHaUJqTm56eldhSVk0SmJvMW8ifQ.rF1INd7UF2UUIgw3DWkzI524ASp80-I_VTlMwbvbNVmVmGz9z4zL47aTIfl0AE9tUWrp4EUzk94XbqbTEyr4Cw",
"issuerKey": {
"crv": "Ed25519",
"x": "xWqc4dXP9LHY_Ia09ijwYuMFxHUjbo2HZOvcquHT0eE",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-a9dd74a03970acdb",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example",
"expectedVct": "urn:eudi:pid:1",
"requireStatus": false
},
"expected": {
"verdict": "PARTIAL",
"failed": [],
"levels": {
"integrity": "NOT_MEASURED",
"authenticity": "PASSED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,83 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/aere-pid.disclosed-protected",
"artifact": "sdjwt-vc-presentation",
"title": "the status claim made selectively disclosable, and disclosed",
"source": "derived from sdjwt-vc-presentation/aere-pid.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": "sdjwt-vc-presentation/aere-pid.valid",
"mutation": {
"producer": "the issuer put status behind a disclosure (no key binding in this token)",
"changed": [
[
"requireKeyBinding"
],
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImRjK3NkLWp3dCJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUiLCJpYXQiOjE3OTIzMDI1NTIsImV4cCI6MTgyMzgzODU1MiwiX3NkX2FsZyI6InNoYS0yNTYiLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4Ijoid3NfOVdBVGxJdDNXOTZKVS02Y1ByLWNhbGt6SGZNSTZhdWVrM0s1OVZEUSIsImt0eSI6Ik9LUCJ9fSwiX3NkIjpbIkRwa05uSmVBamRVMHFSdEJqdV9DdGNBdmNDN2lmaXFEbkpFZk5Kck81U1EiXX0.ZshknlcwIGLJQmqM167plJQIoD73pIcZU4_MPSvCOsFI6k7IiQzFf7raCHTWWyhK1IjwrWMJ4cP5zAw0UWc_BQ~WyJzYWx0LXMiLCJzdGF0dXMiLHsic3RhdHVzX2xpc3QiOnsiaWR4IjoxLCJ1cmkiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSJ9fV0~",
"issuerKey": {
"crv": "Ed25519",
"x": "xWqc4dXP9LHY_Ia09ijwYuMFxHUjbo2HZOvcquHT0eE",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-a9dd74a03970acdb",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example",
"expectedVct": "urn:eudi:pid:1",
"statusListJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjMwMjU1MiwiZXhwIjoxNzkyMzA2MTUyLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoxLCJsc3QiOiJlTnBqWUFBQUFBSUFBUSJ9fQ.-LALHjNMKDkk0wbZvjXQjh-yuGRi-Jz0ZV3kYmT1K5KVRjPnKXZBB7H6SDd4Mrt15-mYduZgcM3LH8zq5w3CBQ",
"requireKeyBinding": false
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwtvc.disclosed-protected"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,83 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/aere-pid.form-idx",
"artifact": "sdjwt-vc-presentation",
"title": "a status reference with a negative index",
"source": "derived from sdjwt-vc-presentation/aere-pid.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": "sdjwt-vc-presentation/aere-pid.valid",
"mutation": {
"producer": "the issuer signed status.status_list.idx -1 (no key binding in this token)",
"changed": [
[
"requireKeyBinding"
],
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImRjK3NkLWp3dCJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUiLCJpYXQiOjE3OTIzMDI1NTIsImV4cCI6MTgyMzgzODU1MiwiX3NkX2FsZyI6InNoYS0yNTYiLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4Ijoid3NfOVdBVGxJdDNXOTZKVS02Y1ByLWNhbGt6SGZNSTZhdWVrM0s1OVZEUSIsImt0eSI6Ik9LUCJ9fSwic3RhdHVzIjp7InN0YXR1c19saXN0Ijp7ImlkeCI6LTEsInVyaSI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUvc3RhdHVzL3BpZC8xIn19fQ.Fa2p9WGijm3pj2YeK7XO1g5MWt1Q9ZOv-HfBK9MB3IpEvgfJXiBLhazP-PXWWYnlHhcxR7rXOkSeujXIoR2ABw~",
"issuerKey": {
"crv": "Ed25519",
"x": "xWqc4dXP9LHY_Ia09ijwYuMFxHUjbo2HZOvcquHT0eE",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-a9dd74a03970acdb",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example",
"expectedVct": "urn:eudi:pid:1",
"statusListJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjMwMjU1MiwiZXhwIjoxNzkyMzA2MTUyLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoxLCJsc3QiOiJlTnBqWUFBQUFBSUFBUSJ9fQ.-LALHjNMKDkk0wbZvjXQjh-yuGRi-Jz0ZV3kYmT1K5KVRjPnKXZBB7H6SDd4Mrt15-mYduZgcM3LH8zq5w3CBQ",
"requireKeyBinding": false
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwtvc.form"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,83 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/aere-pid.form-integrity",
"artifact": "sdjwt-vc-presentation",
"title": "a vct#integrity that is a number",
"source": "derived from sdjwt-vc-presentation/aere-pid.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": "sdjwt-vc-presentation/aere-pid.valid",
"mutation": {
"producer": "the issuer signed vct#integrity 7 (no key binding in this token)",
"changed": [
[
"requireKeyBinding"
],
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImRjK3NkLWp3dCJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUiLCJpYXQiOjE3OTIzMDI1NTIsImV4cCI6MTgyMzgzODU1MiwiX3NkX2FsZyI6InNoYS0yNTYiLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4Ijoid3NfOVdBVGxJdDNXOTZKVS02Y1ByLWNhbGt6SGZNSTZhdWVrM0s1OVZEUSIsImt0eSI6Ik9LUCJ9fSwidmN0I2ludGVncml0eSI6N30.KpUk6XDQMp6dudRtH0jboaIqncCm-JwWKCPWtT8E9W2r-i8Oxc93tvxfevtYRkfswsdO0q1joNzd2g-HkpyGDQ~",
"issuerKey": {
"crv": "Ed25519",
"x": "xWqc4dXP9LHY_Ia09ijwYuMFxHUjbo2HZOvcquHT0eE",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-a9dd74a03970acdb",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example",
"expectedVct": "urn:eudi:pid:1",
"statusListJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjMwMjU1MiwiZXhwIjoxNzkyMzA2MTUyLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoxLCJsc3QiOiJlTnBqWUFBQUFBSUFBUSJ9fQ.-LALHjNMKDkk0wbZvjXQjh-yuGRi-Jz0ZV3kYmT1K5KVRjPnKXZBB7H6SDd4Mrt15-mYduZgcM3LH8zq5w3CBQ",
"requireKeyBinding": false
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwtvc.form"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,83 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/aere-pid.form-status",
"artifact": "sdjwt-vc-presentation",
"title": "a status claim that is a string",
"source": "derived from sdjwt-vc-presentation/aere-pid.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": "sdjwt-vc-presentation/aere-pid.valid",
"mutation": {
"producer": "the issuer signed status \"revoked\" (no key binding in this token)",
"changed": [
[
"requireKeyBinding"
],
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImRjK3NkLWp3dCJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUiLCJpYXQiOjE3OTIzMDI1NTIsImV4cCI6MTgyMzgzODU1MiwiX3NkX2FsZyI6InNoYS0yNTYiLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4Ijoid3NfOVdBVGxJdDNXOTZKVS02Y1ByLWNhbGt6SGZNSTZhdWVrM0s1OVZEUSIsImt0eSI6Ik9LUCJ9fSwic3RhdHVzIjoicmV2b2tlZCJ9.3bZlQeCXOmnkJ_WipORhYzEa_eDZ0Xpt8qNOwKPTVSsJT_sOPyfzxVsREtI1C8Nn78fF-7SrXnwbsxpepiI_Aw~",
"issuerKey": {
"crv": "Ed25519",
"x": "xWqc4dXP9LHY_Ia09ijwYuMFxHUjbo2HZOvcquHT0eE",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-a9dd74a03970acdb",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example",
"expectedVct": "urn:eudi:pid:1",
"statusListJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjMwMjU1MiwiZXhwIjoxNzkyMzA2MTUyLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoxLCJsc3QiOiJlTnBqWUFBQUFBSUFBUSJ9fQ.-LALHjNMKDkk0wbZvjXQjh-yuGRi-Jz0ZV3kYmT1K5KVRjPnKXZBB7H6SDd4Mrt15-mYduZgcM3LH8zq5w3CBQ",
"requireKeyBinding": false
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwtvc.form"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,78 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/aere-pid.status-index",
"artifact": "sdjwt-vc-presentation",
"title": "the list handed is shorter than the index the credential names",
"source": "derived from sdjwt-vc-presentation/aere-pid.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": "sdjwt-vc-presentation/aere-pid.valid",
"mutation": {
"op": "set",
"path": [
"statusListJwt"
],
"value": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjMwMjU1Miwic3RhdHVzX2xpc3QiOnsiYml0cyI6OCwibHN0IjoiZU5wallHQmdBQUFBQkFBQiJ9fQ.K7O0Lgxk_ze_VvWSUnv92kKNVeaytqlH5qc-dGTXH8HGBVOUZgD7CG19SGytHkjphiZD4Ym-TqeYqSOjH_SzCw"
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImRjK3NkLWp3dCJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsInN0YXR1cyI6eyJzdGF0dXNfbGlzdCI6eyJpZHgiOjUsInVyaSI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUvc3RhdHVzL3BpZC8xIn19LCJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJtZlVYbmZPYWlKNXlSbVNuMjZMYmVrV1F5TGFJZnRlVFQ0ckJBZ1FEZU9BIn0seyIuLi4iOiJqaG1kQVhKZ213dVhNbHZIVXI5NXRXUFFISVJlNmRiRkI2c2FmN09qUXdFIn1dLCJpc3N1aW5nX2F1dGhvcml0eSI6IkV4YW1wbGUgQXV0aG9yaXR5IiwiaXNzdWluZ19jb3VudHJ5IjoiUk8iLCJfc2QiOlsiMFluYktwU0hQeDgySDlfcFlFd2pIR2trRDZsYTZzT0lXMDI2VUR3bm5KSSIsIjBld2puX2x5UTExZHFlbDZZYWpDYXA4MzMyU0JKRzAtdWgySmx1UUFrZTQiLCJBNWlQMVFHREVUOHR6VnJvQ2oza1h1c0w5VFJDVzh0Wjdzdy1Fek1ob3l3IiwiQkswSzM3V3ZYVVotcy1CTE5ZQ0tYdmdtUkV3TFFvQi0wSGwyQkxkMDVudyIsImJ5R3d1ZGlONXdoUWpRSGZQQmZHLWhubGFnWkd2S1hXS2VqcXEtMmpsU00iLCJoTTZ2U3Q0NkEtVFVlbDFqT3B2OGplTV96WnRDZklnS1BRdFpQcHRHMzVZIiwidjloYXQ5YUw1elNUejVSem81RGloZ1NEUEpSeWVZaXV2Ykd0R3Vmb2dDRSJdLCJfc2RfYWxnIjoic2hhLTI1NiIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUiLCJpYXQiOjE3OTIzMDI1NTIsImV4cCI6MTgyMzgzODU1MiwibmJmIjoxNzkyMzAyNTUyLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4Ijoid3NfOVdBVGxJdDNXOTZKVS02Y1ByLWNhbGt6SGZNSTZhdWVrM0s1OVZEUSIsImt0eSI6Ik9LUCJ9fX0.xQWADsMnzqfN1Vdk-GFoBy5EuJ1uKCH58pg_8bg6cA2cZyFO0OQlmiEaoj-996ZpRWriNA-obPdhtsg3Ov3iCQ~WyJRSVY1ZUJweEtiTVhEMkQyaTZYRVFRIiwiYmlydGhkYXRlIiwiMTk5MC0wMS0wMSJd~WyJ1Q3Rhbnd3eFh1ajN0ZHc0LWo0U01BIiwiYWdlX292ZXJfMTgiLHRydWVd~WyJQZGNUVFNUU3FDRXZwZnh5UXdUZ1d3IiwiUk8iXQ~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE3OTIzMDI1NTIsImF1ZCI6Imh0dHBzOi8vdmVyaWZpZXIuZXhhbXBsZSIsIm5vbmNlIjoibi1hOWRkNzRhMDM5NzBhY2RiIiwic2RfaGFzaCI6IkN0VWxlVmYzS1lHdGNkOU8xS0pzNzZCcTdHaUJqTm56eldhSVk0SmJvMW8ifQ.rF1INd7UF2UUIgw3DWkzI524ASp80-I_VTlMwbvbNVmVmGz9z4zL47aTIfl0AE9tUWrp4EUzk94XbqbTEyr4Cw",
"issuerKey": {
"crv": "Ed25519",
"x": "xWqc4dXP9LHY_Ia09ijwYuMFxHUjbo2HZOvcquHT0eE",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-a9dd74a03970acdb",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example",
"expectedVct": "urn:eudi:pid:1",
"statusListJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjMwMjU1Miwic3RhdHVzX2xpc3QiOnsiYml0cyI6OCwibHN0IjoiZU5wallHQmdBQUFBQkFBQiJ9fQ.K7O0Lgxk_ze_VvWSUnv92kKNVeaytqlH5qc-dGTXH8HGBVOUZgD7CG19SGytHkjphiZD4Ym-TqeYqSOjH_SzCw"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwtvc.status-index"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,78 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/aere-pid.status-list-expired",
"artifact": "sdjwt-vc-presentation",
"title": "the list handed expired before the verifier clock",
"source": "derived from sdjwt-vc-presentation/aere-pid.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": "sdjwt-vc-presentation/aere-pid.valid",
"mutation": {
"op": "set",
"path": [
"statusListJwt"
],
"value": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjMwMjU1MiwiZXhwIjoxNzkyMzAyNTgyLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoxLCJsc3QiOiJlTnBqWUFBQUFBSUFBUSJ9fQ.OygFuUeCnTQ0RMOF1ABDYUVwJIY4XOgSt1KTFRrmfBZ7WQLtQifeOaSZDRjjRMmi7KGRVXtnSN6g7ADPboCaDg"
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImRjK3NkLWp3dCJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsInN0YXR1cyI6eyJzdGF0dXNfbGlzdCI6eyJpZHgiOjUsInVyaSI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUvc3RhdHVzL3BpZC8xIn19LCJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJtZlVYbmZPYWlKNXlSbVNuMjZMYmVrV1F5TGFJZnRlVFQ0ckJBZ1FEZU9BIn0seyIuLi4iOiJqaG1kQVhKZ213dVhNbHZIVXI5NXRXUFFISVJlNmRiRkI2c2FmN09qUXdFIn1dLCJpc3N1aW5nX2F1dGhvcml0eSI6IkV4YW1wbGUgQXV0aG9yaXR5IiwiaXNzdWluZ19jb3VudHJ5IjoiUk8iLCJfc2QiOlsiMFluYktwU0hQeDgySDlfcFlFd2pIR2trRDZsYTZzT0lXMDI2VUR3bm5KSSIsIjBld2puX2x5UTExZHFlbDZZYWpDYXA4MzMyU0JKRzAtdWgySmx1UUFrZTQiLCJBNWlQMVFHREVUOHR6VnJvQ2oza1h1c0w5VFJDVzh0Wjdzdy1Fek1ob3l3IiwiQkswSzM3V3ZYVVotcy1CTE5ZQ0tYdmdtUkV3TFFvQi0wSGwyQkxkMDVudyIsImJ5R3d1ZGlONXdoUWpRSGZQQmZHLWhubGFnWkd2S1hXS2VqcXEtMmpsU00iLCJoTTZ2U3Q0NkEtVFVlbDFqT3B2OGplTV96WnRDZklnS1BRdFpQcHRHMzVZIiwidjloYXQ5YUw1elNUejVSem81RGloZ1NEUEpSeWVZaXV2Ykd0R3Vmb2dDRSJdLCJfc2RfYWxnIjoic2hhLTI1NiIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUiLCJpYXQiOjE3OTIzMDI1NTIsImV4cCI6MTgyMzgzODU1MiwibmJmIjoxNzkyMzAyNTUyLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4Ijoid3NfOVdBVGxJdDNXOTZKVS02Y1ByLWNhbGt6SGZNSTZhdWVrM0s1OVZEUSIsImt0eSI6Ik9LUCJ9fX0.xQWADsMnzqfN1Vdk-GFoBy5EuJ1uKCH58pg_8bg6cA2cZyFO0OQlmiEaoj-996ZpRWriNA-obPdhtsg3Ov3iCQ~WyJRSVY1ZUJweEtiTVhEMkQyaTZYRVFRIiwiYmlydGhkYXRlIiwiMTk5MC0wMS0wMSJd~WyJ1Q3Rhbnd3eFh1ajN0ZHc0LWo0U01BIiwiYWdlX292ZXJfMTgiLHRydWVd~WyJQZGNUVFNUU3FDRXZwZnh5UXdUZ1d3IiwiUk8iXQ~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE3OTIzMDI1NTIsImF1ZCI6Imh0dHBzOi8vdmVyaWZpZXIuZXhhbXBsZSIsIm5vbmNlIjoibi1hOWRkNzRhMDM5NzBhY2RiIiwic2RfaGFzaCI6IkN0VWxlVmYzS1lHdGNkOU8xS0pzNzZCcTdHaUJqTm56eldhSVk0SmJvMW8ifQ.rF1INd7UF2UUIgw3DWkzI524ASp80-I_VTlMwbvbNVmVmGz9z4zL47aTIfl0AE9tUWrp4EUzk94XbqbTEyr4Cw",
"issuerKey": {
"crv": "Ed25519",
"x": "xWqc4dXP9LHY_Ia09ijwYuMFxHUjbo2HZOvcquHT0eE",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-a9dd74a03970acdb",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example",
"expectedVct": "urn:eudi:pid:1",
"statusListJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjMwMjU1MiwiZXhwIjoxNzkyMzAyNTgyLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoxLCJsc3QiOiJlTnBqWUFBQUFBSUFBUSJ9fQ.OygFuUeCnTQ0RMOF1ABDYUVwJIY4XOgSt1KTFRrmfBZ7WQLtQifeOaSZDRjjRMmi7KGRVXtnSN6g7ADPboCaDg"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwtvc.status-list"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,78 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/aere-pid.status-list-no-iat",
"artifact": "sdjwt-vc-presentation",
"title": "the list handed has no iat",
"source": "derived from sdjwt-vc-presentation/aere-pid.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": "sdjwt-vc-presentation/aere-pid.valid",
"mutation": {
"op": "set",
"path": [
"statusListJwt"
],
"value": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImV4cCI6MTc5MjMwNjE1Miwic3RhdHVzX2xpc3QiOnsiYml0cyI6MSwibHN0IjoiZU5wallBQUFBQUlBQVEifX0.EsgwUPlLED1rLsG4eRe2TfmMuYhOrKsC5_r-uMqvOpKj-YenmnXD7w29pnRM_zEf86vvAI0bNQp6P87B1sPEAw"
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImRjK3NkLWp3dCJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsInN0YXR1cyI6eyJzdGF0dXNfbGlzdCI6eyJpZHgiOjUsInVyaSI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUvc3RhdHVzL3BpZC8xIn19LCJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJtZlVYbmZPYWlKNXlSbVNuMjZMYmVrV1F5TGFJZnRlVFQ0ckJBZ1FEZU9BIn0seyIuLi4iOiJqaG1kQVhKZ213dVhNbHZIVXI5NXRXUFFISVJlNmRiRkI2c2FmN09qUXdFIn1dLCJpc3N1aW5nX2F1dGhvcml0eSI6IkV4YW1wbGUgQXV0aG9yaXR5IiwiaXNzdWluZ19jb3VudHJ5IjoiUk8iLCJfc2QiOlsiMFluYktwU0hQeDgySDlfcFlFd2pIR2trRDZsYTZzT0lXMDI2VUR3bm5KSSIsIjBld2puX2x5UTExZHFlbDZZYWpDYXA4MzMyU0JKRzAtdWgySmx1UUFrZTQiLCJBNWlQMVFHREVUOHR6VnJvQ2oza1h1c0w5VFJDVzh0Wjdzdy1Fek1ob3l3IiwiQkswSzM3V3ZYVVotcy1CTE5ZQ0tYdmdtUkV3TFFvQi0wSGwyQkxkMDVudyIsImJ5R3d1ZGlONXdoUWpRSGZQQmZHLWhubGFnWkd2S1hXS2VqcXEtMmpsU00iLCJoTTZ2U3Q0NkEtVFVlbDFqT3B2OGplTV96WnRDZklnS1BRdFpQcHRHMzVZIiwidjloYXQ5YUw1elNUejVSem81RGloZ1NEUEpSeWVZaXV2Ykd0R3Vmb2dDRSJdLCJfc2RfYWxnIjoic2hhLTI1NiIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUiLCJpYXQiOjE3OTIzMDI1NTIsImV4cCI6MTgyMzgzODU1MiwibmJmIjoxNzkyMzAyNTUyLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4Ijoid3NfOVdBVGxJdDNXOTZKVS02Y1ByLWNhbGt6SGZNSTZhdWVrM0s1OVZEUSIsImt0eSI6Ik9LUCJ9fX0.xQWADsMnzqfN1Vdk-GFoBy5EuJ1uKCH58pg_8bg6cA2cZyFO0OQlmiEaoj-996ZpRWriNA-obPdhtsg3Ov3iCQ~WyJRSVY1ZUJweEtiTVhEMkQyaTZYRVFRIiwiYmlydGhkYXRlIiwiMTk5MC0wMS0wMSJd~WyJ1Q3Rhbnd3eFh1ajN0ZHc0LWo0U01BIiwiYWdlX292ZXJfMTgiLHRydWVd~WyJQZGNUVFNUU3FDRXZwZnh5UXdUZ1d3IiwiUk8iXQ~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE3OTIzMDI1NTIsImF1ZCI6Imh0dHBzOi8vdmVyaWZpZXIuZXhhbXBsZSIsIm5vbmNlIjoibi1hOWRkNzRhMDM5NzBhY2RiIiwic2RfaGFzaCI6IkN0VWxlVmYzS1lHdGNkOU8xS0pzNzZCcTdHaUJqTm56eldhSVk0SmJvMW8ifQ.rF1INd7UF2UUIgw3DWkzI524ASp80-I_VTlMwbvbNVmVmGz9z4zL47aTIfl0AE9tUWrp4EUzk94XbqbTEyr4Cw",
"issuerKey": {
"crv": "Ed25519",
"x": "xWqc4dXP9LHY_Ia09ijwYuMFxHUjbo2HZOvcquHT0eE",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-a9dd74a03970acdb",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example",
"expectedVct": "urn:eudi:pid:1",
"statusListJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImV4cCI6MTc5MjMwNjE1Miwic3RhdHVzX2xpc3QiOnsiYml0cyI6MSwibHN0IjoiZU5wallBQUFBQUlBQVEifX0.EsgwUPlLED1rLsG4eRe2TfmMuYhOrKsC5_r-uMqvOpKj-YenmnXD7w29pnRM_zEf86vvAI0bNQp6P87B1sPEAw"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwtvc.status-list"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,78 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/aere-pid.status-list-other-uri",
"artifact": "sdjwt-vc-presentation",
"title": "the list handed was published for another uri (sub)",
"source": "derived from sdjwt-vc-presentation/aere-pid.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": "sdjwt-vc-presentation/aere-pid.valid",
"mutation": {
"op": "set",
"path": [
"statusListJwt"
],
"value": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMS1vdGhlciIsImlhdCI6MTc5MjMwMjU1MiwiZXhwIjoxNzkyMzA2MTUyLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoxLCJsc3QiOiJlTnBqWUFBQUFBSUFBUSJ9fQ.rUNIGt2ncvgWImphPEIF8xRZmQvObZy37NB330HXiMEFPI-DbGCS-bZG4-TOOhoVLqb8MmTrGy3mOXA0Mbh4DQ"
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImRjK3NkLWp3dCJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsInN0YXR1cyI6eyJzdGF0dXNfbGlzdCI6eyJpZHgiOjUsInVyaSI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUvc3RhdHVzL3BpZC8xIn19LCJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJtZlVYbmZPYWlKNXlSbVNuMjZMYmVrV1F5TGFJZnRlVFQ0ckJBZ1FEZU9BIn0seyIuLi4iOiJqaG1kQVhKZ213dVhNbHZIVXI5NXRXUFFISVJlNmRiRkI2c2FmN09qUXdFIn1dLCJpc3N1aW5nX2F1dGhvcml0eSI6IkV4YW1wbGUgQXV0aG9yaXR5IiwiaXNzdWluZ19jb3VudHJ5IjoiUk8iLCJfc2QiOlsiMFluYktwU0hQeDgySDlfcFlFd2pIR2trRDZsYTZzT0lXMDI2VUR3bm5KSSIsIjBld2puX2x5UTExZHFlbDZZYWpDYXA4MzMyU0JKRzAtdWgySmx1UUFrZTQiLCJBNWlQMVFHREVUOHR6VnJvQ2oza1h1c0w5VFJDVzh0Wjdzdy1Fek1ob3l3IiwiQkswSzM3V3ZYVVotcy1CTE5ZQ0tYdmdtUkV3TFFvQi0wSGwyQkxkMDVudyIsImJ5R3d1ZGlONXdoUWpRSGZQQmZHLWhubGFnWkd2S1hXS2VqcXEtMmpsU00iLCJoTTZ2U3Q0NkEtVFVlbDFqT3B2OGplTV96WnRDZklnS1BRdFpQcHRHMzVZIiwidjloYXQ5YUw1elNUejVSem81RGloZ1NEUEpSeWVZaXV2Ykd0R3Vmb2dDRSJdLCJfc2RfYWxnIjoic2hhLTI1NiIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUiLCJpYXQiOjE3OTIzMDI1NTIsImV4cCI6MTgyMzgzODU1MiwibmJmIjoxNzkyMzAyNTUyLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4Ijoid3NfOVdBVGxJdDNXOTZKVS02Y1ByLWNhbGt6SGZNSTZhdWVrM0s1OVZEUSIsImt0eSI6Ik9LUCJ9fX0.xQWADsMnzqfN1Vdk-GFoBy5EuJ1uKCH58pg_8bg6cA2cZyFO0OQlmiEaoj-996ZpRWriNA-obPdhtsg3Ov3iCQ~WyJRSVY1ZUJweEtiTVhEMkQyaTZYRVFRIiwiYmlydGhkYXRlIiwiMTk5MC0wMS0wMSJd~WyJ1Q3Rhbnd3eFh1ajN0ZHc0LWo0U01BIiwiYWdlX292ZXJfMTgiLHRydWVd~WyJQZGNUVFNUU3FDRXZwZnh5UXdUZ1d3IiwiUk8iXQ~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE3OTIzMDI1NTIsImF1ZCI6Imh0dHBzOi8vdmVyaWZpZXIuZXhhbXBsZSIsIm5vbmNlIjoibi1hOWRkNzRhMDM5NzBhY2RiIiwic2RfaGFzaCI6IkN0VWxlVmYzS1lHdGNkOU8xS0pzNzZCcTdHaUJqTm56eldhSVk0SmJvMW8ifQ.rF1INd7UF2UUIgw3DWkzI524ASp80-I_VTlMwbvbNVmVmGz9z4zL47aTIfl0AE9tUWrp4EUzk94XbqbTEyr4Cw",
"issuerKey": {
"crv": "Ed25519",
"x": "xWqc4dXP9LHY_Ia09ijwYuMFxHUjbo2HZOvcquHT0eE",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-a9dd74a03970acdb",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example",
"expectedVct": "urn:eudi:pid:1",
"statusListJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMS1vdGhlciIsImlhdCI6MTc5MjMwMjU1MiwiZXhwIjoxNzkyMzA2MTUyLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoxLCJsc3QiOiJlTnBqWUFBQUFBSUFBUSJ9fQ.rUNIGt2ncvgWImphPEIF8xRZmQvObZy37NB330HXiMEFPI-DbGCS-bZG4-TOOhoVLqb8MmTrGy3mOXA0Mbh4DQ"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwtvc.status-list"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,78 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/aere-pid.status-list-stranger",
"artifact": "sdjwt-vc-presentation",
"title": "the list handed is signed by another key than the issuer's",
"source": "derived from sdjwt-vc-presentation/aere-pid.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": "sdjwt-vc-presentation/aere-pid.valid",
"mutation": {
"op": "set",
"path": [
"statusListJwt"
],
"value": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjMwMjU1Miwic3RhdHVzX2xpc3QiOnsiYml0cyI6MSwibHN0IjoiZU5wallBQUFBQUlBQVEifX0.stW22QbAfDuxc9bB_L7S8_Viy8Q-FmMCrp33upkwLZA6Ez9qeGi2Z_WzkYq0GbLQsb0KxG9RTiWHkV-XIW5uBw"
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImRjK3NkLWp3dCJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsInN0YXR1cyI6eyJzdGF0dXNfbGlzdCI6eyJpZHgiOjUsInVyaSI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUvc3RhdHVzL3BpZC8xIn19LCJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJtZlVYbmZPYWlKNXlSbVNuMjZMYmVrV1F5TGFJZnRlVFQ0ckJBZ1FEZU9BIn0seyIuLi4iOiJqaG1kQVhKZ213dVhNbHZIVXI5NXRXUFFISVJlNmRiRkI2c2FmN09qUXdFIn1dLCJpc3N1aW5nX2F1dGhvcml0eSI6IkV4YW1wbGUgQXV0aG9yaXR5IiwiaXNzdWluZ19jb3VudHJ5IjoiUk8iLCJfc2QiOlsiMFluYktwU0hQeDgySDlfcFlFd2pIR2trRDZsYTZzT0lXMDI2VUR3bm5KSSIsIjBld2puX2x5UTExZHFlbDZZYWpDYXA4MzMyU0JKRzAtdWgySmx1UUFrZTQiLCJBNWlQMVFHREVUOHR6VnJvQ2oza1h1c0w5VFJDVzh0Wjdzdy1Fek1ob3l3IiwiQkswSzM3V3ZYVVotcy1CTE5ZQ0tYdmdtUkV3TFFvQi0wSGwyQkxkMDVudyIsImJ5R3d1ZGlONXdoUWpRSGZQQmZHLWhubGFnWkd2S1hXS2VqcXEtMmpsU00iLCJoTTZ2U3Q0NkEtVFVlbDFqT3B2OGplTV96WnRDZklnS1BRdFpQcHRHMzVZIiwidjloYXQ5YUw1elNUejVSem81RGloZ1NEUEpSeWVZaXV2Ykd0R3Vmb2dDRSJdLCJfc2RfYWxnIjoic2hhLTI1NiIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUiLCJpYXQiOjE3OTIzMDI1NTIsImV4cCI6MTgyMzgzODU1MiwibmJmIjoxNzkyMzAyNTUyLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4Ijoid3NfOVdBVGxJdDNXOTZKVS02Y1ByLWNhbGt6SGZNSTZhdWVrM0s1OVZEUSIsImt0eSI6Ik9LUCJ9fX0.xQWADsMnzqfN1Vdk-GFoBy5EuJ1uKCH58pg_8bg6cA2cZyFO0OQlmiEaoj-996ZpRWriNA-obPdhtsg3Ov3iCQ~WyJRSVY1ZUJweEtiTVhEMkQyaTZYRVFRIiwiYmlydGhkYXRlIiwiMTk5MC0wMS0wMSJd~WyJ1Q3Rhbnd3eFh1ajN0ZHc0LWo0U01BIiwiYWdlX292ZXJfMTgiLHRydWVd~WyJQZGNUVFNUU3FDRXZwZnh5UXdUZ1d3IiwiUk8iXQ~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE3OTIzMDI1NTIsImF1ZCI6Imh0dHBzOi8vdmVyaWZpZXIuZXhhbXBsZSIsIm5vbmNlIjoibi1hOWRkNzRhMDM5NzBhY2RiIiwic2RfaGFzaCI6IkN0VWxlVmYzS1lHdGNkOU8xS0pzNzZCcTdHaUJqTm56eldhSVk0SmJvMW8ifQ.rF1INd7UF2UUIgw3DWkzI524ASp80-I_VTlMwbvbNVmVmGz9z4zL47aTIfl0AE9tUWrp4EUzk94XbqbTEyr4Cw",
"issuerKey": {
"crv": "Ed25519",
"x": "xWqc4dXP9LHY_Ia09ijwYuMFxHUjbo2HZOvcquHT0eE",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-a9dd74a03970acdb",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example",
"expectedVct": "urn:eudi:pid:1",
"statusListJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjMwMjU1Miwic3RhdHVzX2xpc3QiOnsiYml0cyI6MSwibHN0IjoiZU5wallBQUFBQUlBQVEifX0.stW22QbAfDuxc9bB_L7S8_Viy8Q-FmMCrp33upkwLZA6Ez9qeGi2Z_WzkYq0GbLQsb0KxG9RTiWHkV-XIW5uBw"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwtvc.status-list"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,78 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/aere-pid.status-list-typ",
"artifact": "sdjwt-vc-presentation",
"title": "the list handed is typed JWT, not statuslist+jwt",
"source": "derived from sdjwt-vc-presentation/aere-pid.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": "sdjwt-vc-presentation/aere-pid.valid",
"mutation": {
"op": "set",
"path": [
"statusListJwt"
],
"value": "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjMwMjU1MiwiZXhwIjoxNzkyMzA2MTUyLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoxLCJsc3QiOiJlTnBqWUFBQUFBSUFBUSJ9fQ.6U_gARjIurUBzIQYqufPjNYzmT3nvVWebULymAWs3Dth94siwGLwqSJquXJFXEGgEZjjT_-e5fpVpi9uJ1siCg"
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImRjK3NkLWp3dCJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsInN0YXR1cyI6eyJzdGF0dXNfbGlzdCI6eyJpZHgiOjUsInVyaSI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUvc3RhdHVzL3BpZC8xIn19LCJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJtZlVYbmZPYWlKNXlSbVNuMjZMYmVrV1F5TGFJZnRlVFQ0ckJBZ1FEZU9BIn0seyIuLi4iOiJqaG1kQVhKZ213dVhNbHZIVXI5NXRXUFFISVJlNmRiRkI2c2FmN09qUXdFIn1dLCJpc3N1aW5nX2F1dGhvcml0eSI6IkV4YW1wbGUgQXV0aG9yaXR5IiwiaXNzdWluZ19jb3VudHJ5IjoiUk8iLCJfc2QiOlsiMFluYktwU0hQeDgySDlfcFlFd2pIR2trRDZsYTZzT0lXMDI2VUR3bm5KSSIsIjBld2puX2x5UTExZHFlbDZZYWpDYXA4MzMyU0JKRzAtdWgySmx1UUFrZTQiLCJBNWlQMVFHREVUOHR6VnJvQ2oza1h1c0w5VFJDVzh0Wjdzdy1Fek1ob3l3IiwiQkswSzM3V3ZYVVotcy1CTE5ZQ0tYdmdtUkV3TFFvQi0wSGwyQkxkMDVudyIsImJ5R3d1ZGlONXdoUWpRSGZQQmZHLWhubGFnWkd2S1hXS2VqcXEtMmpsU00iLCJoTTZ2U3Q0NkEtVFVlbDFqT3B2OGplTV96WnRDZklnS1BRdFpQcHRHMzVZIiwidjloYXQ5YUw1elNUejVSem81RGloZ1NEUEpSeWVZaXV2Ykd0R3Vmb2dDRSJdLCJfc2RfYWxnIjoic2hhLTI1NiIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUiLCJpYXQiOjE3OTIzMDI1NTIsImV4cCI6MTgyMzgzODU1MiwibmJmIjoxNzkyMzAyNTUyLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4Ijoid3NfOVdBVGxJdDNXOTZKVS02Y1ByLWNhbGt6SGZNSTZhdWVrM0s1OVZEUSIsImt0eSI6Ik9LUCJ9fX0.xQWADsMnzqfN1Vdk-GFoBy5EuJ1uKCH58pg_8bg6cA2cZyFO0OQlmiEaoj-996ZpRWriNA-obPdhtsg3Ov3iCQ~WyJRSVY1ZUJweEtiTVhEMkQyaTZYRVFRIiwiYmlydGhkYXRlIiwiMTk5MC0wMS0wMSJd~WyJ1Q3Rhbnd3eFh1ajN0ZHc0LWo0U01BIiwiYWdlX292ZXJfMTgiLHRydWVd~WyJQZGNUVFNUU3FDRXZwZnh5UXdUZ1d3IiwiUk8iXQ~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE3OTIzMDI1NTIsImF1ZCI6Imh0dHBzOi8vdmVyaWZpZXIuZXhhbXBsZSIsIm5vbmNlIjoibi1hOWRkNzRhMDM5NzBhY2RiIiwic2RfaGFzaCI6IkN0VWxlVmYzS1lHdGNkOU8xS0pzNzZCcTdHaUJqTm56eldhSVk0SmJvMW8ifQ.rF1INd7UF2UUIgw3DWkzI524ASp80-I_VTlMwbvbNVmVmGz9z4zL47aTIfl0AE9tUWrp4EUzk94XbqbTEyr4Cw",
"issuerKey": {
"crv": "Ed25519",
"x": "xWqc4dXP9LHY_Ia09ijwYuMFxHUjbo2HZOvcquHT0eE",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-a9dd74a03970acdb",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example",
"expectedVct": "urn:eudi:pid:1",
"statusListJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjMwMjU1MiwiZXhwIjoxNzkyMzA2MTUyLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoxLCJsc3QiOiJlTnBqWUFBQUFBSUFBUSJ9fQ.6U_gARjIurUBzIQYqufPjNYzmT3nvVWebULymAWs3Dth94siwGLwqSJquXJFXEGgEZjjT_-e5fpVpi9uJ1siCg"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwtvc.status-list"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,78 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/aere-pid.status-revoked",
"artifact": "sdjwt-vc-presentation",
"title": "the issuer's list has status 1 (INVALID) at the credential's index",
"source": "derived from sdjwt-vc-presentation/aere-pid.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": "sdjwt-vc-presentation/aere-pid.valid",
"mutation": {
"op": "set",
"path": [
"statusListJwt"
],
"value": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjMwMjU1MiwiZXhwIjoxNzkyMzA2MTUyLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoxLCJsc3QiOiJlTnBUWUFBQUFFSUFJUSJ9fQ.oimbeRq48Zvabtwl6elhRf_5bY5WdAvnTOAdktoHPxbfoip7swrJ3Ux2v1O48LSph-7cceYTVXNksbVcKyTCAQ"
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImRjK3NkLWp3dCJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsInN0YXR1cyI6eyJzdGF0dXNfbGlzdCI6eyJpZHgiOjUsInVyaSI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUvc3RhdHVzL3BpZC8xIn19LCJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJtZlVYbmZPYWlKNXlSbVNuMjZMYmVrV1F5TGFJZnRlVFQ0ckJBZ1FEZU9BIn0seyIuLi4iOiJqaG1kQVhKZ213dVhNbHZIVXI5NXRXUFFISVJlNmRiRkI2c2FmN09qUXdFIn1dLCJpc3N1aW5nX2F1dGhvcml0eSI6IkV4YW1wbGUgQXV0aG9yaXR5IiwiaXNzdWluZ19jb3VudHJ5IjoiUk8iLCJfc2QiOlsiMFluYktwU0hQeDgySDlfcFlFd2pIR2trRDZsYTZzT0lXMDI2VUR3bm5KSSIsIjBld2puX2x5UTExZHFlbDZZYWpDYXA4MzMyU0JKRzAtdWgySmx1UUFrZTQiLCJBNWlQMVFHREVUOHR6VnJvQ2oza1h1c0w5VFJDVzh0Wjdzdy1Fek1ob3l3IiwiQkswSzM3V3ZYVVotcy1CTE5ZQ0tYdmdtUkV3TFFvQi0wSGwyQkxkMDVudyIsImJ5R3d1ZGlONXdoUWpRSGZQQmZHLWhubGFnWkd2S1hXS2VqcXEtMmpsU00iLCJoTTZ2U3Q0NkEtVFVlbDFqT3B2OGplTV96WnRDZklnS1BRdFpQcHRHMzVZIiwidjloYXQ5YUw1elNUejVSem81RGloZ1NEUEpSeWVZaXV2Ykd0R3Vmb2dDRSJdLCJfc2RfYWxnIjoic2hhLTI1NiIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUiLCJpYXQiOjE3OTIzMDI1NTIsImV4cCI6MTgyMzgzODU1MiwibmJmIjoxNzkyMzAyNTUyLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4Ijoid3NfOVdBVGxJdDNXOTZKVS02Y1ByLWNhbGt6SGZNSTZhdWVrM0s1OVZEUSIsImt0eSI6Ik9LUCJ9fX0.xQWADsMnzqfN1Vdk-GFoBy5EuJ1uKCH58pg_8bg6cA2cZyFO0OQlmiEaoj-996ZpRWriNA-obPdhtsg3Ov3iCQ~WyJRSVY1ZUJweEtiTVhEMkQyaTZYRVFRIiwiYmlydGhkYXRlIiwiMTk5MC0wMS0wMSJd~WyJ1Q3Rhbnd3eFh1ajN0ZHc0LWo0U01BIiwiYWdlX292ZXJfMTgiLHRydWVd~WyJQZGNUVFNUU3FDRXZwZnh5UXdUZ1d3IiwiUk8iXQ~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE3OTIzMDI1NTIsImF1ZCI6Imh0dHBzOi8vdmVyaWZpZXIuZXhhbXBsZSIsIm5vbmNlIjoibi1hOWRkNzRhMDM5NzBhY2RiIiwic2RfaGFzaCI6IkN0VWxlVmYzS1lHdGNkOU8xS0pzNzZCcTdHaUJqTm56eldhSVk0SmJvMW8ifQ.rF1INd7UF2UUIgw3DWkzI524ASp80-I_VTlMwbvbNVmVmGz9z4zL47aTIfl0AE9tUWrp4EUzk94XbqbTEyr4Cw",
"issuerKey": {
"crv": "Ed25519",
"x": "xWqc4dXP9LHY_Ia09ijwYuMFxHUjbo2HZOvcquHT0eE",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-a9dd74a03970acdb",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example",
"expectedVct": "urn:eudi:pid:1",
"statusListJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjMwMjU1MiwiZXhwIjoxNzkyMzA2MTUyLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoxLCJsc3QiOiJlTnBUWUFBQUFFSUFJUSJ9fQ.oimbeRq48Zvabtwl6elhRf_5bY5WdAvnTOAdktoHPxbfoip7swrJ3Ux2v1O48LSph-7cceYTVXNksbVcKyTCAQ"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwtvc.status-revoked"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,78 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/aere-pid.status-suspended",
"artifact": "sdjwt-vc-presentation",
"title": "the issuer's list, 2 bits per entry, has status 2 (SUSPENDED) at the index",
"source": "derived from sdjwt-vc-presentation/aere-pid.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": "sdjwt-vc-presentation/aere-pid.valid",
"mutation": {
"op": "set",
"path": [
"statusListJwt"
],
"value": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjMwMjU1MiwiZXhwIjoxNzkyMzA2MTUyLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoyLCJsc3QiOiJlTnBqNEdCZ0FBQUFIQUFKIn19.facNVbBrSybeLUNLVCU0FDBpH9XdDZmcVQkGcatktJ7v4fEI-_XBG-JAD4h9VKZr6zmddk3ZtD3x3h_HW8EbBg"
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImRjK3NkLWp3dCJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsInN0YXR1cyI6eyJzdGF0dXNfbGlzdCI6eyJpZHgiOjUsInVyaSI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUvc3RhdHVzL3BpZC8xIn19LCJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJtZlVYbmZPYWlKNXlSbVNuMjZMYmVrV1F5TGFJZnRlVFQ0ckJBZ1FEZU9BIn0seyIuLi4iOiJqaG1kQVhKZ213dVhNbHZIVXI5NXRXUFFISVJlNmRiRkI2c2FmN09qUXdFIn1dLCJpc3N1aW5nX2F1dGhvcml0eSI6IkV4YW1wbGUgQXV0aG9yaXR5IiwiaXNzdWluZ19jb3VudHJ5IjoiUk8iLCJfc2QiOlsiMFluYktwU0hQeDgySDlfcFlFd2pIR2trRDZsYTZzT0lXMDI2VUR3bm5KSSIsIjBld2puX2x5UTExZHFlbDZZYWpDYXA4MzMyU0JKRzAtdWgySmx1UUFrZTQiLCJBNWlQMVFHREVUOHR6VnJvQ2oza1h1c0w5VFJDVzh0Wjdzdy1Fek1ob3l3IiwiQkswSzM3V3ZYVVotcy1CTE5ZQ0tYdmdtUkV3TFFvQi0wSGwyQkxkMDVudyIsImJ5R3d1ZGlONXdoUWpRSGZQQmZHLWhubGFnWkd2S1hXS2VqcXEtMmpsU00iLCJoTTZ2U3Q0NkEtVFVlbDFqT3B2OGplTV96WnRDZklnS1BRdFpQcHRHMzVZIiwidjloYXQ5YUw1elNUejVSem81RGloZ1NEUEpSeWVZaXV2Ykd0R3Vmb2dDRSJdLCJfc2RfYWxnIjoic2hhLTI1NiIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUiLCJpYXQiOjE3OTIzMDI1NTIsImV4cCI6MTgyMzgzODU1MiwibmJmIjoxNzkyMzAyNTUyLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4Ijoid3NfOVdBVGxJdDNXOTZKVS02Y1ByLWNhbGt6SGZNSTZhdWVrM0s1OVZEUSIsImt0eSI6Ik9LUCJ9fX0.xQWADsMnzqfN1Vdk-GFoBy5EuJ1uKCH58pg_8bg6cA2cZyFO0OQlmiEaoj-996ZpRWriNA-obPdhtsg3Ov3iCQ~WyJRSVY1ZUJweEtiTVhEMkQyaTZYRVFRIiwiYmlydGhkYXRlIiwiMTk5MC0wMS0wMSJd~WyJ1Q3Rhbnd3eFh1ajN0ZHc0LWo0U01BIiwiYWdlX292ZXJfMTgiLHRydWVd~WyJQZGNUVFNUU3FDRXZwZnh5UXdUZ1d3IiwiUk8iXQ~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE3OTIzMDI1NTIsImF1ZCI6Imh0dHBzOi8vdmVyaWZpZXIuZXhhbXBsZSIsIm5vbmNlIjoibi1hOWRkNzRhMDM5NzBhY2RiIiwic2RfaGFzaCI6IkN0VWxlVmYzS1lHdGNkOU8xS0pzNzZCcTdHaUJqTm56eldhSVk0SmJvMW8ifQ.rF1INd7UF2UUIgw3DWkzI524ASp80-I_VTlMwbvbNVmVmGz9z4zL47aTIfl0AE9tUWrp4EUzk94XbqbTEyr4Cw",
"issuerKey": {
"crv": "Ed25519",
"x": "xWqc4dXP9LHY_Ia09ijwYuMFxHUjbo2HZOvcquHT0eE",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-a9dd74a03970acdb",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example",
"expectedVct": "urn:eudi:pid:1",
"statusListJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjMwMjU1MiwiZXhwIjoxNzkyMzA2MTUyLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoyLCJsc3QiOiJlTnBqNEdCZ0FBQUFIQUFKIn19.facNVbBrSybeLUNLVCU0FDBpH9XdDZmcVQkGcatktJ7v4fEI-_XBG-JAD4h9VKZr6zmddk3ZtD3x3h_HW8EbBg"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwtvc.status-revoked"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,76 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/aere-pid.status-unjudged",
"artifact": "sdjwt-vc-presentation",
"title": "no list handed, and the verifier did not waive the status",
"source": "derived from sdjwt-vc-presentation/aere-pid.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": "sdjwt-vc-presentation/aere-pid.valid",
"mutation": {
"op": "remove",
"path": [
"statusListJwt"
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImRjK3NkLWp3dCJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsInN0YXR1cyI6eyJzdGF0dXNfbGlzdCI6eyJpZHgiOjUsInVyaSI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUvc3RhdHVzL3BpZC8xIn19LCJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJtZlVYbmZPYWlKNXlSbVNuMjZMYmVrV1F5TGFJZnRlVFQ0ckJBZ1FEZU9BIn0seyIuLi4iOiJqaG1kQVhKZ213dVhNbHZIVXI5NXRXUFFISVJlNmRiRkI2c2FmN09qUXdFIn1dLCJpc3N1aW5nX2F1dGhvcml0eSI6IkV4YW1wbGUgQXV0aG9yaXR5IiwiaXNzdWluZ19jb3VudHJ5IjoiUk8iLCJfc2QiOlsiMFluYktwU0hQeDgySDlfcFlFd2pIR2trRDZsYTZzT0lXMDI2VUR3bm5KSSIsIjBld2puX2x5UTExZHFlbDZZYWpDYXA4MzMyU0JKRzAtdWgySmx1UUFrZTQiLCJBNWlQMVFHREVUOHR6VnJvQ2oza1h1c0w5VFJDVzh0Wjdzdy1Fek1ob3l3IiwiQkswSzM3V3ZYVVotcy1CTE5ZQ0tYdmdtUkV3TFFvQi0wSGwyQkxkMDVudyIsImJ5R3d1ZGlONXdoUWpRSGZQQmZHLWhubGFnWkd2S1hXS2VqcXEtMmpsU00iLCJoTTZ2U3Q0NkEtVFVlbDFqT3B2OGplTV96WnRDZklnS1BRdFpQcHRHMzVZIiwidjloYXQ5YUw1elNUejVSem81RGloZ1NEUEpSeWVZaXV2Ykd0R3Vmb2dDRSJdLCJfc2RfYWxnIjoic2hhLTI1NiIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUiLCJpYXQiOjE3OTIzMDI1NTIsImV4cCI6MTgyMzgzODU1MiwibmJmIjoxNzkyMzAyNTUyLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4Ijoid3NfOVdBVGxJdDNXOTZKVS02Y1ByLWNhbGt6SGZNSTZhdWVrM0s1OVZEUSIsImt0eSI6Ik9LUCJ9fX0.xQWADsMnzqfN1Vdk-GFoBy5EuJ1uKCH58pg_8bg6cA2cZyFO0OQlmiEaoj-996ZpRWriNA-obPdhtsg3Ov3iCQ~WyJRSVY1ZUJweEtiTVhEMkQyaTZYRVFRIiwiYmlydGhkYXRlIiwiMTk5MC0wMS0wMSJd~WyJ1Q3Rhbnd3eFh1ajN0ZHc0LWo0U01BIiwiYWdlX292ZXJfMTgiLHRydWVd~WyJQZGNUVFNUU3FDRXZwZnh5UXdUZ1d3IiwiUk8iXQ~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE3OTIzMDI1NTIsImF1ZCI6Imh0dHBzOi8vdmVyaWZpZXIuZXhhbXBsZSIsIm5vbmNlIjoibi1hOWRkNzRhMDM5NzBhY2RiIiwic2RfaGFzaCI6IkN0VWxlVmYzS1lHdGNkOU8xS0pzNzZCcTdHaUJqTm56eldhSVk0SmJvMW8ifQ.rF1INd7UF2UUIgw3DWkzI524ASp80-I_VTlMwbvbNVmVmGz9z4zL47aTIfl0AE9tUWrp4EUzk94XbqbTEyr4Cw",
"issuerKey": {
"crv": "Ed25519",
"x": "xWqc4dXP9LHY_Ia09ijwYuMFxHUjbo2HZOvcquHT0eE",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-a9dd74a03970acdb",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example",
"expectedVct": "urn:eudi:pid:1"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwtvc.status-unjudged"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,70 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/aere-pid.valid",
"artifact": "sdjwt-vc-presentation",
"title": "an SD-JWT VC issued with AERE keys (EdDSA; vct urn:eudi:pid:1, typ dc+sd-jwt, a status_list reference), three claims shown, judged with the issuer's Status List Token (all VALID)",
"source": "producers (sdjwt-vc.mjs: issueSdJwtVc, presentSdJwtVc, issueStatusListJwt), three hybrid key pairs made and discarded at generation",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": null,
"mutation": null,
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImRjK3NkLWp3dCJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsInN0YXR1cyI6eyJzdGF0dXNfbGlzdCI6eyJpZHgiOjUsInVyaSI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUvc3RhdHVzL3BpZC8xIn19LCJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJtZlVYbmZPYWlKNXlSbVNuMjZMYmVrV1F5TGFJZnRlVFQ0ckJBZ1FEZU9BIn0seyIuLi4iOiJqaG1kQVhKZ213dVhNbHZIVXI5NXRXUFFISVJlNmRiRkI2c2FmN09qUXdFIn1dLCJpc3N1aW5nX2F1dGhvcml0eSI6IkV4YW1wbGUgQXV0aG9yaXR5IiwiaXNzdWluZ19jb3VudHJ5IjoiUk8iLCJfc2QiOlsiMFluYktwU0hQeDgySDlfcFlFd2pIR2trRDZsYTZzT0lXMDI2VUR3bm5KSSIsIjBld2puX2x5UTExZHFlbDZZYWpDYXA4MzMyU0JKRzAtdWgySmx1UUFrZTQiLCJBNWlQMVFHREVUOHR6VnJvQ2oza1h1c0w5VFJDVzh0Wjdzdy1Fek1ob3l3IiwiQkswSzM3V3ZYVVotcy1CTE5ZQ0tYdmdtUkV3TFFvQi0wSGwyQkxkMDVudyIsImJ5R3d1ZGlONXdoUWpRSGZQQmZHLWhubGFnWkd2S1hXS2VqcXEtMmpsU00iLCJoTTZ2U3Q0NkEtVFVlbDFqT3B2OGplTV96WnRDZklnS1BRdFpQcHRHMzVZIiwidjloYXQ5YUw1elNUejVSem81RGloZ1NEUEpSeWVZaXV2Ykd0R3Vmb2dDRSJdLCJfc2RfYWxnIjoic2hhLTI1NiIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUiLCJpYXQiOjE3OTIzMDI1NTIsImV4cCI6MTgyMzgzODU1MiwibmJmIjoxNzkyMzAyNTUyLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4Ijoid3NfOVdBVGxJdDNXOTZKVS02Y1ByLWNhbGt6SGZNSTZhdWVrM0s1OVZEUSIsImt0eSI6Ik9LUCJ9fX0.xQWADsMnzqfN1Vdk-GFoBy5EuJ1uKCH58pg_8bg6cA2cZyFO0OQlmiEaoj-996ZpRWriNA-obPdhtsg3Ov3iCQ~WyJRSVY1ZUJweEtiTVhEMkQyaTZYRVFRIiwiYmlydGhkYXRlIiwiMTk5MC0wMS0wMSJd~WyJ1Q3Rhbnd3eFh1ajN0ZHc0LWo0U01BIiwiYWdlX292ZXJfMTgiLHRydWVd~WyJQZGNUVFNUU3FDRXZwZnh5UXdUZ1d3IiwiUk8iXQ~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE3OTIzMDI1NTIsImF1ZCI6Imh0dHBzOi8vdmVyaWZpZXIuZXhhbXBsZSIsIm5vbmNlIjoibi1hOWRkNzRhMDM5NzBhY2RiIiwic2RfaGFzaCI6IkN0VWxlVmYzS1lHdGNkOU8xS0pzNzZCcTdHaUJqTm56eldhSVk0SmJvMW8ifQ.rF1INd7UF2UUIgw3DWkzI524ASp80-I_VTlMwbvbNVmVmGz9z4zL47aTIfl0AE9tUWrp4EUzk94XbqbTEyr4Cw",
"issuerKey": {
"crv": "Ed25519",
"x": "xWqc4dXP9LHY_Ia09ijwYuMFxHUjbo2HZOvcquHT0eE",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-a9dd74a03970acdb",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example",
"expectedVct": "urn:eudi:pid:1",
"statusListJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjMwMjU1MiwiZXhwIjoxNzkyMzA2MTUyLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoxLCJsc3QiOiJlTnBqWUFBQUFBSUFBUSJ9fQ.-LALHjNMKDkk0wbZvjXQjh-yuGRi-Jz0ZV3kYmT1K5KVRjPnKXZBB7H6SDd4Mrt15-mYduZgcM3LH8zq5w3CBQ"
},
"expected": {
"verdict": "VALID",
"failed": [],
"levels": {
"integrity": "PASSED",
"authenticity": "PASSED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,76 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/aere-pid.vct-expected",
"artifact": "sdjwt-vc-presentation",
"title": "the verifier names no credential type it expects",
"source": "derived from sdjwt-vc-presentation/aere-pid.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": "sdjwt-vc-presentation/aere-pid.valid",
"mutation": {
"op": "remove",
"path": [
"expectedVct"
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImRjK3NkLWp3dCJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsInN0YXR1cyI6eyJzdGF0dXNfbGlzdCI6eyJpZHgiOjUsInVyaSI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUvc3RhdHVzL3BpZC8xIn19LCJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJtZlVYbmZPYWlKNXlSbVNuMjZMYmVrV1F5TGFJZnRlVFQ0ckJBZ1FEZU9BIn0seyIuLi4iOiJqaG1kQVhKZ213dVhNbHZIVXI5NXRXUFFISVJlNmRiRkI2c2FmN09qUXdFIn1dLCJpc3N1aW5nX2F1dGhvcml0eSI6IkV4YW1wbGUgQXV0aG9yaXR5IiwiaXNzdWluZ19jb3VudHJ5IjoiUk8iLCJfc2QiOlsiMFluYktwU0hQeDgySDlfcFlFd2pIR2trRDZsYTZzT0lXMDI2VUR3bm5KSSIsIjBld2puX2x5UTExZHFlbDZZYWpDYXA4MzMyU0JKRzAtdWgySmx1UUFrZTQiLCJBNWlQMVFHREVUOHR6VnJvQ2oza1h1c0w5VFJDVzh0Wjdzdy1Fek1ob3l3IiwiQkswSzM3V3ZYVVotcy1CTE5ZQ0tYdmdtUkV3TFFvQi0wSGwyQkxkMDVudyIsImJ5R3d1ZGlONXdoUWpRSGZQQmZHLWhubGFnWkd2S1hXS2VqcXEtMmpsU00iLCJoTTZ2U3Q0NkEtVFVlbDFqT3B2OGplTV96WnRDZklnS1BRdFpQcHRHMzVZIiwidjloYXQ5YUw1elNUejVSem81RGloZ1NEUEpSeWVZaXV2Ykd0R3Vmb2dDRSJdLCJfc2RfYWxnIjoic2hhLTI1NiIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUiLCJpYXQiOjE3OTIzMDI1NTIsImV4cCI6MTgyMzgzODU1MiwibmJmIjoxNzkyMzAyNTUyLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4Ijoid3NfOVdBVGxJdDNXOTZKVS02Y1ByLWNhbGt6SGZNSTZhdWVrM0s1OVZEUSIsImt0eSI6Ik9LUCJ9fX0.xQWADsMnzqfN1Vdk-GFoBy5EuJ1uKCH58pg_8bg6cA2cZyFO0OQlmiEaoj-996ZpRWriNA-obPdhtsg3Ov3iCQ~WyJRSVY1ZUJweEtiTVhEMkQyaTZYRVFRIiwiYmlydGhkYXRlIiwiMTk5MC0wMS0wMSJd~WyJ1Q3Rhbnd3eFh1ajN0ZHc0LWo0U01BIiwiYWdlX292ZXJfMTgiLHRydWVd~WyJQZGNUVFNUU3FDRXZwZnh5UXdUZ1d3IiwiUk8iXQ~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE3OTIzMDI1NTIsImF1ZCI6Imh0dHBzOi8vdmVyaWZpZXIuZXhhbXBsZSIsIm5vbmNlIjoibi1hOWRkNzRhMDM5NzBhY2RiIiwic2RfaGFzaCI6IkN0VWxlVmYzS1lHdGNkOU8xS0pzNzZCcTdHaUJqTm56eldhSVk0SmJvMW8ifQ.rF1INd7UF2UUIgw3DWkzI524ASp80-I_VTlMwbvbNVmVmGz9z4zL47aTIfl0AE9tUWrp4EUzk94XbqbTEyr4Cw",
"issuerKey": {
"crv": "Ed25519",
"x": "xWqc4dXP9LHY_Ia09ijwYuMFxHUjbo2HZOvcquHT0eE",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-a9dd74a03970acdb",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example",
"statusListJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjMwMjU1MiwiZXhwIjoxNzkyMzA2MTUyLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoxLCJsc3QiOiJlTnBqWUFBQUFBSUFBUSJ9fQ.-LALHjNMKDkk0wbZvjXQjh-yuGRi-Jz0ZV3kYmT1K5KVRjPnKXZBB7H6SDd4Mrt15-mYduZgcM3LH8zq5w3CBQ"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwtvc.vct-expected"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,78 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/aere-pid.vct-mismatch",
"artifact": "sdjwt-vc-presentation",
"title": "the verifier expects another credential type",
"source": "derived from sdjwt-vc-presentation/aere-pid.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": "sdjwt-vc-presentation/aere-pid.valid",
"mutation": {
"op": "set",
"path": [
"expectedVct"
],
"value": "urn:eudi:pid:2"
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImRjK3NkLWp3dCJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsInN0YXR1cyI6eyJzdGF0dXNfbGlzdCI6eyJpZHgiOjUsInVyaSI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUvc3RhdHVzL3BpZC8xIn19LCJuYXRpb25hbGl0aWVzIjpbeyIuLi4iOiJtZlVYbmZPYWlKNXlSbVNuMjZMYmVrV1F5TGFJZnRlVFQ0ckJBZ1FEZU9BIn0seyIuLi4iOiJqaG1kQVhKZ213dVhNbHZIVXI5NXRXUFFISVJlNmRiRkI2c2FmN09qUXdFIn1dLCJpc3N1aW5nX2F1dGhvcml0eSI6IkV4YW1wbGUgQXV0aG9yaXR5IiwiaXNzdWluZ19jb3VudHJ5IjoiUk8iLCJfc2QiOlsiMFluYktwU0hQeDgySDlfcFlFd2pIR2trRDZsYTZzT0lXMDI2VUR3bm5KSSIsIjBld2puX2x5UTExZHFlbDZZYWpDYXA4MzMyU0JKRzAtdWgySmx1UUFrZTQiLCJBNWlQMVFHREVUOHR6VnJvQ2oza1h1c0w5VFJDVzh0Wjdzdy1Fek1ob3l3IiwiQkswSzM3V3ZYVVotcy1CTE5ZQ0tYdmdtUkV3TFFvQi0wSGwyQkxkMDVudyIsImJ5R3d1ZGlONXdoUWpRSGZQQmZHLWhubGFnWkd2S1hXS2VqcXEtMmpsU00iLCJoTTZ2U3Q0NkEtVFVlbDFqT3B2OGplTV96WnRDZklnS1BRdFpQcHRHMzVZIiwidjloYXQ5YUw1elNUejVSem81RGloZ1NEUEpSeWVZaXV2Ykd0R3Vmb2dDRSJdLCJfc2RfYWxnIjoic2hhLTI1NiIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUiLCJpYXQiOjE3OTIzMDI1NTIsImV4cCI6MTgyMzgzODU1MiwibmJmIjoxNzkyMzAyNTUyLCJjbmYiOnsiandrIjp7ImNydiI6IkVkMjU1MTkiLCJ4Ijoid3NfOVdBVGxJdDNXOTZKVS02Y1ByLWNhbGt6SGZNSTZhdWVrM0s1OVZEUSIsImt0eSI6Ik9LUCJ9fX0.xQWADsMnzqfN1Vdk-GFoBy5EuJ1uKCH58pg_8bg6cA2cZyFO0OQlmiEaoj-996ZpRWriNA-obPdhtsg3Ov3iCQ~WyJRSVY1ZUJweEtiTVhEMkQyaTZYRVFRIiwiYmlydGhkYXRlIiwiMTk5MC0wMS0wMSJd~WyJ1Q3Rhbnd3eFh1ajN0ZHc0LWo0U01BIiwiYWdlX292ZXJfMTgiLHRydWVd~WyJQZGNUVFNUU3FDRXZwZnh5UXdUZ1d3IiwiUk8iXQ~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE3OTIzMDI1NTIsImF1ZCI6Imh0dHBzOi8vdmVyaWZpZXIuZXhhbXBsZSIsIm5vbmNlIjoibi1hOWRkNzRhMDM5NzBhY2RiIiwic2RfaGFzaCI6IkN0VWxlVmYzS1lHdGNkOU8xS0pzNzZCcTdHaUJqTm56eldhSVk0SmJvMW8ifQ.rF1INd7UF2UUIgw3DWkzI524ASp80-I_VTlMwbvbNVmVmGz9z4zL47aTIfl0AE9tUWrp4EUzk94XbqbTEyr4Cw",
"issuerKey": {
"crv": "Ed25519",
"x": "xWqc4dXP9LHY_Ia09ijwYuMFxHUjbo2HZOvcquHT0eE",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-a9dd74a03970acdb",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example",
"expectedVct": "urn:eudi:pid:2",
"statusListJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjMwMjU1MiwiZXhwIjoxNzkyMzA2MTUyLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoxLCJsc3QiOiJlTnBqWUFBQUFBSUFBUSJ9fQ.-LALHjNMKDkk0wbZvjXQjh-yuGRi-Jz0ZV3kYmT1K5KVRjPnKXZBB7H6SDd4Mrt15-mYduZgcM3LH8zq5w3CBQ"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwtvc.vct-mismatch"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,79 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/aere-pid.vct",
"artifact": "sdjwt-vc-presentation",
"title": "a credential typed dc+sd-jwt with no vct at all",
"source": "derived from sdjwt-vc-presentation/aere-pid.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": "sdjwt-vc-presentation/aere-pid.valid",
"mutation": {
"producer": "the issuer signed an SD-JWT typed dc+sd-jwt without vct; the holder presented it",
"changed": [
[
"sdJwt"
]
]
},
"input": {
"sdJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6ImRjK3NkLWp3dCJ9.eyJnaXZlbl9uYW1lIjoiQWRhIiwiX3NkX2FsZyI6InNoYS0yNTYiLCJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiaWF0IjoxNzkyMzAyNTUyLCJleHAiOjE4MjM4Mzg1NTIsImNuZiI6eyJqd2siOnsiY3J2IjoiRWQyNTUxOSIsIngiOiJ3c185V0FUbEl0M1c5NkpVLTZjUHItY2Fsa3pIZk1JNmF1ZWszSzU5VkRRIiwia3R5IjoiT0tQIn19fQ.vgtkVUyEUw5Fq_2vQzmMPhFoEeNmeJatrDDqeSlNKXo5vIm3SOLFUTQABT5_ZWKXOIiBDw1og6x-95xXdAGSBw~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE3OTIzMDI1NTIsImF1ZCI6Imh0dHBzOi8vdmVyaWZpZXIuZXhhbXBsZSIsIm5vbmNlIjoibi1hOWRkNzRhMDM5NzBhY2RiIiwic2RfaGFzaCI6InJWaWRYbXBJXzNVcTFqSy1rR09EYjFIMEZxQk9IRWdsYnEtUGZhb2FlcGsifQ.BOiEAOVRGdarYAw3qs0gXi3X0qRbQpa-nd88imbiZRKNnkSB9BP-CrCO2eUFy_UwfrCMoVhoX4LP0USEmCP6BQ",
"issuerKey": {
"crv": "Ed25519",
"x": "xWqc4dXP9LHY_Ia09ijwYuMFxHUjbo2HZOvcquHT0eE",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "n-a9dd74a03970acdb",
"now": "2026-10-18T05:50:12.000Z",
"expectedIssuer": "https://issuer.example",
"expectedVct": "urn:eudi:pid:1",
"statusListJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjMwMjU1MiwiZXhwIjoxNzkyMzA2MTUyLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoxLCJsc3QiOiJlTnBqWUFBQUFBSUFBUSJ9fQ.-LALHjNMKDkk0wbZvjXQjh-yuGRi-Jz0ZV3kYmT1K5KVRjPnKXZBB7H6SDd4Mrt15-mYduZgcM3LH8zq5w3CBQ"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwtvc.vct"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,69 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/sd-jwt-vc-8-bits.valid",
"artifact": "sdjwt-vc-presentation",
"title": "the same credential with the 8-bit list of @owf/token-status-list",
"source": "@sd-jwt/sd-jwt-vc 0.23.0 and @owf/token-status-list 0.5.0 with jose 6.2.12 (interop/fixturi-interop-sdjwt-vc.json of the identity component, generated 2026-10-18; their test keys made and discarded at generation)",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": null,
"mutation": null,
"input": {
"sdJwt": "eyJ0eXAiOiJkYytzZC1qd3QiLCJhbGciOiJFZERTQSJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmxvci5leGFtcGxlIiwiaWF0IjoxNzkyMjgxNjAwLCJuYmYiOjE3OTIyODE2MDAsImV4cCI6MTgyMzgxNzYwMCwic3RhdHVzIjp7InN0YXR1c19saXN0Ijp7ImlkeCI6NSwidXJpIjoiaHR0cHM6Ly9pc3N1ZXIuZXhhbXBsZS9zdGF0dXMvcGlkLzEifX0sIm5hdGlvbmFsaXRpZXMiOlt7Ii4uLiI6InlmQ0kwTmlLd21zMEVnVldvREU2d3l1VVIyN21RMXVHY1dSV2hzUVlsOWcifSx7Ii4uLiI6Inc1YnJ2M0NJLW1XT1V1SHAxMjEyR1R4OHlkSUNUUkpYS0JKdm5IMWhBNlEifV0sImlzc3VpbmdfYXV0aG9yaXR5IjoiRXhhbXBsZSBBdXRob3JpdHkiLCJpc3N1aW5nX2NvdW50cnkiOiJSTyIsImNuZiI6eyJqd2siOnsiY3J2IjoiRWQyNTUxOSIsIngiOiIzSVhUQTFkWG5IUUpydVdpcHZRRUVSczNaTTBhX3RoQ3NTM1pvcER2YW1VIiwia3R5IjoiT0tQIn19LCJfc2QiOlsiUE1WRGFGZ2FtYkpWX3BvTkJWR1hfbTNzWjFIRFpTT0FWbFJCbmUyZ0d6dyIsIlNhVTlYaXhrU21ENVZiU3RvZ042Ymh4ckVkR21KQWhfb0JFM3V5RFhULXMiLCJVLWFoTFlqdVl1ZnVzMXNDWVBITDBkNUhkYjlVNUpxUDJ4X0dMVklVaW93IiwiZVBCOFZNQ1ZPTGY4OVlTU1o0NGs2Q3lVLUdhRzRwM055cHVDU3h3cUJjOCIsImVnWVhkVGxzNXVTZmpFYVJSUWo1LUpCeHJKOXF2TjZPYTJNdDlHR3VmUzAiLCJndUpYclNEaktYaWg4NWlwaVBzeXdnUzQzZHB6NElHR1RfU292d0ZFdlpRIiwibFVxaFJtb29fVWdrcm1iTTVhSlU5NFNfVkt0VTJoNkRvNlRtcG9TX0xkdyJdLCJfc2RfYWxnIjoic2hhLTI1NiJ9.xE1r3QgOhiLHKuDuWAK51bmR9HicD9PYTMwHhRmfTDCwPdAjxUJZ6CzH_aYjvJ69mDnuYW2vrtTkGZl9DfwGCg~WyJjMTI0ZGMzYWVhYTNkNjEyIiwiYmlydGhkYXRlIiwiMTk5MC0wMS0wMSJd~WyIzZTkwZWUzMWE2YmZhODE1IiwiYWdlX292ZXJfMTgiLHRydWVd~WyI2MTQ5NGMyZmFhZjRhMGE5IiwiUk8iXQ~eyJ0eXAiOiJrYitqd3QiLCJhbGciOiJFZERTQSJ9.eyJhdWQiOiJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUiLCJub25jZSI6ImludGVyb3AtdmMtZDc2ZDU5NmExYjdkIiwiaWF0IjoxNzkyMjgxNjAwLCJzZF9oYXNoIjoiRE1jbEh4QVZ0SkE2QXpZVGZDX0l1SnhQX28zMDVnUkx5ckxUS1owUWhkZyJ9.fx0jsSAGfSyFzKcjxDT-r_vXqP2FxbuGaC-2RS7_oCtjej8hHDUi-V7rHKlWMkS56yvCcVnYJFWdcz8vr7FxAw",
"issuerKey": {
"crv": "Ed25519",
"x": "qwjKP3mAWl0rQJi-UunAZ_nAEJbLgc56-bc9IuVmV9s",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "interop-vc-d76d596a1b7d",
"now": "2026-10-18T00:01:00.000Z",
"expectedVct": "urn:eudi:pid:1",
"statusListJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjI4MTYwMCwiZXhwIjoxNzkyMjg1MjAwLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjo4LCJsc3QiOiJlTnBqWUVBRkFBQVFBQUUifX0.4lWY5Vh_PBhMKFkjLu83rSvZNq4dYowJpUEOyvClhauQqgbBY1lDO0YRA7kQU0MRQFhIvWnQWcDFpeSlMQ0VCg"
},
"expected": {
"verdict": "VALID",
"failed": [],
"levels": {
"integrity": "PASSED",
"authenticity": "PASSED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,70 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/sd-jwt-vc-es256.valid",
"artifact": "sdjwt-vc-presentation",
"title": "the same with ES256 keys",
"source": "@sd-jwt/sd-jwt-vc 0.23.0 and @owf/token-status-list 0.5.0 with jose 6.2.12 (interop/fixturi-interop-sdjwt-vc.json of the identity component, generated 2026-10-18; their test keys made and discarded at generation)",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": null,
"mutation": null,
"input": {
"sdJwt": "eyJ0eXAiOiJkYytzZC1qd3QiLCJhbGciOiJFUzI1NiJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmxvci5leGFtcGxlIiwiaWF0IjoxNzkyMjgxNjAwLCJuYmYiOjE3OTIyODE2MDAsImV4cCI6MTgyMzgxNzYwMCwic3RhdHVzIjp7InN0YXR1c19saXN0Ijp7ImlkeCI6NSwidXJpIjoiaHR0cHM6Ly9pc3N1ZXIuZXhhbXBsZS9zdGF0dXMvcGlkLzEifX0sIm5hdGlvbmFsaXRpZXMiOlt7Ii4uLiI6Ilh0VWE1a2JRZzdCNnZubERDbjBIR0NMY3F6MU1tdW1hSEp1RHRkQ2RwUkkifSx7Ii4uLiI6IlV1VUI5RGt5MXNyOWdfY1pwbElQZ0V6OEZtaG5OOU5BSkFaSnVoYTRhRTgifV0sImlzc3VpbmdfYXV0aG9yaXR5IjoiRXhhbXBsZSBBdXRob3JpdHkiLCJpc3N1aW5nX2NvdW50cnkiOiJSTyIsImNuZiI6eyJqd2siOnsia3R5IjoiRUMiLCJ4IjoiWlcwZ0RtM0xxNHFfNWpBbi0wa21DVzVteDVmRGI1ZXJUT0ttUTVDMnNjTSIsInkiOiJsaHJMWlY2MkZDS01KYW5WNlZ2RGZfZ3dEbXBsVHhYWHI2c3ZxM3pYQVR3IiwiY3J2IjoiUC0yNTYifX0sIl9zZCI6WyIwMWh2UldpRHdCbnhIS0NvMW5GeVkzN18zZUFMSTdUUnFJdHd0MExzamIwIiwiQ19XUWdyOFUyamNGbEhaRm1hbFJ6N3cxbVdpNTdtZlY0OWdfZUs0aEZNdyIsIkVPX1Y4T3pzSks2Q3NocXJ6ZXMzSzFQRzY2V05fUkM4b1htOHZpTzNrMTAiLCJSRHFwYUNxb0VPbzFqRHViQXh3aTRDbzkyMlItdVJ0dmFDdVM5UW90UlJVIiwiVkliVUdIWl9DTVpPZVlMTVVOYTUyMHctTEtCUmgzWFQwOGo5elpBWk9XWSIsImdtMHNPNU5sM3NhSjhJODgtMTd4T1NiT3c0UWpGcTVZTUU2VzI2YUYtWVEiLCJrZWpHLTU0YjUzWVBYWmtKV2FSZEpvR1RUZGJyeUlUdmVPY1lrYlRBWnBBIl0sIl9zZF9hbGciOiJzaGEtMjU2In0.p4dhgj0gszwe4kXzwh4TbJKVoY3-sNSjLI0tUlQrWEpHxvlEenToGA6YgcRFDWmitv1_mMHUNzwjW_nd7GOyyA~WyJhYzlkNmM2NDlmNDhhZGUwIiwiYmlydGhkYXRlIiwiMTk5MC0wMS0wMSJd~WyI1ODAwMzI3YjZiODlhMWFiIiwiYWdlX292ZXJfMTgiLHRydWVd~WyJiZTU0Mzg5MjcwMGU5YWYxIiwiUk8iXQ~eyJ0eXAiOiJrYitqd3QiLCJhbGciOiJFUzI1NiJ9.eyJhdWQiOiJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUiLCJub25jZSI6ImludGVyb3AtdmMtZDc2ZDU5NmExYjdkIiwiaWF0IjoxNzkyMjgxNjAwLCJzZF9oYXNoIjoiajFVQTlYdXcwdEx0c3lDWkNsQ0RzVDNrOUhvVVNwY0hjdGphM2l6YlBobyJ9.ZEoIdkNAtBkJD59nrmm1efs9T5pmvUNUbIME4lHJ7lmMVlIqQazaROGiw9tyCndlwMyb9T9mNmrU6rDBf3rg6Q",
"issuerKey": {
"kty": "EC",
"x": "R_TdGYHfNybEvRm1kG75eylpg-XP19wF1jHT0MhAu94",
"y": "641tE1De1QAXA_eevwKYPho1pjGRZdu-SOqyGcysgCM",
"crv": "P-256"
},
"issuerAlg": "ES256",
"audience": "https://verifier.example",
"nonce": "interop-vc-d76d596a1b7d",
"now": "2026-10-18T00:01:00.000Z",
"expectedVct": "urn:eudi:pid:1",
"statusListJwt": "eyJhbGciOiJFUzI1NiIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjI4MTYwMCwiZXhwIjoxNzkyMjg1MjAwLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoxLCJsc3QiOiJlTnBqWUFBQUFBSUFBUSJ9fQ.c9Nl7zzk5iGSPH15mq2ADe_VH9qi61n_ZBc4H70VmqPFw02xXvhB8iUU9FhvBBbkiQB9LBIQHtgc2uQeWNuZZw"
},
"expected": {
"verdict": "VALID",
"failed": [],
"levels": {
"integrity": "PASSED",
"authenticity": "PASSED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,69 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/sd-jwt-vc-status-waived.partial",
"artifact": "sdjwt-vc-presentation",
"title": "the @sd-jwt/sd-jwt-vc credential without its list, the status waived: not judged, so not VALID",
"source": "@sd-jwt/sd-jwt-vc 0.23.0 and @owf/token-status-list 0.5.0 with jose 6.2.12 (interop/fixturi-interop-sdjwt-vc.json of the identity component, generated 2026-10-18; their test keys made and discarded at generation)",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": null,
"mutation": null,
"input": {
"sdJwt": "eyJ0eXAiOiJkYytzZC1qd3QiLCJhbGciOiJFZERTQSJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmxvci5leGFtcGxlIiwiaWF0IjoxNzkyMjgxNjAwLCJuYmYiOjE3OTIyODE2MDAsImV4cCI6MTgyMzgxNzYwMCwic3RhdHVzIjp7InN0YXR1c19saXN0Ijp7ImlkeCI6NSwidXJpIjoiaHR0cHM6Ly9pc3N1ZXIuZXhhbXBsZS9zdGF0dXMvcGlkLzEifX0sIm5hdGlvbmFsaXRpZXMiOlt7Ii4uLiI6InlmQ0kwTmlLd21zMEVnVldvREU2d3l1VVIyN21RMXVHY1dSV2hzUVlsOWcifSx7Ii4uLiI6Inc1YnJ2M0NJLW1XT1V1SHAxMjEyR1R4OHlkSUNUUkpYS0JKdm5IMWhBNlEifV0sImlzc3VpbmdfYXV0aG9yaXR5IjoiRXhhbXBsZSBBdXRob3JpdHkiLCJpc3N1aW5nX2NvdW50cnkiOiJSTyIsImNuZiI6eyJqd2siOnsiY3J2IjoiRWQyNTUxOSIsIngiOiIzSVhUQTFkWG5IUUpydVdpcHZRRUVSczNaTTBhX3RoQ3NTM1pvcER2YW1VIiwia3R5IjoiT0tQIn19LCJfc2QiOlsiUE1WRGFGZ2FtYkpWX3BvTkJWR1hfbTNzWjFIRFpTT0FWbFJCbmUyZ0d6dyIsIlNhVTlYaXhrU21ENVZiU3RvZ042Ymh4ckVkR21KQWhfb0JFM3V5RFhULXMiLCJVLWFoTFlqdVl1ZnVzMXNDWVBITDBkNUhkYjlVNUpxUDJ4X0dMVklVaW93IiwiZVBCOFZNQ1ZPTGY4OVlTU1o0NGs2Q3lVLUdhRzRwM055cHVDU3h3cUJjOCIsImVnWVhkVGxzNXVTZmpFYVJSUWo1LUpCeHJKOXF2TjZPYTJNdDlHR3VmUzAiLCJndUpYclNEaktYaWg4NWlwaVBzeXdnUzQzZHB6NElHR1RfU292d0ZFdlpRIiwibFVxaFJtb29fVWdrcm1iTTVhSlU5NFNfVkt0VTJoNkRvNlRtcG9TX0xkdyJdLCJfc2RfYWxnIjoic2hhLTI1NiJ9.xE1r3QgOhiLHKuDuWAK51bmR9HicD9PYTMwHhRmfTDCwPdAjxUJZ6CzH_aYjvJ69mDnuYW2vrtTkGZl9DfwGCg~WyJjMTI0ZGMzYWVhYTNkNjEyIiwiYmlydGhkYXRlIiwiMTk5MC0wMS0wMSJd~WyIzZTkwZWUzMWE2YmZhODE1IiwiYWdlX292ZXJfMTgiLHRydWVd~WyI2MTQ5NGMyZmFhZjRhMGE5IiwiUk8iXQ~eyJ0eXAiOiJrYitqd3QiLCJhbGciOiJFZERTQSJ9.eyJhdWQiOiJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUiLCJub25jZSI6ImludGVyb3AtdmMtZDc2ZDU5NmExYjdkIiwiaWF0IjoxNzkyMjgxNjAwLCJzZF9oYXNoIjoiRE1jbEh4QVZ0SkE2QXpZVGZDX0l1SnhQX28zMDVnUkx5ckxUS1owUWhkZyJ9.fx0jsSAGfSyFzKcjxDT-r_vXqP2FxbuGaC-2RS7_oCtjej8hHDUi-V7rHKlWMkS56yvCcVnYJFWdcz8vr7FxAw",
"issuerKey": {
"crv": "Ed25519",
"x": "qwjKP3mAWl0rQJi-UunAZ_nAEJbLgc56-bc9IuVmV9s",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "interop-vc-d76d596a1b7d",
"now": "2026-10-18T00:01:00.000Z",
"expectedVct": "urn:eudi:pid:1",
"requireStatus": false
},
"expected": {
"verdict": "PARTIAL",
"failed": [],
"levels": {
"integrity": "NOT_MEASURED",
"authenticity": "PASSED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,78 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/sd-jwt-vc.status-list-expired",
"artifact": "sdjwt-vc-presentation",
"title": "the list of @owf/token-status-list, expired",
"source": "derived from sdjwt-vc-presentation/sd-jwt-vc.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": "sdjwt-vc-presentation/sd-jwt-vc.valid",
"mutation": {
"producer": "@owf/token-status-list wrote the list with exp before the verifier clock",
"changed": [
[
"statusListJwt"
]
]
},
"input": {
"sdJwt": "eyJ0eXAiOiJkYytzZC1qd3QiLCJhbGciOiJFZERTQSJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmxvci5leGFtcGxlIiwiaWF0IjoxNzkyMjgxNjAwLCJuYmYiOjE3OTIyODE2MDAsImV4cCI6MTgyMzgxNzYwMCwic3RhdHVzIjp7InN0YXR1c19saXN0Ijp7ImlkeCI6NSwidXJpIjoiaHR0cHM6Ly9pc3N1ZXIuZXhhbXBsZS9zdGF0dXMvcGlkLzEifX0sIm5hdGlvbmFsaXRpZXMiOlt7Ii4uLiI6InlmQ0kwTmlLd21zMEVnVldvREU2d3l1VVIyN21RMXVHY1dSV2hzUVlsOWcifSx7Ii4uLiI6Inc1YnJ2M0NJLW1XT1V1SHAxMjEyR1R4OHlkSUNUUkpYS0JKdm5IMWhBNlEifV0sImlzc3VpbmdfYXV0aG9yaXR5IjoiRXhhbXBsZSBBdXRob3JpdHkiLCJpc3N1aW5nX2NvdW50cnkiOiJSTyIsImNuZiI6eyJqd2siOnsiY3J2IjoiRWQyNTUxOSIsIngiOiIzSVhUQTFkWG5IUUpydVdpcHZRRUVSczNaTTBhX3RoQ3NTM1pvcER2YW1VIiwia3R5IjoiT0tQIn19LCJfc2QiOlsiUE1WRGFGZ2FtYkpWX3BvTkJWR1hfbTNzWjFIRFpTT0FWbFJCbmUyZ0d6dyIsIlNhVTlYaXhrU21ENVZiU3RvZ042Ymh4ckVkR21KQWhfb0JFM3V5RFhULXMiLCJVLWFoTFlqdVl1ZnVzMXNDWVBITDBkNUhkYjlVNUpxUDJ4X0dMVklVaW93IiwiZVBCOFZNQ1ZPTGY4OVlTU1o0NGs2Q3lVLUdhRzRwM055cHVDU3h3cUJjOCIsImVnWVhkVGxzNXVTZmpFYVJSUWo1LUpCeHJKOXF2TjZPYTJNdDlHR3VmUzAiLCJndUpYclNEaktYaWg4NWlwaVBzeXdnUzQzZHB6NElHR1RfU292d0ZFdlpRIiwibFVxaFJtb29fVWdrcm1iTTVhSlU5NFNfVkt0VTJoNkRvNlRtcG9TX0xkdyJdLCJfc2RfYWxnIjoic2hhLTI1NiJ9.xE1r3QgOhiLHKuDuWAK51bmR9HicD9PYTMwHhRmfTDCwPdAjxUJZ6CzH_aYjvJ69mDnuYW2vrtTkGZl9DfwGCg~WyJjMTI0ZGMzYWVhYTNkNjEyIiwiYmlydGhkYXRlIiwiMTk5MC0wMS0wMSJd~WyIzZTkwZWUzMWE2YmZhODE1IiwiYWdlX292ZXJfMTgiLHRydWVd~WyI2MTQ5NGMyZmFhZjRhMGE5IiwiUk8iXQ~eyJ0eXAiOiJrYitqd3QiLCJhbGciOiJFZERTQSJ9.eyJhdWQiOiJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUiLCJub25jZSI6ImludGVyb3AtdmMtZDc2ZDU5NmExYjdkIiwiaWF0IjoxNzkyMjgxNjAwLCJzZF9oYXNoIjoiRE1jbEh4QVZ0SkE2QXpZVGZDX0l1SnhQX28zMDVnUkx5ckxUS1owUWhkZyJ9.fx0jsSAGfSyFzKcjxDT-r_vXqP2FxbuGaC-2RS7_oCtjej8hHDUi-V7rHKlWMkS56yvCcVnYJFWdcz8vr7FxAw",
"issuerKey": {
"crv": "Ed25519",
"x": "qwjKP3mAWl0rQJi-UunAZ_nAEJbLgc56-bc9IuVmV9s",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "interop-vc-d76d596a1b7d",
"now": "2026-10-18T00:01:00.000Z",
"expectedVct": "urn:eudi:pid:1",
"statusListJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjI4MTYwMCwiZXhwIjoxNzkyMjgxNjMwLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoxLCJsc3QiOiJlTnBqWUFBQUFBSUFBUSJ9fQ.Kxsth2IkgDtbkwdxbG1tSGSNx_g0_sQNvwaZWjpggXwuv_TQdpqdAWQL9Io8zsOSwi4bSF569tZ35TvVfFNWBQ"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwtvc.status-list"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,78 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/sd-jwt-vc.status-list-other-uri",
"artifact": "sdjwt-vc-presentation",
"title": "the list of @owf/token-status-list published for another uri",
"source": "derived from sdjwt-vc-presentation/sd-jwt-vc.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": "sdjwt-vc-presentation/sd-jwt-vc.valid",
"mutation": {
"producer": "@owf/token-status-list wrote the list with another sub",
"changed": [
[
"statusListJwt"
]
]
},
"input": {
"sdJwt": "eyJ0eXAiOiJkYytzZC1qd3QiLCJhbGciOiJFZERTQSJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmxvci5leGFtcGxlIiwiaWF0IjoxNzkyMjgxNjAwLCJuYmYiOjE3OTIyODE2MDAsImV4cCI6MTgyMzgxNzYwMCwic3RhdHVzIjp7InN0YXR1c19saXN0Ijp7ImlkeCI6NSwidXJpIjoiaHR0cHM6Ly9pc3N1ZXIuZXhhbXBsZS9zdGF0dXMvcGlkLzEifX0sIm5hdGlvbmFsaXRpZXMiOlt7Ii4uLiI6InlmQ0kwTmlLd21zMEVnVldvREU2d3l1VVIyN21RMXVHY1dSV2hzUVlsOWcifSx7Ii4uLiI6Inc1YnJ2M0NJLW1XT1V1SHAxMjEyR1R4OHlkSUNUUkpYS0JKdm5IMWhBNlEifV0sImlzc3VpbmdfYXV0aG9yaXR5IjoiRXhhbXBsZSBBdXRob3JpdHkiLCJpc3N1aW5nX2NvdW50cnkiOiJSTyIsImNuZiI6eyJqd2siOnsiY3J2IjoiRWQyNTUxOSIsIngiOiIzSVhUQTFkWG5IUUpydVdpcHZRRUVSczNaTTBhX3RoQ3NTM1pvcER2YW1VIiwia3R5IjoiT0tQIn19LCJfc2QiOlsiUE1WRGFGZ2FtYkpWX3BvTkJWR1hfbTNzWjFIRFpTT0FWbFJCbmUyZ0d6dyIsIlNhVTlYaXhrU21ENVZiU3RvZ042Ymh4ckVkR21KQWhfb0JFM3V5RFhULXMiLCJVLWFoTFlqdVl1ZnVzMXNDWVBITDBkNUhkYjlVNUpxUDJ4X0dMVklVaW93IiwiZVBCOFZNQ1ZPTGY4OVlTU1o0NGs2Q3lVLUdhRzRwM055cHVDU3h3cUJjOCIsImVnWVhkVGxzNXVTZmpFYVJSUWo1LUpCeHJKOXF2TjZPYTJNdDlHR3VmUzAiLCJndUpYclNEaktYaWg4NWlwaVBzeXdnUzQzZHB6NElHR1RfU292d0ZFdlpRIiwibFVxaFJtb29fVWdrcm1iTTVhSlU5NFNfVkt0VTJoNkRvNlRtcG9TX0xkdyJdLCJfc2RfYWxnIjoic2hhLTI1NiJ9.xE1r3QgOhiLHKuDuWAK51bmR9HicD9PYTMwHhRmfTDCwPdAjxUJZ6CzH_aYjvJ69mDnuYW2vrtTkGZl9DfwGCg~WyJjMTI0ZGMzYWVhYTNkNjEyIiwiYmlydGhkYXRlIiwiMTk5MC0wMS0wMSJd~WyIzZTkwZWUzMWE2YmZhODE1IiwiYWdlX292ZXJfMTgiLHRydWVd~WyI2MTQ5NGMyZmFhZjRhMGE5IiwiUk8iXQ~eyJ0eXAiOiJrYitqd3QiLCJhbGciOiJFZERTQSJ9.eyJhdWQiOiJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUiLCJub25jZSI6ImludGVyb3AtdmMtZDc2ZDU5NmExYjdkIiwiaWF0IjoxNzkyMjgxNjAwLCJzZF9oYXNoIjoiRE1jbEh4QVZ0SkE2QXpZVGZDX0l1SnhQX28zMDVnUkx5ckxUS1owUWhkZyJ9.fx0jsSAGfSyFzKcjxDT-r_vXqP2FxbuGaC-2RS7_oCtjej8hHDUi-V7rHKlWMkS56yvCcVnYJFWdcz8vr7FxAw",
"issuerKey": {
"crv": "Ed25519",
"x": "qwjKP3mAWl0rQJi-UunAZ_nAEJbLgc56-bc9IuVmV9s",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "interop-vc-d76d596a1b7d",
"now": "2026-10-18T00:01:00.000Z",
"expectedVct": "urn:eudi:pid:1",
"statusListJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMS1hbHRhIiwiaWF0IjoxNzkyMjgxNjAwLCJleHAiOjE3OTIyODUyMDAsInN0YXR1c19saXN0Ijp7ImJpdHMiOjEsImxzdCI6ImVOcGpZQUFBQUFJQUFRIn19.SVVx1R0qyArp0nWD0PfwLBg63oZeoaRIZGNhPYdU4QG0yh3YasSZ_kIimjEW2hEz6NzH_HEW3Ci61a5Dze3nCA"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwtvc.status-list"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,78 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/sd-jwt-vc.status-revoked",
"artifact": "sdjwt-vc-presentation",
"title": "the list of @owf/token-status-list with status 1 at the index",
"source": "derived from sdjwt-vc-presentation/sd-jwt-vc.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": "sdjwt-vc-presentation/sd-jwt-vc.valid",
"mutation": {
"producer": "@owf/token-status-list wrote the list with INVALID at the credential's index",
"changed": [
[
"statusListJwt"
]
]
},
"input": {
"sdJwt": "eyJ0eXAiOiJkYytzZC1qd3QiLCJhbGciOiJFZERTQSJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmxvci5leGFtcGxlIiwiaWF0IjoxNzkyMjgxNjAwLCJuYmYiOjE3OTIyODE2MDAsImV4cCI6MTgyMzgxNzYwMCwic3RhdHVzIjp7InN0YXR1c19saXN0Ijp7ImlkeCI6NSwidXJpIjoiaHR0cHM6Ly9pc3N1ZXIuZXhhbXBsZS9zdGF0dXMvcGlkLzEifX0sIm5hdGlvbmFsaXRpZXMiOlt7Ii4uLiI6InlmQ0kwTmlLd21zMEVnVldvREU2d3l1VVIyN21RMXVHY1dSV2hzUVlsOWcifSx7Ii4uLiI6Inc1YnJ2M0NJLW1XT1V1SHAxMjEyR1R4OHlkSUNUUkpYS0JKdm5IMWhBNlEifV0sImlzc3VpbmdfYXV0aG9yaXR5IjoiRXhhbXBsZSBBdXRob3JpdHkiLCJpc3N1aW5nX2NvdW50cnkiOiJSTyIsImNuZiI6eyJqd2siOnsiY3J2IjoiRWQyNTUxOSIsIngiOiIzSVhUQTFkWG5IUUpydVdpcHZRRUVSczNaTTBhX3RoQ3NTM1pvcER2YW1VIiwia3R5IjoiT0tQIn19LCJfc2QiOlsiUE1WRGFGZ2FtYkpWX3BvTkJWR1hfbTNzWjFIRFpTT0FWbFJCbmUyZ0d6dyIsIlNhVTlYaXhrU21ENVZiU3RvZ042Ymh4ckVkR21KQWhfb0JFM3V5RFhULXMiLCJVLWFoTFlqdVl1ZnVzMXNDWVBITDBkNUhkYjlVNUpxUDJ4X0dMVklVaW93IiwiZVBCOFZNQ1ZPTGY4OVlTU1o0NGs2Q3lVLUdhRzRwM055cHVDU3h3cUJjOCIsImVnWVhkVGxzNXVTZmpFYVJSUWo1LUpCeHJKOXF2TjZPYTJNdDlHR3VmUzAiLCJndUpYclNEaktYaWg4NWlwaVBzeXdnUzQzZHB6NElHR1RfU292d0ZFdlpRIiwibFVxaFJtb29fVWdrcm1iTTVhSlU5NFNfVkt0VTJoNkRvNlRtcG9TX0xkdyJdLCJfc2RfYWxnIjoic2hhLTI1NiJ9.xE1r3QgOhiLHKuDuWAK51bmR9HicD9PYTMwHhRmfTDCwPdAjxUJZ6CzH_aYjvJ69mDnuYW2vrtTkGZl9DfwGCg~WyJjMTI0ZGMzYWVhYTNkNjEyIiwiYmlydGhkYXRlIiwiMTk5MC0wMS0wMSJd~WyIzZTkwZWUzMWE2YmZhODE1IiwiYWdlX292ZXJfMTgiLHRydWVd~WyI2MTQ5NGMyZmFhZjRhMGE5IiwiUk8iXQ~eyJ0eXAiOiJrYitqd3QiLCJhbGciOiJFZERTQSJ9.eyJhdWQiOiJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUiLCJub25jZSI6ImludGVyb3AtdmMtZDc2ZDU5NmExYjdkIiwiaWF0IjoxNzkyMjgxNjAwLCJzZF9oYXNoIjoiRE1jbEh4QVZ0SkE2QXpZVGZDX0l1SnhQX28zMDVnUkx5ckxUS1owUWhkZyJ9.fx0jsSAGfSyFzKcjxDT-r_vXqP2FxbuGaC-2RS7_oCtjej8hHDUi-V7rHKlWMkS56yvCcVnYJFWdcz8vr7FxAw",
"issuerKey": {
"crv": "Ed25519",
"x": "qwjKP3mAWl0rQJi-UunAZ_nAEJbLgc56-bc9IuVmV9s",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "interop-vc-d76d596a1b7d",
"now": "2026-10-18T00:01:00.000Z",
"expectedVct": "urn:eudi:pid:1",
"statusListJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjI4MTYwMCwiZXhwIjoxNzkyMjg1MjAwLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoxLCJsc3QiOiJlTnBUWUFBQUFFSUFJUSJ9fQ.E3ryJi_TXj8M0rBCbt0WNKkBeIiwTywQZvDeQVkq_Jl6QO3fVMX3pUa3u98MHOx7gnk36AWzs8Kkm7ix6qirDQ"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwtvc.status-revoked"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,78 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/sd-jwt-vc.status-suspended",
"artifact": "sdjwt-vc-presentation",
"title": "the 2-bit list of @owf/token-status-list with status 2 at the index",
"source": "derived from sdjwt-vc-presentation/sd-jwt-vc.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": "sdjwt-vc-presentation/sd-jwt-vc.valid",
"mutation": {
"producer": "@owf/token-status-list wrote a 2-bit list with SUSPENDED at the credential's index",
"changed": [
[
"statusListJwt"
]
]
},
"input": {
"sdJwt": "eyJ0eXAiOiJkYytzZC1qd3QiLCJhbGciOiJFZERTQSJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmxvci5leGFtcGxlIiwiaWF0IjoxNzkyMjgxNjAwLCJuYmYiOjE3OTIyODE2MDAsImV4cCI6MTgyMzgxNzYwMCwic3RhdHVzIjp7InN0YXR1c19saXN0Ijp7ImlkeCI6NSwidXJpIjoiaHR0cHM6Ly9pc3N1ZXIuZXhhbXBsZS9zdGF0dXMvcGlkLzEifX0sIm5hdGlvbmFsaXRpZXMiOlt7Ii4uLiI6InlmQ0kwTmlLd21zMEVnVldvREU2d3l1VVIyN21RMXVHY1dSV2hzUVlsOWcifSx7Ii4uLiI6Inc1YnJ2M0NJLW1XT1V1SHAxMjEyR1R4OHlkSUNUUkpYS0JKdm5IMWhBNlEifV0sImlzc3VpbmdfYXV0aG9yaXR5IjoiRXhhbXBsZSBBdXRob3JpdHkiLCJpc3N1aW5nX2NvdW50cnkiOiJSTyIsImNuZiI6eyJqd2siOnsiY3J2IjoiRWQyNTUxOSIsIngiOiIzSVhUQTFkWG5IUUpydVdpcHZRRUVSczNaTTBhX3RoQ3NTM1pvcER2YW1VIiwia3R5IjoiT0tQIn19LCJfc2QiOlsiUE1WRGFGZ2FtYkpWX3BvTkJWR1hfbTNzWjFIRFpTT0FWbFJCbmUyZ0d6dyIsIlNhVTlYaXhrU21ENVZiU3RvZ042Ymh4ckVkR21KQWhfb0JFM3V5RFhULXMiLCJVLWFoTFlqdVl1ZnVzMXNDWVBITDBkNUhkYjlVNUpxUDJ4X0dMVklVaW93IiwiZVBCOFZNQ1ZPTGY4OVlTU1o0NGs2Q3lVLUdhRzRwM055cHVDU3h3cUJjOCIsImVnWVhkVGxzNXVTZmpFYVJSUWo1LUpCeHJKOXF2TjZPYTJNdDlHR3VmUzAiLCJndUpYclNEaktYaWg4NWlwaVBzeXdnUzQzZHB6NElHR1RfU292d0ZFdlpRIiwibFVxaFJtb29fVWdrcm1iTTVhSlU5NFNfVkt0VTJoNkRvNlRtcG9TX0xkdyJdLCJfc2RfYWxnIjoic2hhLTI1NiJ9.xE1r3QgOhiLHKuDuWAK51bmR9HicD9PYTMwHhRmfTDCwPdAjxUJZ6CzH_aYjvJ69mDnuYW2vrtTkGZl9DfwGCg~WyJjMTI0ZGMzYWVhYTNkNjEyIiwiYmlydGhkYXRlIiwiMTk5MC0wMS0wMSJd~WyIzZTkwZWUzMWE2YmZhODE1IiwiYWdlX292ZXJfMTgiLHRydWVd~WyI2MTQ5NGMyZmFhZjRhMGE5IiwiUk8iXQ~eyJ0eXAiOiJrYitqd3QiLCJhbGciOiJFZERTQSJ9.eyJhdWQiOiJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUiLCJub25jZSI6ImludGVyb3AtdmMtZDc2ZDU5NmExYjdkIiwiaWF0IjoxNzkyMjgxNjAwLCJzZF9oYXNoIjoiRE1jbEh4QVZ0SkE2QXpZVGZDX0l1SnhQX28zMDVnUkx5ckxUS1owUWhkZyJ9.fx0jsSAGfSyFzKcjxDT-r_vXqP2FxbuGaC-2RS7_oCtjej8hHDUi-V7rHKlWMkS56yvCcVnYJFWdcz8vr7FxAw",
"issuerKey": {
"crv": "Ed25519",
"x": "qwjKP3mAWl0rQJi-UunAZ_nAEJbLgc56-bc9IuVmV9s",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "interop-vc-d76d596a1b7d",
"now": "2026-10-18T00:01:00.000Z",
"expectedVct": "urn:eudi:pid:1",
"statusListJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjI4MTYwMCwiZXhwIjoxNzkyMjg1MjAwLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoyLCJsc3QiOiJlTnBqNEdCZ0FBQUFIQUFKIn19.YE9Lr-dw70H4bLl-RslRGHS2E59RQYCRfuhalVQteNzqeDiMyYx1rtvOx0ynhmreetKebIoKQRfzREnHF7ImDA"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwtvc.status-revoked"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,77 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/sd-jwt-vc.status-unjudged",
"artifact": "sdjwt-vc-presentation",
"title": "the @sd-jwt/sd-jwt-vc credential without its list, the status not waived",
"source": "derived from sdjwt-vc-presentation/sd-jwt-vc.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": "sdjwt-vc-presentation/sd-jwt-vc.valid",
"mutation": {
"producer": "the same credential, no list handed",
"changed": [
[
"statusListJwt"
]
]
},
"input": {
"sdJwt": "eyJ0eXAiOiJkYytzZC1qd3QiLCJhbGciOiJFZERTQSJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmxvci5leGFtcGxlIiwiaWF0IjoxNzkyMjgxNjAwLCJuYmYiOjE3OTIyODE2MDAsImV4cCI6MTgyMzgxNzYwMCwic3RhdHVzIjp7InN0YXR1c19saXN0Ijp7ImlkeCI6NSwidXJpIjoiaHR0cHM6Ly9pc3N1ZXIuZXhhbXBsZS9zdGF0dXMvcGlkLzEifX0sIm5hdGlvbmFsaXRpZXMiOlt7Ii4uLiI6InlmQ0kwTmlLd21zMEVnVldvREU2d3l1VVIyN21RMXVHY1dSV2hzUVlsOWcifSx7Ii4uLiI6Inc1YnJ2M0NJLW1XT1V1SHAxMjEyR1R4OHlkSUNUUkpYS0JKdm5IMWhBNlEifV0sImlzc3VpbmdfYXV0aG9yaXR5IjoiRXhhbXBsZSBBdXRob3JpdHkiLCJpc3N1aW5nX2NvdW50cnkiOiJSTyIsImNuZiI6eyJqd2siOnsiY3J2IjoiRWQyNTUxOSIsIngiOiIzSVhUQTFkWG5IUUpydVdpcHZRRUVSczNaTTBhX3RoQ3NTM1pvcER2YW1VIiwia3R5IjoiT0tQIn19LCJfc2QiOlsiUE1WRGFGZ2FtYkpWX3BvTkJWR1hfbTNzWjFIRFpTT0FWbFJCbmUyZ0d6dyIsIlNhVTlYaXhrU21ENVZiU3RvZ042Ymh4ckVkR21KQWhfb0JFM3V5RFhULXMiLCJVLWFoTFlqdVl1ZnVzMXNDWVBITDBkNUhkYjlVNUpxUDJ4X0dMVklVaW93IiwiZVBCOFZNQ1ZPTGY4OVlTU1o0NGs2Q3lVLUdhRzRwM055cHVDU3h3cUJjOCIsImVnWVhkVGxzNXVTZmpFYVJSUWo1LUpCeHJKOXF2TjZPYTJNdDlHR3VmUzAiLCJndUpYclNEaktYaWg4NWlwaVBzeXdnUzQzZHB6NElHR1RfU292d0ZFdlpRIiwibFVxaFJtb29fVWdrcm1iTTVhSlU5NFNfVkt0VTJoNkRvNlRtcG9TX0xkdyJdLCJfc2RfYWxnIjoic2hhLTI1NiJ9.xE1r3QgOhiLHKuDuWAK51bmR9HicD9PYTMwHhRmfTDCwPdAjxUJZ6CzH_aYjvJ69mDnuYW2vrtTkGZl9DfwGCg~WyJjMTI0ZGMzYWVhYTNkNjEyIiwiYmlydGhkYXRlIiwiMTk5MC0wMS0wMSJd~WyIzZTkwZWUzMWE2YmZhODE1IiwiYWdlX292ZXJfMTgiLHRydWVd~WyI2MTQ5NGMyZmFhZjRhMGE5IiwiUk8iXQ~eyJ0eXAiOiJrYitqd3QiLCJhbGciOiJFZERTQSJ9.eyJhdWQiOiJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUiLCJub25jZSI6ImludGVyb3AtdmMtZDc2ZDU5NmExYjdkIiwiaWF0IjoxNzkyMjgxNjAwLCJzZF9oYXNoIjoiRE1jbEh4QVZ0SkE2QXpZVGZDX0l1SnhQX28zMDVnUkx5ckxUS1owUWhkZyJ9.fx0jsSAGfSyFzKcjxDT-r_vXqP2FxbuGaC-2RS7_oCtjej8hHDUi-V7rHKlWMkS56yvCcVnYJFWdcz8vr7FxAw",
"issuerKey": {
"crv": "Ed25519",
"x": "qwjKP3mAWl0rQJi-UunAZ_nAEJbLgc56-bc9IuVmV9s",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "interop-vc-d76d596a1b7d",
"now": "2026-10-18T00:01:00.000Z",
"expectedVct": "urn:eudi:pid:1"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwtvc.status-unjudged"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,69 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/sd-jwt-vc.valid",
"artifact": "sdjwt-vc-presentation",
"title": "an SD-JWT VC issued and presented by @sd-jwt/sd-jwt-vc (EdDSA; typ dc+sd-jwt, vct urn:eudi:pid:1, a status_list reference) with the Status List Token of @owf/token-status-list (all VALID)",
"source": "@sd-jwt/sd-jwt-vc 0.23.0 and @owf/token-status-list 0.5.0 with jose 6.2.12 (interop/fixturi-interop-sdjwt-vc.json of the identity component, generated 2026-10-18; their test keys made and discarded at generation)",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": null,
"mutation": null,
"input": {
"sdJwt": "eyJ0eXAiOiJkYytzZC1qd3QiLCJhbGciOiJFZERTQSJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmxvci5leGFtcGxlIiwiaWF0IjoxNzkyMjgxNjAwLCJuYmYiOjE3OTIyODE2MDAsImV4cCI6MTgyMzgxNzYwMCwic3RhdHVzIjp7InN0YXR1c19saXN0Ijp7ImlkeCI6NSwidXJpIjoiaHR0cHM6Ly9pc3N1ZXIuZXhhbXBsZS9zdGF0dXMvcGlkLzEifX0sIm5hdGlvbmFsaXRpZXMiOlt7Ii4uLiI6InlmQ0kwTmlLd21zMEVnVldvREU2d3l1VVIyN21RMXVHY1dSV2hzUVlsOWcifSx7Ii4uLiI6Inc1YnJ2M0NJLW1XT1V1SHAxMjEyR1R4OHlkSUNUUkpYS0JKdm5IMWhBNlEifV0sImlzc3VpbmdfYXV0aG9yaXR5IjoiRXhhbXBsZSBBdXRob3JpdHkiLCJpc3N1aW5nX2NvdW50cnkiOiJSTyIsImNuZiI6eyJqd2siOnsiY3J2IjoiRWQyNTUxOSIsIngiOiIzSVhUQTFkWG5IUUpydVdpcHZRRUVSczNaTTBhX3RoQ3NTM1pvcER2YW1VIiwia3R5IjoiT0tQIn19LCJfc2QiOlsiUE1WRGFGZ2FtYkpWX3BvTkJWR1hfbTNzWjFIRFpTT0FWbFJCbmUyZ0d6dyIsIlNhVTlYaXhrU21ENVZiU3RvZ042Ymh4ckVkR21KQWhfb0JFM3V5RFhULXMiLCJVLWFoTFlqdVl1ZnVzMXNDWVBITDBkNUhkYjlVNUpxUDJ4X0dMVklVaW93IiwiZVBCOFZNQ1ZPTGY4OVlTU1o0NGs2Q3lVLUdhRzRwM055cHVDU3h3cUJjOCIsImVnWVhkVGxzNXVTZmpFYVJSUWo1LUpCeHJKOXF2TjZPYTJNdDlHR3VmUzAiLCJndUpYclNEaktYaWg4NWlwaVBzeXdnUzQzZHB6NElHR1RfU292d0ZFdlpRIiwibFVxaFJtb29fVWdrcm1iTTVhSlU5NFNfVkt0VTJoNkRvNlRtcG9TX0xkdyJdLCJfc2RfYWxnIjoic2hhLTI1NiJ9.xE1r3QgOhiLHKuDuWAK51bmR9HicD9PYTMwHhRmfTDCwPdAjxUJZ6CzH_aYjvJ69mDnuYW2vrtTkGZl9DfwGCg~WyJjMTI0ZGMzYWVhYTNkNjEyIiwiYmlydGhkYXRlIiwiMTk5MC0wMS0wMSJd~WyIzZTkwZWUzMWE2YmZhODE1IiwiYWdlX292ZXJfMTgiLHRydWVd~WyI2MTQ5NGMyZmFhZjRhMGE5IiwiUk8iXQ~eyJ0eXAiOiJrYitqd3QiLCJhbGciOiJFZERTQSJ9.eyJhdWQiOiJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUiLCJub25jZSI6ImludGVyb3AtdmMtZDc2ZDU5NmExYjdkIiwiaWF0IjoxNzkyMjgxNjAwLCJzZF9oYXNoIjoiRE1jbEh4QVZ0SkE2QXpZVGZDX0l1SnhQX28zMDVnUkx5ckxUS1owUWhkZyJ9.fx0jsSAGfSyFzKcjxDT-r_vXqP2FxbuGaC-2RS7_oCtjej8hHDUi-V7rHKlWMkS56yvCcVnYJFWdcz8vr7FxAw",
"issuerKey": {
"crv": "Ed25519",
"x": "qwjKP3mAWl0rQJi-UunAZ_nAEJbLgc56-bc9IuVmV9s",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "interop-vc-d76d596a1b7d",
"now": "2026-10-18T00:01:00.000Z",
"expectedVct": "urn:eudi:pid:1",
"statusListJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjI4MTYwMCwiZXhwIjoxNzkyMjg1MjAwLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoxLCJsc3QiOiJlTnBqWUFBQUFBSUFBUSJ9fQ.mqBQYXpgRWu78YISD865GiYpBZcni3Ejpt440jL-LNV4kVtHcdBXR-_7XA2rhoPqbTC02MzLTf8MsFS4me0kAQ"
},
"expected": {
"verdict": "VALID",
"failed": [],
"levels": {
"integrity": "PASSED",
"authenticity": "PASSED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -0,0 +1,78 @@
{
"v": 1,
"kind": "aere-conformance-vector",
"id": "sdjwt-vc-presentation/sd-jwt-vc.vct-mismatch",
"artifact": "sdjwt-vc-presentation",
"title": "the verifier expects another credential type than the @sd-jwt/sd-jwt-vc credential carries",
"source": "derived from sdjwt-vc-presentation/sd-jwt-vc.valid",
"requires": [],
"exercises": [
"sdjwt.alg",
"sdjwt.claim-conflict",
"sdjwt.crit",
"sdjwt.digest-twice",
"sdjwt.disclosure-form",
"sdjwt.disclosure-name",
"sdjwt.disclosure-twice",
"sdjwt.form",
"sdjwt.issuer",
"sdjwt.kb-audience",
"sdjwt.kb-claims",
"sdjwt.kb-cnf",
"sdjwt.kb-context",
"sdjwt.kb-freshness",
"sdjwt.kb-nonce",
"sdjwt.kb-required",
"sdjwt.kb-sd-hash",
"sdjwt.key",
"sdjwt.sd-alg",
"sdjwt.signature",
"sdjwt.time",
"sdjwt.typ",
"sdjwt.unreferenced",
"sdjwtvc.disclosed-protected",
"sdjwtvc.form",
"sdjwtvc.status-index",
"sdjwtvc.status-list",
"sdjwtvc.status-revoked",
"sdjwtvc.status-unjudged",
"sdjwtvc.vct",
"sdjwtvc.vct-expected",
"sdjwtvc.vct-mismatch"
],
"base": "sdjwt-vc-presentation/sd-jwt-vc.valid",
"mutation": {
"producer": "the same credential and list, the verifier expecting urn:eudi:pid:2",
"changed": [
[
"expectedVct"
]
]
},
"input": {
"sdJwt": "eyJ0eXAiOiJkYytzZC1qd3QiLCJhbGciOiJFZERTQSJ9.eyJ2Y3QiOiJ1cm46ZXVkaTpwaWQ6MSIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmxvci5leGFtcGxlIiwiaWF0IjoxNzkyMjgxNjAwLCJuYmYiOjE3OTIyODE2MDAsImV4cCI6MTgyMzgxNzYwMCwic3RhdHVzIjp7InN0YXR1c19saXN0Ijp7ImlkeCI6NSwidXJpIjoiaHR0cHM6Ly9pc3N1ZXIuZXhhbXBsZS9zdGF0dXMvcGlkLzEifX0sIm5hdGlvbmFsaXRpZXMiOlt7Ii4uLiI6InlmQ0kwTmlLd21zMEVnVldvREU2d3l1VVIyN21RMXVHY1dSV2hzUVlsOWcifSx7Ii4uLiI6Inc1YnJ2M0NJLW1XT1V1SHAxMjEyR1R4OHlkSUNUUkpYS0JKdm5IMWhBNlEifV0sImlzc3VpbmdfYXV0aG9yaXR5IjoiRXhhbXBsZSBBdXRob3JpdHkiLCJpc3N1aW5nX2NvdW50cnkiOiJSTyIsImNuZiI6eyJqd2siOnsiY3J2IjoiRWQyNTUxOSIsIngiOiIzSVhUQTFkWG5IUUpydVdpcHZRRUVSczNaTTBhX3RoQ3NTM1pvcER2YW1VIiwia3R5IjoiT0tQIn19LCJfc2QiOlsiUE1WRGFGZ2FtYkpWX3BvTkJWR1hfbTNzWjFIRFpTT0FWbFJCbmUyZ0d6dyIsIlNhVTlYaXhrU21ENVZiU3RvZ042Ymh4ckVkR21KQWhfb0JFM3V5RFhULXMiLCJVLWFoTFlqdVl1ZnVzMXNDWVBITDBkNUhkYjlVNUpxUDJ4X0dMVklVaW93IiwiZVBCOFZNQ1ZPTGY4OVlTU1o0NGs2Q3lVLUdhRzRwM055cHVDU3h3cUJjOCIsImVnWVhkVGxzNXVTZmpFYVJSUWo1LUpCeHJKOXF2TjZPYTJNdDlHR3VmUzAiLCJndUpYclNEaktYaWg4NWlwaVBzeXdnUzQzZHB6NElHR1RfU292d0ZFdlpRIiwibFVxaFJtb29fVWdrcm1iTTVhSlU5NFNfVkt0VTJoNkRvNlRtcG9TX0xkdyJdLCJfc2RfYWxnIjoic2hhLTI1NiJ9.xE1r3QgOhiLHKuDuWAK51bmR9HicD9PYTMwHhRmfTDCwPdAjxUJZ6CzH_aYjvJ69mDnuYW2vrtTkGZl9DfwGCg~WyJjMTI0ZGMzYWVhYTNkNjEyIiwiYmlydGhkYXRlIiwiMTk5MC0wMS0wMSJd~WyIzZTkwZWUzMWE2YmZhODE1IiwiYWdlX292ZXJfMTgiLHRydWVd~WyI2MTQ5NGMyZmFhZjRhMGE5IiwiUk8iXQ~eyJ0eXAiOiJrYitqd3QiLCJhbGciOiJFZERTQSJ9.eyJhdWQiOiJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUiLCJub25jZSI6ImludGVyb3AtdmMtZDc2ZDU5NmExYjdkIiwiaWF0IjoxNzkyMjgxNjAwLCJzZF9oYXNoIjoiRE1jbEh4QVZ0SkE2QXpZVGZDX0l1SnhQX28zMDVnUkx5ckxUS1owUWhkZyJ9.fx0jsSAGfSyFzKcjxDT-r_vXqP2FxbuGaC-2RS7_oCtjej8hHDUi-V7rHKlWMkS56yvCcVnYJFWdcz8vr7FxAw",
"issuerKey": {
"crv": "Ed25519",
"x": "qwjKP3mAWl0rQJi-UunAZ_nAEJbLgc56-bc9IuVmV9s",
"kty": "OKP"
},
"issuerAlg": "EdDSA",
"audience": "https://verifier.example",
"nonce": "interop-vc-d76d596a1b7d",
"now": "2026-10-18T00:01:00.000Z",
"expectedVct": "urn:eudi:pid:2",
"statusListJwt": "eyJhbGciOiJFZERTQSIsInR5cCI6InN0YXR1c2xpc3Qrand0In0.eyJzdWIiOiJodHRwczovL2lzc3Vlci5leGFtcGxlL3N0YXR1cy9waWQvMSIsImlhdCI6MTc5MjI4MTYwMCwiZXhwIjoxNzkyMjg1MjAwLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoxLCJsc3QiOiJlTnBqWUFBQUFBSUFBUSJ9fQ.mqBQYXpgRWu78YISD865GiYpBZcni3Ejpt440jL-LNV4kVtHcdBXR-_7XA2rhoPqbTC02MzLTf8MsFS4me0kAQ"
},
"expected": {
"verdict": "INVALID",
"failed": [
"sdjwtvc.vct-mismatch"
],
"levels": {
"integrity": "FAILED",
"authenticity": "NOT_MEASURED",
"anchoring": "NOT_MEASURED",
"finality": "NOT_MEASURED"
}
}
}

View File

@ -3,7 +3,7 @@
Post-quantum credentials with selective disclosure, bound to the holder's key, with delegation to devices, agents and short-lived
session keys, revocation and an issuer status list. Everything verifies offline, by anyone, from the files alone. Node.js 24, no
dependencies (`node:crypto` provides Ed25519 and ML-DSA-65, FIPS 204). The same keys also issue and verify standard SD-JWT (IETF
RFC 9901), below.
RFC 9901) and SD-JWT VC (the IETF draft), below, measured against other implementations in both directions.
```
node identity-cli.mjs keygen --out issuer.keys.json
@ -147,7 +147,8 @@ of the exchange. What it does not do: validate the IVMS101 schema (it carries th
## SD-JWT, the IETF standard (`sdjwt.mjs`)
The same issuer and holder keys, in the format of the standard: Selective Disclosure for JSON Web Tokens, IETF RFC 9901 (November
2025), compact serialization. Checked against the RFC's own vectors, not against another SD-JWT library (below).
2025), compact serialization. Checked against the RFC's own vectors and, since 2026-10-18, against another SD-JWT library in both
directions (below).
```js
import { issueSdJwt, presentSdJwt, verifySdJwt } from './sdjwt.mjs';
@ -173,14 +174,114 @@ gives exactly the processed payload printed in the RFC; the same presentation fo
with a disclosure removed or added after key binding, or with another issuer key, is refused.
Algorithms: ES256 (the RFC examples), EdDSA / Ed25519 (RFC 8037; the key every AERE identity has) and ML-DSA-65 with the JWK key
type AKP. The ML-DSA JOSE names come from the IETF draft `draft-ietf-cose-dilithium`, not yet a published standard, so a verifier
that does not know them rejects an ML-DSA-65 SD-JWT; for today's libraries, issue with EdDSA. A hybrid (two signatures in one token)
would need the general JWS JSON serialization and is not done here. The algorithm must match the key the verifier gives (no `none`,
no algorithm confusion); a disclosure not bound to a digest, a digest seen twice, a disclosure naming `_sd`, `...` or `__proto__`, or
one that overwrites a claim, or a claim named `__proto__` anywhere, is refused; the issuer refuses claim values that already carry SD-JWT
structure (`_sd`, `_sd_alg`, `{"...": digest}`), which would let a holder disclose claims the issuer never saw; `exp` gets no allowance and `nbf`/`iat` get 60 s, as for AERE credentials. What it is not:
SD-JWT VC (no `vct`, no type metadata), and no status list inside the token (revocation stays with the AERE credential's list).
Checked against the RFC's vectors, not against another SD-JWT library: that is not measured.
type AKP (`alg` `ML-DSA-65`, parameters `pub` and `priv`), the names and key form of IETF RFC 9964 (May 2026; until then the draft
`draft-ietf-cose-dilithium`, which this file quoted as not yet a standard). Measured 2026-10-18 on Node.js 24.14.1: jose 6.2.12 signs
and verifies ML-DSA-65 JWS through Node's WebCrypto (which prints an experimental-feature warning), its signatures and ours verify
each other, and `@sd-jwt/core` 0.23.0 accepts an ML-DSA-65 SD-JWT and KB-JWT through its injected verifier; a library that does not
know RFC 9964 rejects such a token, so for it issue with EdDSA. A hybrid (two signatures in one token) would need the general JWS JSON
serialization and is not done here. The algorithm must match the key the verifier gives (no `none`, no algorithm confusion); a
disclosure not bound to a digest, a digest seen twice, a disclosure naming `_sd`, `...`, `_sd_alg` or `__proto__`, or one that
overwrites a claim, or a claim named `__proto__` anywhere, is refused; `_sd_alg` below the top level of the payload is refused (RFC
9901 Section 4.1.1: it MUST NOT be nested; until 2026-10-18 it was kept as an ordinary claim); the `typ` value may carry the
`application/` prefix or not (RFC 7515 Section 4.1.9); the issuer refuses claim values that already carry SD-JWT structure (`_sd`,
`_sd_alg`, `{"...": digest}`), which would let a holder disclose claims the issuer never saw; `exp` gets no allowance and `nbf`/`iat`
get 60 s, as for AERE credentials. What it is not: the SD-JWT VC profile is `sdjwt-vc.mjs`, below; a plain SD-JWT carries no status
list (the AERE credential has its own list, and the SD-JWT VC profile reads a Token Status List).
**Interoperability, measured 2026-10-18** (`interop/interop-sdjwt.mjs`, run with the foreign libraries installed in a folder outside
this repository; Node.js 24.14.1; `@sd-jwt/core` 0.23.0 of openwallet-foundation-labs/identity-common-ts with `@owf/identity-common`
0.5.0, `@sd-jwt/crypto-nodejs` 0.19.0 as its hasher and salt generator, `jose` 6.2.12 as its JWS engine, its keys made in WebCrypto):
26 of 26 rows gave the verdicts expected of both sides. Ours to theirs: an SD-JWT issued and presented here (EdDSA, ES256 and
ML-DSA-65; top-level claims, list elements, two decoy digests, a Key Binding JWT with the verifier's audience and nonce) verifies
there with the same processed payload; a changed disclosure, a KB-JWT made for another audience, `alg` `none`, a digest listed
twice, a KB-JWT signed by another key than `cnf.jwk` and a nested `_sd_alg` are refused by both, each with its reason. Theirs to
ours: an SD-JWT issued and presented by `@sd-jwt/core` (nested disclosures such as `address.locality`, list elements, decoys, a
KB-JWT) verifies here with the same payload for the three algorithms, untyped with `expectedTyp: null` and typed `example+sd-jwt`
under the default, and the same tampered forms plus a disclosure removed after key binding are refused by both. The tokens they
produced are kept as fixtures (`interop/fixturi-interop-sdjwt.json`, 11 cases, with their public test keys) and `proba-sdjwt.mjs`
judges them offline at the recorded clock; the row-by-row table is `interop/rezultate-interop-sdjwt.json`. Differences found, and
what was decided: `@sd-jwt/core` puts no `typ` on an issuer-signed JWT unless told to (`SDJwtVcInstance` puts `dc+sd-jwt`) and never
checks it; our verifier requires an explicit `...+sd-jwt` type by default (RFC 9901 Section 9.11 recommends that verifiers check it)
and takes an untyped token with `expectedTyp: null`: kept. Their verifier compares the KB-JWT audience only when given
`expectedKeyBindingAudience`, and does not look at a KB-JWT at all when no `keyBindingNonce` is given; ours requires the verifier's
audience and nonce whenever a KB-JWT is present or required (Section 7.3 step 5.f): kept. Their issuer takes any secure hash of
the IANA list for `_sd_alg` (`sha-384`, `sha-512`, ...); ours understands only `sha-256` (Section 4.1.1 requires it and leaves the
rest to policy): kept, measured as our refusal of their `sha-384` token. Nested `_sd_alg`: they refused it and we kept it as a
claim; the RFC's MUST NOT decided it, repaired here. The salt of their default helper, `generateSalt(16)` of `@sd-jwt/crypto-nodejs`,
is 16 hexadecimal characters, 64 bits, under the 128 bits Section 9.3 recommends; ours is 16 random bytes; theirs, and the generator
is injectable. Disclosures are ordered by the presentation frame there and by issuance order here; the RFC orders them not at all.
An AKP JWK without `alg` is refused by Node's `crypto` and by jose alike (RFC 9964 Section 3 requires it).
## SD-JWT VC (`sdjwt-vc.mjs`)
The profile "SD-JWT-based Verifiable Digital Credentials", IETF `draft-ietf-oauth-sd-jwt-vc-19` (31 August 2026, submitted to the
IESG, not an RFC), as a thin layer over `sdjwt.mjs`, with the Token Status List of `draft-ietf-oauth-status-list-21` (21 June 2026)
read offline. No dependencies.
```js
import { issueSdJwtVc, presentSdJwtVc, verifySdJwtVc, issueStatusListJwt, readStatusListJwt } from './sdjwt-vc.mjs';
const { sdJwt } = issueSdJwtVc({ issuer, holder, vct: 'urn:eudi:pid:1', iss, claims, disclosable, arrayDisclosable, exp,
status: { status_list: { idx: 5, uri: 'https://issuer.example/status/1' } } }); // typ dc+sd-jwt; vct, iss, cnf, nbf, exp, status in the clear
const shown = presentSdJwtVc({ sdJwt, reveal: ['birthdate'], holder, audience, nonce });
const list = issueStatusListJwt({ issuer, uri, statuses: [0, 0, 0, 0, 0, 1], bits: 1, exp }); // typ statuslist+jwt, sub = uri, iat, status_list { bits, lst }
const r = verifySdJwtVc(shown, { issuerKey, audience, nonce, expectedVct: 'urn:eudi:pid:1', statusListJwt: list });
// r: { valid, reason, payload, disclosed, keyBinding, vct, status: { present, judged, uri, idx, value, name } }
```
What the verifier requires beyond RFC 9901: the header type `dc+sd-jwt` (Section 2.2.1); a `vct` in the payload equal to one the
verifier names (`expectedVct` is required: a verifier that does not say which credential type it expects would accept any); none of
`iss`, `nbf`, `exp`, `cnf`, `vct`, `vct#integrity`, `aka_vcts`, `status` selectively disclosed (Section 2.2.2.3; the issuer refuses to
make them disclosable); `exp` by default, as for a plain SD-JWT. A `status` claim is judged from the Status List Token the verifier
fetched from the `uri` the credential names and hands in (`statusListJwt`; signed with the issuer's key unless `statusListKey` says
otherwise): its signature, its `typ`, `sub` equal to that uri, `iat`, `exp`, then the status at `idx` (0 valid; 1 revoked, 2
suspended and any other value refuse; the bits are packed from the least significant bit, 1, 2, 4 or 8 per entry). A credential
that names a status nobody judged is refused by default (`requireStatus: false` accepts it and reports the status as present and
not judged); one that names no status is judged without a list. Nothing is fetched: not the list, not the type metadata of `vct`
(`vct#integrity` is carried, not resolved), and the issuer's key is the verifier's input, never resolved from `iss` (Section 2.5:
JWT VC Issuer Metadata, `x5c`) or taken from the token.
From the command line: `node identity-cli.mjs verify-sdjwt-vc --sd-jwt token.txt --issuer-key issuer.pub.json --audience A --nonce N
--expected-vct urn:eudi:pid:1 [--status-list list.txt [--status-list-key k.json]] [--status-not-required] [--expected-issuer I]
[--at T] [--json]`; 0 VALID, 1 INVALID, 2 a usage error.
**Interoperability, measured 2026-10-18** (`interop/interop-sdjwt-vc.mjs`; `@sd-jwt/sd-jwt-vc` 0.23.0, `@owf/token-status-list` 0.5.0,
jose 6.2.12, Node.js 24.14.1): 28 of 28 rows gave the verdicts expected of both sides. Ours to theirs: an SD-JWT VC issued here
(EdDSA, ES256, ML-DSA-65; `vct` `urn:eudi:pid:1`, a `status_list` reference) with our Status List Token served to their
`statusListFetcher` verifies in `SDJwtVcInstance` with `expectedVct`, the key binding audience and nonce; our list with the index
revoked, or suspended on 2 bits, our list published for another uri, a wrong expected `vct` and a KB-JWT for another audience are
refused by both; our lists on 1, 2 and 8 bits are read by their decoder index by index, and theirs by ours (12 mixed statuses on 2
bits, written equals read, both ways). Theirs to ours: their credential and their status list verify here under the default type,
and their revoked, suspended, other-uri and expired lists, a wrong `vct`, a KB-JWT for another audience and a credential they issued
without `vct` are refused here with the reason. Their tokens and lists are fixtures (`interop/fixturi-interop-sdjwt-vc.json`, 12
cases) that `proba-sdjwt-vc.mjs` judges offline. Differences: their issuer does not require `vct` and their verifier checks it only
when given `expectedVct`; here both are required. Their verifier skips the status when told (`disableStatusVerification`) and
otherwise fetches it over the network; here nothing is fetched and an unjudged status is a refusal unless waived. Both refuse to
make `vct` selectively disclosable.
**The European wallet (ARF) and the PID, read, not claimed.** Read on 2026-10-18: the Architecture and Reference Framework v3.0.0
(21 July 2026; Annex 2.02, the high-level requirements by topic), the PID Rulebook v1.7 (17 July 2026, in
eu-digital-identity-wallet/eudi-doc-attestation-rulebooks-catalog), the OpenID4VC High Assurance Interoperability Profile 1.0
(24 December 2025), `draft-ietf-oauth-sd-jwt-vc-19` and `draft-ietf-oauth-status-list-21`. This module claims no EUDI conformance:
the table says, row by row, what is measured here.
| requirement | where it is written | here |
|---|---|---|
| SD-JWT VC as one of the two common attestation formats, compact serialization | ARF ARB_01; HAIP 6.1 | met; measured against `@sd-jwt/sd-jwt-vc` in both directions |
| `typ` `dc+sd-jwt` | sd-jwt-vc-19 Section 2.2.1 | met (issued and required) |
| `vct` in the `urn:eudi:pid:` namespace, `urn:eudi:pid:1` for the PID | PID Rulebook PID_14, Section 4.2; ARF ARB_05 | met as a mechanism: the issuer sets `vct`, the verifier names the one it expects; the value is the issuer's |
| the mandatory PID attributes (`family_name`, `given_name`, `birthdate`, `place_of_birth`, `nationalities`; the portrait later) and metadata (`issuing_authority`, `issuing_country`) | PID Rulebook Sections 2.2, 2.4 | not met: claims pass through as data, no PID schema is checked |
| claim names from the IANA JWT registry, public or private names; UTF-8 | ARF ARB_06b; PID Rulebook Section 4.1.1 | not judged (JSON is UTF-8; names are not checked against the registry) |
| every claim selectively disclosable on its own | PID Rulebook PID_21; ARF ARB_30 | met for top-level claims and list elements; not for the properties of nested objects at issuance (the verifier reads nested disclosures, the issuer does not make them) |
| key binding (`cnf.jwk`), a KB-JWT always present when the credential is bound | ARF OIA_02; HAIP 6.1.1.1; sd-jwt-vc-19 Section 2.2.2.3 | met (key binding required by default; `cnf` never disclosable) |
| revocation by Token Status List (`status.status_list`) | ARF VCR_01b, VCR_11a; HAIP 6.1; status-list-21 | met offline: the verifier hands in the list it fetched; measured against `@owf/token-status-list`; an unjudged status refuses by default |
| a Relying Party also supports Attestation Revocation Lists | ARF VCR_12 | not met (nothing implemented; VCR_11a notes there is no JSON specification) |
| validity by `nbf` and `exp` | PID Rulebook Section 4; HAIP 6.1 | met (`exp` required by default) |
| algorithms only from the ECCG Agreed Cryptographic Mechanisms v2.0; ES256 at least | ARF OIA_03; HAIP 7 | ES256 met; EdDSA and ML-DSA-65 are offered too, and their standing in ACM v2.0 was not read: not measured |
| hash `sha-256` | HAIP 8; RFC 9901 Section 4.1.1 | met (the only one understood) |
| issuer key from `x5c` (a trust chain, never self-signed) or from JWT VC Issuer Metadata | HAIP 6.1.1; sd-jwt-vc-19 Section 2.5 | not met: the key is the verifier's input |
| type metadata for `vct`, published in a catalog; `vct#integrity` | PID Rulebook PID_15; sd-jwt-vc-19 Section 5 | not met: carried, not resolved |
| presentation over OpenID4VP | ARF ARB_02 note | outside: this is a credential format, not a protocol |
| mdoc (ISO/IEC 18013-5) for proximity; wallets support both formats | ARF ARB_02, ISSU_02 | outside, not today: it would need CBOR (RFC 8949) and COSE (RFC 9052) encoding, the mobile security object, device authentication and the session encryption of ISO/IEC 18013-5 |
## Named rules
@ -194,8 +295,16 @@ not stop at its first refusal: it makes every check it can reach. `valid` is unc
no row failed, also when rows were not judged; a caller that needs "nothing left unjudged" reads `unjudged`.
With these ids the presentation verifier is enrolled in the conformance suite beside this folder (`conformance/`: 37 rules,
65 vectors of the artifact kind `identity-presentation`, each rule taken out of a copy of the verifier in turn). SD-JWT, Travel Rule
and compliance are not enrolled there.
65 vectors of the artifact kind `identity-presentation`, each rule taken out of a copy of the verifier in turn). Since 2026-10-18 the
SD-JWT verifier and the SD-JWT VC profile are enrolled there too: `verifySdJwt` names the rule of its refusal (`rule`, one of the 23 of
`REGULI` in `sdjwt.mjs`: `form`, `alg`, `typ`, `crit`, `key`, `signature`, `issuer`, `sd-alg`, `disclosure-form`, `disclosure-twice`,
`digest-twice`, `disclosure-name`, `claim-conflict`, `unreferenced`, `time`, `kb-context`, `kb-required`, `kb-cnf`, `kb-claims`,
`kb-audience`, `kb-nonce`, `kb-freshness`, `kb-sd-hash`), and `verifySdJwtVc` one of those or one of its own 9 (`vct-expected`, `vct`,
`vct-mismatch`, `disclosed-protected`, `form`, `status-list`, `status-index`, `status-revoked`, `status-unjudged`); both stop at their
first refusal. The suite holds 54 vectors of the kind `sdjwt-presentation` (the RFC 9901 example, the tokens of `@sd-jwt/core` from the
interop fixtures, and tokens issued with AERE keys) and 32 of `sdjwt-vc-presentation` (ours with their status lists, and the credentials
and lists of `@sd-jwt/sd-jwt-vc` and `@owf/token-status-list`); a VC whose status was waived and not judged is `PARTIAL` there, never
`VALID`. Travel Rule and compliance are not enrolled.
Two things changed in behaviour that day, both measured by `proba-identity.mjs`, each with its planting in the negative control:
@ -222,8 +331,12 @@ node proba-conformitate.mjs # 15: compliance policies judged on real pr
node control-negativ-conformitate.mjs # on a copy, each of 14 guards removed -> its own named test turns red
node proba-travel-rule.mjs # 19: two VASPs with registry credentials, the whole exchange, and each attack of the review
node control-negativ-travel-rule.mjs # on a copy, each of 19 guards removed -> its own named test turns red
node proba-sdjwt.mjs # 23: the RFC 9901 vectors, SD-JWTs issued with AERE keys (EdDSA and ML-DSA-65), each attack
node control-negativ-sdjwt.mjs # on a copy, each of 29 guards removed -> its own named test turns red
node proba-sdjwt.mjs # 25: the RFC 9901 vectors, SD-JWTs issued with AERE keys (EdDSA and ML-DSA-65), each attack, the fixtures of @sd-jwt/core
node control-negativ-sdjwt.mjs # on a copy, each of 31 guards removed -> its own named test turns red
node proba-sdjwt-vc.mjs # 10: the SD-JWT VC profile, the status list, the fixtures of @sd-jwt/sd-jwt-vc and @owf/token-status-list, the command line
node control-negativ-sdjwt-vc.mjs # on a copy, each of 16 guards removed -> its own named test turns red
node interop/interop-sdjwt.mjs --lab <folder> # the measurement itself, with the foreign libraries installed in <folder>, outside this repository
node interop/interop-sdjwt-vc.mjs --lab <folder> # (npm: @sd-jwt/core, @sd-jwt/sd-jwt-vc, @sd-jwt/crypto-nodejs, jose); --scrie rewrites the fixtures
```
The envelope test needs the AIP-23 reference verifier (`AERE_VERIFY_PROOF=<verify-proof.mjs>`); without it that test is reported as

View File

@ -0,0 +1,67 @@
// Controlul negativ al probei SD-JWT VC (sdjwt-vc.mjs, proba-sdjwt-vc.mjs): fiecare paznic se strica intr-o COPIE, proba ruleaza pe copie si
// proba NUMITA trebuie sa iasa rosie, cu proba chiar rulata; pe copia neatinsa, verde. Trei stari: un tipar care nu apare exact o data sau o
// proba care nu ajunge la rezumat e STRICAT si se numara esec. Plantarile sunt ancorate pe randuri STABILE si UNICE ale paznicului.
// node control-negativ-sdjwt-vc.mjs iesire 0 = martorul verde si toate plantarile rosii pe proba lor
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { spawn } from 'node:child_process';
import { fileURLToPath } from 'node:url';
const AICI = path.dirname(fileURLToPath(import.meta.url));
const S = 'sdjwt-vc.mjs';
const PLANTARI = [
// [nume, tipar, inlocuire, proba (inceputul numelui ei)]
['vct-ul asteptat nu se mai cere verificatorului', "if (!(Array.isArray(vcts) && vcts.length > 0 && vcts.every((v) => typeof v === 'string' && !!v) /*PAZA:vct-expected*/)) return refuz(", 'if (false) return refuz(', 'PROFIL vct'],
['vct lipsa din jeton primit', "if (!(typeof p.vct === 'string' && !!p.vct /*PAZA:vct*/)) return refuz('vct'", "if (false) return refuz('vct'", 'PROFIL vct'],
['alt vct decat cel asteptat primit', 'if (!(tipuri.includes(p.vct) /*PAZA:vct-mismatch*/)) return refuz(', 'if (false) return refuz(', 'PROFIL vct'],
['typ-ul dc+sd-jwt nu se mai cere (orice ...+sd-jwt)', 'requireStatus = true, expectedTyp = TYP_VC, ...o } = {}) {', 'requireStatus = true, expectedTyp = undefined, ...o } = {}) {', 'PROFIL typ'],
['o afirmatie din s.2.2.2.3 dezvaluita selectiv primita', 'if (!(dez.length === 0 /*PAZA:disclosed-protected*/)) return refuz(', 'if (false) return refuz(', 'PROFIL s.2.2.2.3'],
['emitentul face dezvaluibile afirmatiile din s.2.2.2.3', 'for (const n of [...disclosable, ...arrayDisclosable]) if (NEDEZVALUIBILE.includes(n)) throw', 'for (const n of [...disclosable, ...arrayDisclosable]) if (false) throw', 'PROFIL s.2.2.2.3'],
['emitentul nu mai cere vct', "if (typeof vct !== 'string' || !vct) throw new Error('sd-jwt-vc: vct is required", "if (false) throw new Error('sd-jwt-vc: vct is required", 'PROFIL s.2.2.2.3'],
['starea nejudecata trece implicit drept nerevocata', 'if (!(status.judged || !requireStatus /*PAZA:status-unjudged*/)) return refuz(', 'if (false) return refuz(', 'STARE: lista lipsa'],
['starea revocata/suspendata primita', 'if (!(v === 0 /*PAZA:status-revoked*/)) return refuz(', 'if (false) return refuz(', 'STARE: revocat'],
['impachetarea bitilor citita de la bitul cel mai semnificativ (ordinea gresita)', '(octeti[Math.floor(idx * bits / 8)] >> ((idx * bits) % 8)) & ((1 << bits) - 1)', '(octeti[Math.floor(idx * bits / 8)] >> (8 - bits - ((idx * bits) % 8))) & ((1 << bits) - 1)', 'STARE: revocat'],
['sub-ul listei nu se mai compara cu uri-ul din jeton', 'if (!(corp.sub === uri /*PAZA:status-list*/)) return nu(', 'if (false) return nu(', 'STARE: lista pentru alt uri'],
['lista expirata primita', 'if (!(corp.exp === undefined || (Number.isFinite(corp.exp) && acum < corp.exp) /*PAZA:status-list*/)) return nu(', 'if (false) return nu(', 'STARE: lista pentru alt uri'],
['typ-ul statuslist+jwt al listei nu se mai cere', "verifyJws(jwt, publicJwk(key, alg), { typ: TYP_STATUS_LIST })", "verifyJws(jwt, publicJwk(key, alg), { typ: null })", 'STARE: lista pentru alt uri'],
['iat-ul listei nu se mai cere', "if (!(Number.isFinite(corp.iat) /*PAZA:status-list*/)) return nu('iat is required", "if (false) return nu('iat is required", 'STARE: lista pentru alt uri'],
['indexul dincolo de lista citit ca 0', 'if (!(v !== null /*PAZA:status-index*/)) return refuz(', 'if (false) return refuz(', 'STARE: lista pentru alt uri'],
// fixturile straine: cu impachetarea gresita, listele @owf/token-status-list pe 1 bit cu indexul 5 = 1 ar fi citite altfel
['fixturile straine: lista LOR revocata citita cu ordinea gresita a bitilor', 'const statusAt = (idx) => (Number.isInteger(idx) && idx >= 0 && idx < entries ?', 'const statusAt = (idx) => (false && Number.isInteger(idx) && idx >= 0 && idx < entries ?', 'INTEROP'],
];
function copie() {
const t = fs.mkdtempSync(path.join(os.tmpdir(), 'aere-sdjwt-vc-ctl-'));
for (const f of [S, 'sdjwt.mjs', 'identity.mjs', 'identity-cli.mjs', 'proba-sdjwt-vc.mjs']) fs.copyFileSync(path.join(AICI, f), path.join(t, f));
fs.mkdirSync(path.join(t, 'interop'));
fs.copyFileSync(path.join(AICI, 'interop', 'fixturi-interop-sdjwt-vc.json'), path.join(t, 'interop', 'fixturi-interop-sdjwt-vc.json'));
return t;
}
function ruleaza(t) {
return new Promise((resolve) => {
const c = spawn(process.execPath, [path.join(t, 'proba-sdjwt-vc.mjs')]); let out = '';
const ceas = setTimeout(() => c.kill(), 180000);
c.stdout.on('data', (x) => { out += x; }); c.stderr.on('data', (x) => { out += x; });
c.on('close', (cod) => { clearTimeout(ceas); resolve({ cod, rulat: /aere-sd-jwt-vc: \d+\/\d+/.test(out), rosii: out.split('\n').filter((l) => l.startsWith(' RAU ')) }); });
});
}
async function planteaza([nume, din, inl, tinta]) {
const t = copie();
try {
const f = path.join(t, S); const src = fs.readFileSync(f, 'utf8');
if (src.split(din).length !== 2) return [false, ` STRICAT ${nume}: tiparul apare de ${src.split(din).length - 1} ori`];
fs.writeFileSync(f, src.replace(din, inl));
const r = await ruleaza(t);
if (!r.rulat) return [false, ` STRICAT ${nume}: proba nu a ajuns la rezumat (cod ${r.cod})`];
if (r.rosii.some((l) => l.startsWith(' RAU ' + tinta))) return [true, ` ROSU cum trebuia ${nume} (proba '${tinta}' pica)`];
return [false, ` CONTROL CAZUT ${nume}: proba '${tinta}' a ramas verde (${r.rosii.length} rosii altundeva)`];
} finally { fs.rmSync(t, { recursive: true, force: true }); }
}
let rele = 0;
const t0 = copie(); const m = await ruleaza(t0); fs.rmSync(t0, { recursive: true, force: true });
if (m.rulat && m.cod === 0 && !m.rosii.length) console.log(' OK martorul: copia neatinsa verde'); else { rele++; console.log(` STRICAT martorul nu e verde (cod ${m.cod}, ${m.rosii.length} rosii)`); }
const rez = new Array(PLANTARI.length); let i = 0;
await Promise.all(Array.from({ length: 4 }, async () => { while (i < PLANTARI.length) { const k = i++; rez[k] = await planteaza(PLANTARI[k]); } }));
for (const [bun, linie] of rez) { console.log(linie); if (!bun) rele++; }
console.log(rele ? `CONTROL NEGATIV: ${rele} probleme` : `DOVEDIT: martorul verde, ${PLANTARI.length} din ${PLANTARI.length} paznici scosi -> proba lor rosie`);
process.exitCode = rele ? 1 : 0;

View File

@ -1,6 +1,8 @@
// Controlul negativ al probei SD-JWT (sdjwt.mjs, proba-sdjwt.mjs): fiecare paznic se strica intr-o COPIE, proba ruleaza pe copie si proba
// NUMITA trebuie sa iasa rosie, cu proba chiar rulata; pe copia neatinsa, verde. Trei stari: un tipar care nu apare exact o data sau o
// proba care nu ajunge la rezumat e STRICAT si se numara esec.
// 2026-10-18: paznicii poarta marcajele /*PAZA:<regula>*/ ale suitei de conformitate pe conditia lor BUNA (`if (!(bun /*PAZA:x*/)) refuz`);
// plantarile de aici fac conditia falsa pe alt drum (`if (false)`), ca sa fie independente de plantarea suitei (care o face adevarata).
// node control-negativ-sdjwt.mjs iesire 0 = martorul verde si toate plantarile rosii pe proba lor
import fs from 'node:fs';
import os from 'node:os';
@ -12,41 +14,46 @@ const AICI = path.dirname(fileURLToPath(import.meta.url));
const S = 'sdjwt.mjs';
const PLANTARI = [
// [nume, tipar, inlocuire, proba (inceputul numelui ei)]
['alg none primit', 'if (!ALGS.includes(antet.alg)) throw', "if (antet.alg === 'nimic') throw", 'ATAC: alg none'],
['algoritmul nu mai trebuie sa fie al cheii (confuzia)', 'if (!potriveste(antet.alg, key)) throw', 'if (false) throw', 'ATAC: alg none'],
['o dezvaluire nelegata de niciun digest primita', 'if (folosite.size !== dupaDigest.size) return', 'if (false) return', 'ATAC: o dezvaluire cu valoarea schimbata'],
['aceeasi dezvaluire de doua ori primita', "if (dupaDigest.has(dg)) return refuz('the same disclosure is given twice');", '', 'ATAC: o dezvaluire cu valoarea schimbata'],
['numele _sd, ... sau __proto__ primite', "if (c[1] === '_sd' || c[1] === '...' || c[1] === '__proto__') throw", 'if (false) throw', 'ATAC: un emitent care pune in _sd'],
['o afirmatie dezvaluita peste una in clar primita', 'if (Object.hasOwn(out, c[1])) throw', 'if (false) throw', 'ATAC: un emitent care pune in _sd'],
['acelasi digest de doua ori primit', 'const vezi = (dg) => { if (vazute.has(dg)) throw', 'const vezi = (dg) => { if (false) throw', 'ATAC: un emitent care pune in _sd'],
['sd_hash nu se mai compara', 'if (sha256b64u(baza) !== K.sd_hash) return', 'if (false) return', 'RFC 9901: o dezvaluire scoasa'],
['alg none primit', "if (!(ALGS.includes(antet.alg) /*PAZA:alg*/)) throw", "if (antet.alg === 'nimic') throw", 'ATAC: alg none'],
['algoritmul nu mai trebuie sa fie al cheii (confuzia)', 'if (!(potriveste(antet.alg, key) /*PAZA:key*/)) throw', 'if (false) throw', 'ATAC: alg none'],
['o dezvaluire nelegata de niciun digest primita', 'if (!(folosite.size === dupaDigest.size /*PAZA:unreferenced*/)) return', 'if (false) return', 'ATAC: o dezvaluire cu valoarea schimbata'],
['aceeasi dezvaluire de doua ori primita', "if (!(!dupaDigest.has(dg) /*PAZA:disclosure-twice*/)) return refuz('disclosure-twice', 'the same disclosure is given twice');", '', 'ATAC: o dezvaluire cu valoarea schimbata'],
['numele _sd, ..., _sd_alg sau __proto__ primite', "if (!(c[1] !== '_sd' && c[1] !== '...' && c[1] !== '_sd_alg' && c[1] !== '__proto__' /*PAZA:disclosure-name*/)) throw", 'if (false) throw', 'ATAC: un emitent care pune in _sd'],
['o afirmatie dezvaluita peste una in clar primita', 'if (!(!Object.hasOwn(out, c[1]) /*PAZA:claim-conflict*/)) throw', 'if (false) throw', 'ATAC: un emitent care pune in _sd'],
['acelasi digest de doua ori primit', 'const vezi = (dg) => { if (!(!vazute.has(dg) /*PAZA:digest-twice*/)) throw', 'const vezi = (dg) => { if (false) throw', 'ATAC: un emitent care pune in _sd'],
['sd_hash nu se mai compara', 'if (!(sha256b64u(baza) === K.sd_hash /*PAZA:kb-sd-hash*/)) return', 'if (false) return', 'RFC 9901: o dezvaluire scoasa'],
['tipul KB (kb+jwt) nu se mai cere', "k = verificaJws(kb, payload.cnf.jwk, { typ: 'kb+jwt' });", 'k = verificaJws(kb, payload.cnf.jwk, { typ: null });', 'ATAC: KB semnat de alta cheie'],
['publicul KB nu se mai compara', 'if (K.aud !== audience) return', 'if (false) return', 'RFC 9901: aceeasi prezentare pentru ALT verificator'],
['nonce-ul KB nu se mai compara', 'if (K.nonce !== nonce) return', 'if (false) return', 'RFC 9901: aceeasi prezentare pentru ALT verificator'],
['KB vechi primit', 'if (Math.abs(acum - K.iat) > maxAgeS) return', 'if (false) return', 'RFC 9901: aceeasi prezentare pentru ALT verificator'],
['exp nu se mai cere', 'if (payload.exp !== undefined && acum >= payload.exp) return', 'if (false) return', 'timpul'],
['fara toleranta de ceas pe nbf', 'if (payload.nbf !== undefined && payload.nbf - clockSkewS > acum) return', 'if (payload.nbf !== undefined && payload.nbf > acum) return', 'timpul'],
['Key Binding cerut, dar lipsa primita', "if (requireKeyBinding) return refuz('key binding is required", "if (false) return refuz('key binding is required", 'RFC 9901: SD-JWT-ul standardului cu ALTA cheie'],
['publicul KB nu se mai compara', 'if (!(K.aud === audience /*PAZA:kb-audience*/)) return', 'if (false) return', 'RFC 9901: aceeasi prezentare pentru ALT verificator'],
['nonce-ul KB nu se mai compara', 'if (!(K.nonce === nonce /*PAZA:kb-nonce*/)) return', 'if (false) return', 'RFC 9901: aceeasi prezentare pentru ALT verificator'],
['KB vechi primit', 'if (!(Math.abs(acum - K.iat) <= maxAgeS /*PAZA:kb-freshness*/)) return', 'if (false) return', 'RFC 9901: aceeasi prezentare pentru ALT verificator'],
['exp nu se mai cere', 'if (!(payload.exp === undefined || acum < payload.exp /*PAZA:time*/)) return', 'if (false) return', 'timpul'],
['fara toleranta de ceas pe nbf', 'if (!(payload.nbf === undefined || payload.nbf - clockSkewS <= acum /*PAZA:time*/)) return', 'if (!(payload.nbf === undefined || payload.nbf <= acum /*PAZA:time*/)) return', 'timpul'],
['Key Binding cerut, dar lipsa primita', "if (!(!requireKeyBinding /*PAZA:kb-required*/)) return refuz('kb-required'", "if (false) return refuz('kb-required'", 'RFC 9901: SD-JWT-ul standardului cu ALTA cheie'],
// revizuirea adversariala din 30 sept: forma de dinainte a fiecarei reparatii
['emitentul semneaza structura SD-JWT din valori', 'if (areStructuraSd(claims)) throw', 'if (false) throw', 'REVIZUIRE: emitentul refuza structura'],
['prezentarea arata elementul din orice lista', 'obiect(r) && r.in === l.lista && c.length === 2', 'obiect(r) && c.length === 2', 'REVIZUIRE: prezentarea arata elementul'],
['publicul si nonce-ul nu se mai cer', "if ((requireKeyBinding || kb !== '') && (typeof audience !== 'string'", "if (false && (typeof audience !== 'string'", 'REVIZUIRE: fara publicul si nonce-ul'],
['exp nu se mai cere implicit', 'if (requireExp && payload.exp === undefined) return', 'if (false) return', 'REVIZUIRE: exp cerut implicit'],
['tipul jetonului nu se mai verifica implicit', "if (cerut === undefined) return typeof typ === 'string' && /(^|\\+)sd-jwt$/.test(typ);", 'if (cerut === undefined) return true;', 'REVIZUIRE: tipul jetonului'],
['expectedIssuer nu se mai compara', 'if (expectedIssuer != null && corp.iss !== expectedIssuer) return', 'if (false) return', 'REVIZUIRE: tipul jetonului'],
['crit primit', "if (Object.hasOwn(antet, 'crit')) throw", 'if (false) throw', 'REVIZUIRE: crit'],
['base64url necanonic primit', "if (b.toString('base64url') !== s) throw", 'if (false) throw', 'REVIZUIRE: crit'],
['exp-ul KB nu se mai cere', 'if (K.exp !== undefined && (!Number.isFinite(K.exp) || acum >= K.exp)) return', 'if (false) return', 'REVIZUIRE: crit'],
['publicul si nonce-ul nu se mai cer', "if (!(!(requireKeyBinding || kb !== '') || context /*PAZA:kb-context*/)) return", 'if (false) return', 'REVIZUIRE: fara publicul si nonce-ul'],
['exp nu se mai cere implicit', 'if (!(!requireExp || payload.exp !== undefined /*PAZA:time*/)) return', 'if (false) return', 'REVIZUIRE: exp cerut implicit'],
['tipul jetonului nu se mai verifica implicit', "if (cerut === undefined) return typeof t === 'string' && /(^|\\+)sd-jwt$/.test(t);", 'if (cerut === undefined) return true;', 'REVIZUIRE: tipul jetonului'],
['expectedIssuer nu se mai compara', 'if (!(expectedIssuer == null || corp.iss === expectedIssuer /*PAZA:issuer*/)) return', 'if (false) return', 'REVIZUIRE: tipul jetonului'],
['crit primit', "if (!(!Object.hasOwn(antet, 'crit') /*PAZA:crit*/)) throw", 'if (false) throw', 'REVIZUIRE: crit'],
['base64url necanonic primit', "if (!(b.toString('base64url') === s /*PAZA:form*/)) throw", 'if (false) throw', 'REVIZUIRE: crit'],
['exp-ul KB nu se mai cere', 'if (!(K.exp === undefined || (Number.isFinite(K.exp) && acum < K.exp) /*PAZA:kb-freshness*/)) return', 'if (false) return', 'REVIZUIRE: crit'],
// 2026-10-01: a doua jumatate a "exp/nbf ale KB"; fara plantarea ei, paznicul scos lasa proba verde (masurat: 23/23)
['nbf-ul KB nu se mai cere', 'if (K.nbf !== undefined && (!Number.isFinite(K.nbf) || K.nbf - clockSkewS > acum)) return', 'if (false) return', 'REVIZUIRE: crit'],
['_sd_alg scos de la orice nivel', "!(sus && k === '_sd_alg')", "k !== '_sd_alg'", 'REVIZUIRE: crit'],
['nbf-ul KB nu se mai cere', 'if (!(K.nbf === undefined || (Number.isFinite(K.nbf) && K.nbf - clockSkewS <= acum) /*PAZA:kb-freshness*/)) return', 'if (false) return', 'REVIZUIRE: crit'],
// 2026-10-18 (interoperarea cu @sd-jwt/core 0.23.0): _sd_alg imbricat era pastrat ca afirmatie; acum e refuzat (RFC 9901 s.4.1.1)
['_sd_alg imbricat primit (scos in tacere, ca pana pe 18 oct)', "if (k === '_sd_alg') { if (!(sus /*PAZA:sd-alg*/)) throw nu('sd-alg'", "if (k === '_sd_alg') { if (false) throw nu('sd-alg'", 'INTEROP: _sd_alg imbricat'],
['prefixul application/ al typ-ului nu se mai scoate (RFC 7515 s.4.1.9)', 'const t = faraPrefix(typ);', 'const t = typ;', 'INTEROP: _sd_alg imbricat'],
['emiterea nu mai cere un typ explicit de SD-JWT', "if (!tipBun(typ, undefined)) throw new Error('sd-jwt: typ must be", "if (false) throw new Error('sd-jwt: typ must be", 'INTEROP: _sd_alg imbricat'],
['cheia publica Node nu mai e primita', "(k.type === 'public' ? k : crypto.createPublicKey(k))", 'crypto.createPublicKey(k)', 'REVIZUIRE: cheia emitentului'],
['o afirmatie __proto__ primita (prototipul schimbat)', "if (Object.hasOwn(x, '__proto__')) throw", 'if (false) throw', 'ATAC: o afirmatie numita __proto__'],
['o afirmatie __proto__ primita (prototipul schimbat)', "if (!(!Object.hasOwn(x, '__proto__') /*PAZA:disclosure-name*/)) throw", 'if (false) throw', 'ATAC: o afirmatie numita __proto__'],
['elementele de lista nedezvaluite pastrate', 'if (!c) continue; // nedezvaluit: elementul se scoate', "if (!c) { out.push(e); continue; }", 'AERE -> SD-JWT (EdDSA'],
];
function copie() {
const t = fs.mkdtempSync(path.join(os.tmpdir(), 'aere-sdjwt-ctl-'));
for (const f of [S, 'identity.mjs', 'identity-cli.mjs', 'proba-sdjwt.mjs', 'fixturi-rfc9901.json']) fs.copyFileSync(path.join(AICI, f), path.join(t, f));
fs.mkdirSync(path.join(t, 'interop'));
fs.copyFileSync(path.join(AICI, 'interop', 'fixturi-interop-sdjwt.json'), path.join(t, 'interop', 'fixturi-interop-sdjwt.json'));
return t;
}
function ruleaza(t) {

View File

@ -18,6 +18,10 @@
// verify-sdjwt --sd-jwt f.txt --issuer-key k.json [--issuer-alg EdDSA|ML-DSA-65|ES256] --audience A --nonce N
// [--expected-issuer I] [--expected-typ T] [--max-age S] [--at T] [--json] an SD-JWT+KB (IETF RFC 9901), sdjwt.mjs;
// the issuer key is a public JWK or the public keys of an AERE identity (the output of pub)
// verify-sdjwt-vc --sd-jwt f.txt --issuer-key k.json [--issuer-alg A] --audience A --nonce N --expected-vct V [--expected-vct V2 ...]
// [--status-list f.txt [--status-list-key k.json] [--status-list-alg A]] [--status-not-required] [--expected-issuer I]
// [--max-age S] [--at T] [--json] an SD-JWT VC (draft-ietf-oauth-sd-jwt-vc), sdjwt-vc.mjs; the status list is the Token
// Status List JWT the verifier fetched from the uri the credential names (without it a credential with `status` is INVALID)
// Coduri de iesire: 0 VALID / COMPLIANT, 1 INVALID / NOT COMPLIANT, 2 intrare respinsa (motivul pe stderr, `error: ...`).
// O valoare de --claim se citeste ca JSON daca e JSON (true, 42, {"a":1}), altfel ca text.
import fs from 'node:fs';
@ -128,33 +132,52 @@ async function main() {
else console.log(r.compliant ? `COMPLIANT with ${r.policyId} (${r.policyHash})` : `NOT COMPLIANT with ${r.policyId}:\n ` + r.reasons.join('\n '));
return r.compliant ? 0 : 1;
}
if (cmd === 'verify-sdjwt') {
if (cmd === 'verify-sdjwt' || cmd === 'verify-sdjwt-vc') {
// 2026-09-30: SD-JWT (IETF RFC 9901) cu sdjwt.mjs; jetonul dintr-un fisier text (serializarea compacta, fara spatii)
// 2026-10-18: verify-sdjwt-vc, profilul SD-JWT VC (sdjwt-vc.mjs): --expected-vct cerut, --status-list <fisier cu Status List Token-ul
// adus de verificator> (altfel, cu `status` in jeton, INVALID: stare nejudecata; --status-not-required o lasa nejudecata si o spune)
const { verifySdJwt, publicJwk } = await import('./sdjwt.mjs');
const vc = cmd === 'verify-sdjwt-vc';
let jeton; try { jeton = fs.readFileSync(cere('--sd-jwt'), 'utf8').trim(); } catch (e) { throw new Folosire(`cannot read --sd-jwt: ${e.message}`); }
const cheie = citeste(cere('--issuer-key'));
const alg = get('--issuer-alg') ?? 'EdDSA';
if (!['EdDSA', 'Ed25519', 'ES256', 'ML-DSA-65'].includes(alg)) throw new Folosire('--issuer-alg is EdDSA, ES256 or ML-DSA-65');
// revizuirea din 30 sept: cheia emitentului e intrarea VERIFICATORULUI; una care nu se citeste, e privata sau nu e a algoritmului cerut e o
// greseala a lui (cod 2, cu motivul), nu un credential INVALID (cheile stricate ieseau INVALID cu mesajul Node)
const cheiePublicaBuna = (optiune, cheie, alg) => {
if (!['EdDSA', 'Ed25519', 'ES256', 'ML-DSA-65'].includes(alg)) throw new Folosire(`${optiune}-alg is EdDSA, ES256 or ML-DSA-65`);
try {
const jwk = publicJwk(cheie, alg);
if ('d' in jwk || 'priv' in jwk) throw new Error('a private JWK was given where a public key belongs');
const k = crypto.createPublicKey({ key: jwk, format: 'jwk' });
const cere2 = alg === 'ES256' ? k.asymmetricKeyType === 'ec' && k.asymmetricKeyDetails.namedCurve === 'prime256v1' : alg === 'ML-DSA-65' ? k.asymmetricKeyType === 'ml-dsa-65' : k.asymmetricKeyType === 'ed25519';
if (!cere2) throw new Error(`the key is a ${k.asymmetricKeyType} key, not one for ${alg}`);
} catch (e) { throw new Folosire('--issuer-key: ' + String(e.message || e).replace(/^sd-jwt: /, '').slice(0, 160)); }
const buna = alg === 'ES256' ? k.asymmetricKeyType === 'ec' && k.asymmetricKeyDetails.namedCurve === 'prime256v1' : alg === 'ML-DSA-65' ? k.asymmetricKeyType === 'ml-dsa-65' : k.asymmetricKeyType === 'ed25519';
if (!buna) throw new Error(`the key is a ${k.asymmetricKeyType} key, not one for ${alg}`);
} catch (e) { if (e instanceof Folosire) throw e; throw new Folosire(`${optiune}: ` + String(e.message || e).replace(/^sd-jwt: /, '').slice(0, 160)); }
};
const cheie = citeste(cere('--issuer-key'));
const alg = get('--issuer-alg') ?? 'EdDSA';
cheiePublicaBuna('--issuer-key', cheie, alg);
const maxAgeS = Number(get('--max-age') ?? 300);
if (!Number.isInteger(maxAgeS) || maxAgeS < 1 || maxAgeS > 3600) throw new Folosire('--max-age is a number of seconds, 1..3600');
const tip = get('--expected-typ');
const r = verifySdJwt(jeton, { issuerKey: cheie, issuerAlg: alg, audience: cere('--audience'), nonce: cere('--nonce'), expectedIssuer: get('--expected-issuer'),
maxAgeS, now: momentul(), ...(tip != null ? { expectedTyp: tip } : {}) });
const comune = { issuerKey: cheie, issuerAlg: alg, audience: cere('--audience'), nonce: cere('--nonce'), expectedIssuer: get('--expected-issuer'), maxAgeS, now: momentul(), ...(tip != null ? { expectedTyp: tip } : {}) };
let r;
if (!vc) r = verifySdJwt(jeton, comune);
else {
const { verifySdJwtVc } = await import('./sdjwt-vc.mjs');
const vcts = toate('--expected-vct'); if (!vcts.length) throw new Folosire('verify-sdjwt-vc needs --expected-vct <vct> (the credential type the verifier expects; may be repeated)');
let statusListJwt = null; if (get('--status-list')) { try { statusListJwt = fs.readFileSync(get('--status-list'), 'utf8').trim(); } catch (e) { throw new Folosire(`cannot read --status-list: ${e.message}`); } }
const statusListKey = get('--status-list-key') ? citeste(get('--status-list-key')) : null, statusListAlg = get('--status-list-alg') ?? alg;
if (statusListKey) cheiePublicaBuna('--status-list-key', statusListKey, statusListAlg);
r = verifySdJwtVc(jeton, { ...comune, expectedVct: vcts, statusListJwt, statusListKey, statusListAlg, requireStatus: !are('--status-not-required') });
}
// JSON compact: cu indentare, iesirea creste cu patratul adancimii afirmatiilor (un jeton de 7 KB imbricat de 2.500 de ori dadea 6 MB)
if (are('--json')) console.log(JSON.stringify(r));
else console.log(r.valid ? `VALID: issued by ${r.issuer}${r.issuerChecked ? '' : ' (not checked against an expected issuer)'}; disclosed: ${r.disclosed.join(', ') || 'nothing'}` : 'INVALID: ' + r.reason);
else if (!r.valid) console.log('INVALID: ' + r.reason);
else {
const stare = !vc ? '' : '; status ' + (r.status.judged ? `${r.status.value} (${r.status.name}) in ${r.status.uri} at ${r.status.idx}` : r.status.present ? `not judged (${r.status.uri ?? r.status.mechanism})` : 'none');
console.log(`VALID: issued by ${r.issuer}${r.issuerChecked ? '' : ' (not checked against an expected issuer)'}${vc ? `; vct ${r.vct}` : ''}; disclosed: ${r.disclosed.join(', ') || 'nothing'}${stare}`);
}
return r.valid ? 0 : 1;
}
throw new Folosire('usage: identity-cli.mjs keygen|pub|id|issue|status-list|delegate|revoke|present|verify|comply|verify-sdjwt ... (see README.md)');
throw new Folosire('usage: identity-cli.mjs keygen|pub|id|issue|status-list|delegate|revoke|present|verify|comply|verify-sdjwt|verify-sdjwt-vc ... (see README.md)');
}
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
main().then((c) => { process.exitCode = c; }, (e) => { console.error('error: ' + (e.message || e)); process.exitCode = e instanceof Folosire ? 2 : 1; });

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More