How quality is measured, and where the evidence behind every claim lives.
Testing & software quality
Every important failure mode becomes a test.
699/701 Rust workspace tests and 173 Swift shell tests pass against real aws-lc-rs cryptography (2 existing Rust tests ignored), run 2026-08-10. Organised below by assurance purpose, not framework.
Unit & state-machine tests
✓Tested
Domain rules, guard functions, transitions, encoding/decoding, boundary conditions — every protocol guard maps 1:1 to a named abort reason and has a test.
The six core Lean models emit transition traces; six Rust suites replay them against the production machines, byte-for-byte. The seventh model (app-shell navigation) is bound to the shipped Swift by an exhaustive (state × event) conformance test. Android has hosted shell tests but still needs its own formal shell model and exhaustive Kotlin conformance suite. CI regenerates traces and fails on staleness — no platform may claim formal parity without that binding.
Full flows through the sans-IO core with real aws-lc-rs cryptography: issue → hold → present over live TCP sockets; payment SCA; QES; wallet-to-wallet; status blocking; export integrity; FFI JSON contract.
e2e_live_presentation.rs / e2e_live_lifecycle.rs (real sockets, RP verifies)crates/shell-io/tests
Every important failure mode becomes a test: replay, wrong nonce/audience, untrusted issuer, revoked/expired credentials, tampered transactions, forged codes, malformed input, misdirected transfers, alg:none.
Distinct test functions whose names encode a rejection/attack case (rejects_*, *replay*, *tamper*, *forged*, *mismatch*, *untrusted*, *revoked*, *invalid*, *malformed*), counted by grep — a subset of the workspace tests.
clippy -D warnings across all targets/features (PASS, 2026-08-10); rustfmt gate; cargo-deny (licenses/bans/sources/advisories) with a written dependency budget; cargo-audit; and a PUBLISHED CycloneDX SBOM (21 crates; wallet-core = 111 runtime components).
Published SBOM (CycloneDX 1.3)docs/certification-evidence/sbom/
Mutation testing
✓Tested
73viable mutants caught
cargo-mutants mutates the security-critical OpenID4VP presentation crate and checks the tests catch each change — measuring whether tests constrain behaviour, not just execute it. The initial run caught 52/73 viable mutants (71%); the 21 misses were real test gaps, closed by adding crate-local tests. Re-run: 73/73 viable caught, 0 missed.
Viable mutants caught / total viable, cargo-mutants v27.1.0 on crates/oid4vp with the crate-local test suite (2026-07-19). 8 unviable (non-compiling) mutants excluded per standard practice. Scope: oid4vp only — a test-adequacy measure, not a correctness proof.
Dependency-free micro-benchmarks of the hot paths against the real aws-lc-rs backend (ES256 sign ~28.7µs / verify ~83.6µs, SHA-256 ~58ns, SD-JWT parse ~430ns; release, Apple Silicon, 2026-07-19). A flow is dominated by one or two ES256 ops plus one TLS round trip.
cargo run -p benches --releasedocs/certification-evidence/perf-benchmarks.md
Interoperability probe
◐Partial
A reproducible probe of the EUDI reference environment over platform TLS: the reference issuer's live OpenID4VCI metadata (HTTP 200, 27 configurations — 11 in the SD-JWT VC format this wallet implements) and reference-verifier reachability. Reachability + wire-shape, NOT a conformance pass.
The wallet presents over three channels: OpenID4VP by QR / deep link, in-person over Bluetooth (ISO 18013-5), and — the primary route for most users — the W3C Digital Credentials API, where a website calls navigator.credentials.get({ digital: … }) and the OS routes the request to the wallet. The DC-API core is implemented and tested (the byte-exact OpenID4VPDCAPIHandover binds the response to the browser-verified Origin, and an end-to-end test drives request → consent → a minimised mdoc vp_token). The iOS provider that surfaces this to Safari is being wired next; until it lands you can still see the OS route a request to the wallet.
→Digital Credentials API — open a DC-API verifier page in a supporting browser (Safari on iOS 26, or Chrome on Android) and request an mdoc/PID. Neutral test verifiers: the eudiw.dev reference verifier and Google's Digital Credentials API test pages both drive navigator.credentials.get({ digital }).
→OpenID4VP by QR / deep link — works today: build a request on the VCVerifier page and scan its openid4vp:// link with the wallet.
→In person (Bluetooth, ISO 18013-5) — tap “Present in person”, show the engagement QR to a compatible mdoc reader; the wallet returns a minimised, encrypted DeviceResponse.
The PID is issued and held in BOTH mdoc and SD-JWT VC form (per the ARF), so a verifier can ask for either format over any of these channels.
Coverage, honestly Code coverage (line/branch/function) has not been measured yet — the number is deliberately absent rather than implied. Coverage also would not prove correctness: the complementary assurance here is machine-checked invariants (Lean), symbolic protocol analysis (Tamarin), oracle-replay conformance binding model to code, adversarial tests, and fuzzing.
Requires an external party (not closeable by our code)
– Independent penetration test (accredited security assessor)
– Accessibility audit of the mobile app (the landing page itself targets WCAG 2.2 AA; a formal audit of the iOS app is external)
– OpenID Foundation conformance certification (their harness; self-certification program opened 2026-02-26)
– CAB certification under CIR (EU) 2024/2981 + EUCC, and wallet-provider / Member-State registration
Planned (codeable) — not yet done, no result implied
– Completed live issuance / presentation round trip against issuer.eudiw.dev / verifier.eudiw.dev — automatable as an XCUITest driving the app (pre-authorized-code issuance + direct_post presentation) with the reference trust anchors pinned as fixtures; the interactive browser-eID grant is the one step that stays manual or mocked, so it runs as a nightly integration job, not a gating unit test
– Live mso_mdoc issuance against an external issuer
A conformant wallet becomes a known-good test counterpart.
Conditional future capability: every applicable local gate is green, the tested build is version-pinned, and official OpenID/EUDI conformance results for the exercised profiles are published.
At that point this wallet becomes a known-good protocol counterpart for teams building the other side in parallel. They can test against a stable, independently evidenced participant instead of waiting for every issuer, verifier and peer wallet to mature at the same time.
Issuer under test
Drive a conformant wallet through metadata discovery, PAR/PKCE, proof, credential response, portrait/profile validation and status handling; attribute a failure to the issuer-facing boundary.
Verifier under test
Send signed OpenID4VP/DCQL requests to the wallet and verify its SD-JWT or mdoc response, including encrypted direct_post.jwt, nonce, certificate binding and minimised disclosure.
Wallet or transport peer under test
Exercise wallet-to-wallet and proximity handshakes against pinned happy-path and hostile traces, including replay, substitution, interruption and recovery cases.
Reproducible cross-implementation loop
1.Pin the wallet commit, profile versions, trust anchors, fixtures and expected capabilities.
2.Run the same happy-path and negative corpus against every parallel implementation.
3.Capture redacted wire transcripts, hashes, state transitions and exact pass/fail reasons.
4.Compare outcomes differentially: conformant peers should agree; divergence becomes a small, reproducible case.
5.Promote every resolved interoperability defect into a permanent cross-implementation regression test.