Skip to content

5 · How we know it works ​

← two-key model · index · next: Build log →


The principle: never let code mark its own homework ​

Every signature test verifies against the public key the plugin handed out, using a third-party verifier — never the plugin's own code.

BackendVerifier usedWhere
Rust softwarethe p256 crate's verifiertests/desktop_signer.rs
WebCryptocrypto.subtle.verifyguest-js/web-backend.test.ts
AndroidKeyStorejava.security.Signatureandroid/src/androidTest/
Any, on-devicecrypto.subtle.verify in the WebViewthe example app's verify button

All of them also assert the signature is exactly 64 bytes. A DER signature is 70–72 bytes and would fail verification roughly 1 time in 256 rather than every time — which is precisely the bug that ships.


Known-answer vectors, not round-trips ​

The DER→P1363 conversion exists three times. Each copy is tested against the same fixed inputs and expected outputs.

Each expected value was computed independently, re-encoded to DER, and confirmed with openssl dgst -sha256 -verify against the real public key — so the expectations are anchored to a third-party implementation, not to our own output.

Why known answers rather than round-trips: a round-trip can be self-consistently wrong. An encoder and a decoder sharing the same padding bug cancel each other out and the test passes. A fixed input with a fixed expected output cannot do that.

Covered in each language: a short r, a short s, both short, a high-bit component carrying DER's 0x00 sign byte, the r=1, s=2 extreme, a zero component, long-form lengths, an always-64-bytes property check, and ten malformed inputs (empty, truncated, wrong tag, overrunning length, zero-length INTEGER, trailing bytes) that must fail cleanly rather than read out of bounds.


The wire contract, pinned three times ​

The string↔enum mapping is duplicated once per language, and duplication drifts. So the exact strings are asserted in tests/wire_contract.rs, WireContractTest.kt and WireContractTests.swift. A rename on one side turns into a red build on that side, instead of a runtime failure on one platform.

Unknown value arrivesResultWhy
backing tagsoftwareunder-reporting strength is harmless; over-reporting is a false claim
protection taghard failureboth wrong guesses are harmful — no safe default exists
error codeunknown, raw string keptdiagnosable rather than flattened

The test pyramid ​

96 tests run without any device. The Swift suite is a standalone SwiftPM package whose sources are symlinks to the files the plugin ships — so it exercises the real code, not a copy that could drift, and it needs no simulator, no Tauri runtime and no keychain.


What has actually been run, and what has not ​

Honesty about coverage matters more than a green badge.

An emulator skips the hardware-residency assertion rather than passing it. A skipped assertion is honest; a passing one on a software keymaster would be a lie told by the test suite.


Running everything ​

bash
cargo test && cargo clippy --all-targets -- -D warnings   # Rust
npm install && npm test && npm run typecheck              # TypeScript
cd darwin_tests && swift test                             # Swift (~1s, no simulator)

# Kotlin — from the example's generated host project
cd examples/tauri-app && npm install && npx tauri android init
cd src-tauri/gen/android && ./gradlew :tauri-plugin-sign-keypair:testDebugUnitTest

← two-key model · index · next: Build log →

Released under the MIT License.