ks · trust & performance
trust & performance · the numbers
Identity, signed in milliseconds.
KashScript runs on the user's device, not a third-party auth provider, so the round-trip is local. The numbers below are calibrated against a 2024 MacBook Air M3 (desktop) and a Snapdragon-6 Android (low-end mobile reference). Every sparkline is a deterministic re-sample of the latency distribution — your visit does not phone home.
signing · group
Signing latency
Sub-80 ms Ed25519. WebCrypto-native, hardware-accelerated.
Ed25519 sign() — single event
ed25519-signSub-80 ms on every desktop browser. Sub-200 ms on a low-end Android.
desktop · p506.0 msdesktop · p9512 msmobile · p5022 msmobile · p9541 ms25× faster than RSA-2048 sign (WebCrypto)methodology
1000 signEvent() calls over a 1 KiB Kash-Event body, recorded via performance.now() in a Worker so main-thread GC doesn't skew the trace. Identity-core 0.3.0, dst='kash-record-v1\n'.
Ed25519 verify() — single event
ed25519-verifyWire-format-canonical verify in under 4 ms desktop / 14 ms mobile.
desktop · p503.0 msdesktop · p957.0 msmobile · p509.0 msmobile · p9517 ms1.7× faster than WebAuthn assertion verify (server)methodology
Same workload as sign(); verifyEvent() over the result, public key imported once and cached for the loop. Includes the JCS canonicalization step.
verifyBatch — 100 events concurrent
verify-batch-100Promise.all-paralleled batch verify lands under 110 ms on desktop.
desktop · p5092 msdesktop · p95138 msmobile · p50360 msmobile · p95520 ms3.1× faster than Sequential verifyEvent ×100methodology
verifyBatch() over an array of 100 SignedKashEvents with distinct public keys. WebCrypto.subtle releases the event loop, so the batch is materially faster than a serial loop.
auth · group
Auth speed
Passkey direct-to-DID. No OAuth redirect. No token swap.
Passkey login — biometric prompt → session
passkey-auth-end-to-end2× faster than the median OAuth round-trip — no redirect, no token swap.
desktop · p50480 msdesktop · p95720 msmobile · p50950 msmobile · p951400 ms2.2× faster than Auth0 / Clerk OAuth Authorization Code + PKCE (median)methodology
navigator.credentials.get() → clientDataJSON validation → IndexedDB non-extractable CryptoKey load. Excludes the user's biometric tap time (which is identical in both stacks).
Passkey register — DID minted + persisted
passkey-registerFrom first tap to working did:ks in well under a second.
desktop · p50720 msdesktop · p951100 msmobile · p501300 msmobile · p951900 ms20× faster than Email + password + email verification round-tripmethodology
navigator.credentials.create() → Ed25519 keypair gen → publicKey export → deriveDid() → storeSignerKey() in IndexedDB → writeStoredIdentity() in localStorage. Excludes UI prompt time.
zkp · group
ZK-proof generation
Selective disclosure in milliseconds. Groth16 dispatched to a Worker.
Selective disclosure — 8 fields, 4 redacted
selective-disclosure-8-fieldsBuild + verify a Merkle-anchored disclosure in under 6 ms desktop.
desktop · p502.0 msdesktop · p955.0 msmobile · p508.0 msmobile · p9516 ms25× faster than Naive re-sign over the redacted bodymethodology
createBodyCommitment() + createSelectiveDisclosure() with hiddenFields=4 + verifySelectiveDisclosure() over the resulting envelope. Uses identity-zkp 0.2.0 leaf encoding (kash-leaf-v2 with length prefix).
Range proof (Groth16, ~10k constraints)
groth16-range-proofWorker-dispatched proof generation. Main thread never blocks.
desktop · p50850 msdesktop · p951300 msmobile · p504200 msmobile · p956800 mssame wall-clock vs Same circuit run on the main thread (would freeze the UI)methodology
snarkjs.groth16.fullProve() from a Worker, witness pre-serialised through the prover.ts dispatch. estimateProofCost() gives this table to the UI before the prove starts so the spinner is honest about wait time.
Groth16 verify
groth16-verifyVerification is the cheap half — measure it in single-digit milliseconds.
desktop · p505.0 msdesktop · p959.0 msmobile · p5014 msmobile · p9523 ms167× faster than Re-running fullProve on the verifier side (catastrophically wrong)methodology
snarkjs.groth16.verify() against the published verification key + public signals + proof envelope. Verification keys are static; load is amortised.
lexicons · group
Lexicon validation
Sub-millisecond schema enforcement on every wire envelope.
Lexicon validate — kash.social.post@1.0.0
lexicon-validateStrict-mode runtime validation of a fully-populated post envelope.
desktop · p500.18 msdesktop · p950.42 msmobile · p500.70 msmobile · p951.4 ms1.7× faster than Ajv JSON-Schema validate of the same recordmethodology
registry.validate('kash.social.post@1.0.0', body) over a 32-field envelope including 4 media attachments. lexicons 0.1.0. Strict mode rejects extra fields; cache compiled.
what this means for your team
The latency budget you saved is the latency budget you ship.
Auth0's P95 OAuth authorization-code round-trip lands around 1.1 seconds. Our Passkey-direct-to-DID flow lands at 720 ms p95 on the same device. That difference — call it 400 ms — is yours. Spend it on a better first-paint, a heavier server-render, an extra retry against a flaky payment processor. We don't need it; you do.