Verification Test Vectors & Invariants
7. Verification Test Vectors & Regression Mapping
Section titled “7. Verification Test Vectors & Regression Mapping”7.1 Formal Standards Test Vectors
Section titled “7.1 Formal Standards Test Vectors”7.1.1 W3C Data Integrity EdDSA Cryptosuites v1.0 (Appendix B.3)
Section titled “7.1.1 W3C Data Integrity EdDSA Cryptosuites v1.0 (Appendix B.3)”Executed byte-for-byte in crates/resolver-core/src/data_integrity.rs:L257-L296 via unit test w3c_eddsa_jcs_2022_test_vector_verifies:
- Credential ID:
urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33 - Issuer:
https://vc.example/issuers/5678 - Verification Method:
did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2#z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2 - Proof Value:
z2HnFSSPPBzR36zdDgK8PbEHeXbR56YF24jwMpt3R1eHXQzJDMWS93FCzpvJpwTWd3GAVFuUfjoJdcnTMuVor51aX - Calculated Combined Hash Digest:
- Starts with:
66ab154f5c2890a140cb8388a22a1604 - Ends with:
59b7cb6251b8991add1ce0bc83107e3db9dbbab5bd2c28f687db1a03abc92f19
- Starts with:
- Tamper Resistance Check: Modifying
alumniOfto"Another School"returnsDiError::Invalid(_). - Result: Cryptographically verified (
PASS).
7.1.2 RFC 8785 Appendix B Floating Point Canonicalization
Section titled “7.1.2 RFC 8785 Appendix B Floating Point Canonicalization”Tested in crates/resolver-core/tests/jcs_interoperability.rs:L7-L43 via test rfc8785_appendix_b_numbers:
- Bit pattern
0x0000000000000000($+0.0$) $\to$"0" - Bit pattern
0x8000000000000000($-0.0$) $\to$"0" - Bit pattern
0x0000000000000001($5 \times 10^{-324}$) $\to$"5e-324" - Bit pattern
0x8000000000000001($-5 \times 10^{-324}$) $\to$"-5e-324" - Bit pattern
0x7fefffffffffffff($1.7976931348623157 \times 10^{308}$) $\to$"1.7976931348623157e+308" - Bit pattern
0x4340000000000000($2^{53}$) $\to$"9007199254740992" - Bit pattern
0x44b52d02c7e14af6$\to$"1e+23" - Bit pattern
0x3eb0c6f7a0b5ed8d$\to$"0.000001" - Large integer rounding:
9007199254740993$\to$"9007199254740992".
7.1.3 ECMAScript Canonical Interoperability Fixtures
Section titled “7.1.3 ECMAScript Canonical Interoperability Fixtures”Tested in crates/resolver-core/tests/jcs_interoperability.rs:L45-L87 using fixtures/ecmascript-jcs.json:
independently_signed_numeric_agent_card_verifies: Validates detached JWS signature generated in ECMAScript against Rust JCS implementation. Tamperingextensions.largeflips status fromVALIDtoINVALID.independently_signed_ecmascript_credential_verifies: Validates W3C Data Integrity EdDSA credential generated by external Node.js engine, confirming byte-for-byte digest and signature parity.
7.2 Internal Integration & Regression Test Mapping
Section titled “7.2 Internal Integration & Regression Test Mapping”The following registry maps every normative requirement and cryptographic security invariant directly to live regression test suites in crates/resolver-core/tests/:
| Verification Requirement | Test Suite File | Test Function / Scenario | Line Range |
|---|---|---|---|
| W3C Data Integrity EdDSA B.3 | data_integrity.rs |
w3c_eddsa_jcs_2022_test_vector_verifies |
L257–L296 |
| RDFC Suites Rejection | data_integrity.rs |
rdfc_suites_are_unsupported_not_invalid |
L298–L305 |
| RFC 8785 Floating Point | jcs_interoperability.rs |
rfc8785_appendix_b_numbers |
L7–L43 |
| ECMAScript Numeric JCS Parity | jcs_interoperability.rs |
independently_signed_numeric_agent_card_verifies |
L45–L73 |
| ECMAScript Credential Parity | jcs_interoperability.rs |
independently_signed_ecmascript_credential_verifies |
L75–L87 |
| Adversarial SSRF CIDR Denylist | adversarial_ssrf.rs |
blocks_every_non_public_range (26 IP subnets) |
L15–L52 |
| SSRF Public Address Allowance | adversarial_ssrf.rs |
allows_public_addresses (1.1.1.1, 8.8.8.8, 2606:...) |
L54–L63 |
| SSRF DNS Pre-Resolution Pinning | adversarial_ssrf.rs |
hostnames_resolving_to_loopback_are_blocked |
L65–L68 |
| did:web IP Literal Rejection | adversarial_ssrf.rs |
did_web_rejects_ip_literals_and_confusable_notations |
L70–L97 |
| Plain HTTP & Userinfo Rejection | adversarial_ssrf.rs |
plain_http_and_userinfo_are_refused_in_production |
L99–L110 |
| Egress Streaming Body Caps | adversarial_ssrf.rs |
streaming_cap_aborts_oversized_bodies |
L111–L130 |
| Redirect Re-Validation & Bounding | adversarial_ssrf.rs |
redirects_are_revalidated_and_bounded |
L131–L160 |
| JSON Duplicate Key Rejection | json_ambiguity_regressions.rs |
jose_duplicate_members_are_not_last_wins |
L32–L53 |
| Credential Duplicate Field Guard | json_ambiguity_regressions.rs |
raw_credential_strings_reject_duplicated_issuer |
L55–L75 |
| Unicode Escape Key Collision | json_ambiguity_regressions.rs |
escaped_unicode_duplicate_keys_are_rejected |
L77–L100 |
| did:key Method Derivation | did_methods.rs |
Key codecs, P-256, secp256k1, Ed25519 multikeys | L10–L60 |
| X25519 KeyAgreement Isolation | did_methods.rs |
Prohibits X25519 from authentication/assertion | L62–L85 |
| did:jwk Private Key Rejection | did_methods.rs |
Rejection of d, p, q, dp, dq, qi members |
L87–L120 |
| did:webvh SCID & Log Invariants | webvh.rs |
SCID derivation, entry-hash chain, witness policies | L10–L150 |
| JWT Profile Separation (18 cases) | jwt_profile_regressions.rs |
profiles_and_registered_identifiers_are_not_interchangeable |
L11–L112 |
| Status List Fail-Closed (25 cases) | status_validation_regressions.rs |
invalid_signed_status_lists_fail_closed |
L11–L135 |
| MCP Stateless 2026-07-28 Flow | mcp.rs |
modern_stateless_flow_with_pagination_and_sse |
L58–L100 |
| MCP Legacy 2025-11-25 Fallback | mcp.rs |
Handshake initialization, session ID, DELETE teardown | L102–L140 |
| MCP Fingerprint & Side Effects | mcp.rs |
Tool hash, schema drift, heuristic risk classification | L142–L180 |
| A2A Protocol & Signatures | a2a.rs |
Discovery, interface check, detached JWS verification | L10–L90 |
| Delegation Chain Verification | delegation.rs |
valid_chain_verifies_and_authorises_only_granted_tools |
L58–L100 |
| Delegation Store Restart Genesis | delegation.rs |
file_store_restores_registrations_after_restart_by_reverifying |
L149–L205 |
| Delegation Tamper Purge | delegation.rs |
file_store_drops_tampered_or_expired_rows_at_restore |
L206–L239 |
| Delegation Untrusted Root Reject | delegation.rs |
untrusted_root_is_rejected |
L256–L266 |
| Delegation Forged Signature | delegation.rs |
forged_signature_fails |
L267–L284 |
| Delegation Privilege Escalation | delegation.rs |
privilege_escalation_is_rejected |
L285–L302 |
| Delegation Linkage, Window & DAG | delegation.rs |
broken_linkage_window_and_cycles_are_rejected |
L303–L342 |
| DIF Domain Linkage Verification | domain_linkage.rs |
data_integrity_linkage_verifies |
L37–L60 |
| Legacy StatusList2021 Backward | legacy_status_interoperability.rs |
Gzip base64 legacy StatusList2021 compatibility | L10–L45 |
7.3 Cryptographic Invariants & Security Assertion Registry
Section titled “7.3 Cryptographic Invariants & Security Assertion Registry”| Invariant Class | Mathematical / Algorithmic Bound | Failure Semantic | Source Enforcement |
|---|---|---|---|
| did:jwk Encoded Length | String length $\le 4,096$ characters | ResolverError::InvalidDid |
methods/jwk.rs |
| did:jwk Private Material | Member $\notin {\text{“d”}, \text{“p”}, \text{“q”}, \text{“dp”}, \text{“dq”}, \text{“qi”}, \text{“oth”}, \text{“k”}}$ | ResolverError::InvalidDid (Fail-Closed) |
methods/jwk.rs |
| did:web ID Match | $\text{doc.id} \equiv \text{requested_did}$ | ResolverError::InvalidDidDocument |
methods/web.rs |
| did:webvh Log Depth | Entries count $\le 2,000$ | ResolverError::InvalidDidDocument |
methods/webvh.rs |
| did:webvh Stream Cap | Total log bytes $\le 4\text{ MiB}$ ($4,194,304\text{ bytes}$) | ResolverError::PayloadTooLarge |
methods/webvh.rs |
| did:webvh Witness Cap | Witness payload $\le 1\text{ MiB}$ ($1,048,576\text{ bytes}$) | ResolverError::PayloadTooLarge |
methods/webvh.rs |
| JSON Key Uniqueness | Zero duplicate keys across all object scopes | Serde MapAccess Terminate (Fail-Closed) | strict_json.rs |
| Ed25519 Canonical Sig | RFC 8032 strict verification (verify_strict) |
CryptoError::InvalidSignature |
crypto.rs |
| ECDSA P-256 S-Value | Lower-$s$ normalized ($s \le \frac{n-1}{2}$) | Auto-normalized via normalize_s() |
crypto.rs |
| X25519 Usage Scope | Verification relationship $\equiv \text{“keyAgreement”}$ only | CryptoError::Malformed |
crypto.rs |
| JWS Critical Headers | crit array MUST be empty or absent |
CryptoError::Unsupported |
jws.rs |
| JWS Unsecured Token | alg: "none" strictly rejected |
CryptoError::Malformed |
jws.rs |
| Status List Wire Size | HTTP body $\le 1\text{ MiB}$ ($1,048,576\text{ bytes}$) | ResolverError::PayloadTooLarge |
vc.rs |
| Status List Decomp. Cap | GZIP decompressed stream $\le 16\text{ MiB}$ ($16,777,216\text{ bytes}$) | Abort Decompression Bomb (Fail-Closed) | vc.rs |
| Status List Min Size | Decompressed bits $\ge 131,072\text{ bits}$ ($16\text{ KiB}$) | Evaluation yields INDETERMINATE |
vc.rs |
| Status List Issuer | $\text{status_vc.issuer} \equiv \text{credential.issuer}$ | Evaluation yields INDETERMINATE |
vc.rs |
| Delegation Chain Depth | Chain receipts count $1 \le N \le 8$ | status: "MALFORMED", depth: "FAIL" |
delegation.rs |
| Delegation PRF Linkage | Subordinate $\text{prf}i \equiv \text{hex}(\text{SHA-256}(\text{JWS}{i-1}))$ | status: "INVALID", linkage: "FAIL" |
delegation.rs |
| Delegation Root PRF | Root receipt ($i=0$) $\text{prf} \equiv \emptyset$ | status: "INVALID", linkage: "FAIL" |
delegation.rs |
| Delegation Attenuation | Monotonic capability containment ($\text{cap}i \subseteq \text{cap}{i-1}$) | status: "INVALID", attenuation: "FAIL" |
delegation.rs |
| Delegation DAG Graph | Acyclic path; zero principal repeats; $\text{iss} \ne \text{aud}$ | status: "INVALID", cycle: "FAIL" |
delegation.rs |
| Delegation Window | $[\text{nbf}i, \text{exp}i] \subseteq [\text{nbf}{i-1}, \text{exp}{i-1}]$ | status: "INVALID", time: "FAIL" |
delegation.rs |
| Egress SSRF Protection | Blocked across 26 non-public IPv4 & IPv6 CIDRs | ResolverError::SsrfDetected |
safe_client.rs |
| Egress DNS Pinning | Hostname resolved, vetted, and pinned to socket | Prevents TOCTOU DNS Rebinding | safe_client.rs |
| Egress Redirect Bound | Maximum redirects $\le 2$; downgrade to HTTP rejected | ResolverError::SsrfDetected |
safe_client.rs |
| Static Context Catalog | 22 compiled @context URIs; 0 runtime dereferencing |
Runtime context fetch strictly prohibited | context_catalog.rs |