Cryptography · spec sheet
Crypto agility.
A migration path, not a redesign.
Wenme’s cryptographic posture is the boring one on purpose. Classical-best-in-class signatures today, symmetric primitives that are already quantum-resistant, and the algorithm identifier in JWKS so the day a NIST PQC signature stabilizes in the Go standard library, we rotate a key — not the architecture.
⌐ primitives in production · 2026-04-13
- Signature
- Ed25519EdDSA · RFC 8032 · since Mar 2026
- At rest
- AES-256-GCMAuthenticated · Grover-resistant
- Digest
- SHA-256 / 512NIST quantum-safe at 128-bit PQ
- Transport
- TLS 1.3Cloudflare edge · direct HTTPS to identity
- Passwords
- NoneZero hashes to harvest, ever
01 / 06
Today’s primitives.
Specified, not described.
What runs in production right now. Each row is an algorithm identifier you can verify against the JWKS document, not a marketing label.
Signature (JWT, ID token, OAuth code)
32-byte private key, 32-byte public key, 64-byte signature. Deterministic, side-channel resistant by construction. Migrated from RSA-2048 (RS256) in March 2026.
Symmetric encryption (data at rest)
Authenticated encryption with associated data. 256-bit key, 96-bit nonce. Per-tenant key rotation. Symmetric — retains 128-bit security under Grover's algorithm.
Cryptographic hash
Used for HMAC, digest envelopes, and integrity checks. NIST recognizes both as quantum-safe at 128-bit and 256-bit post-quantum security respectively.
Transport security
Out-of-process: handled at the Cloudflare edge for wenme.net and end-to-end TLS for identity.wenme.net. PFS via X25519 + AES-256-GCM cipher suites.
PII and backup-code hashing
Used for backup codes and personal data hashing. Cost factor 12 (~250ms per hash on production hardware). Not used for passwords because there are no passwords.
Password handling
There is no password column. There are no password hashes. The legacy code paths were removed in the March 2026 cleanup. This eliminates an entire harvest-now-decrypt-later attack class.
02 / 06
Post-quantum readiness.
The honest version.
We’re going to be specific because banks have started asking specific questions, and because vague answers here are how vendors get caught out at the audit stage.
Already quantum-resistant
- AES-256-GCM
- Symmetric. Grover halves effective security; 256-bit key retains 128-bit post-quantum strength. Compliant with NSA CNSA 2.0.
- SHA-256, SHA-512
- Symmetric. Grover gives 128-bit and 256-bit post-quantum collision resistance respectively. Both NIST-recognized as quantum-safe.
- No password hashes
- The harvest-now-decrypt-later threat for bcrypt'd password databases simply does not apply. There are no password hashes.
Not yet quantum-resistant
- Ed25519 signatures
- Curve25519 ECDLP. Broken by Shor's algorithm on a sufficiently large quantum computer. We chose Ed25519 because it is the best classical signature available — not because it is post-quantum.
- TLS 1.3 ECDHE key exchange
- X25519 ECDH. Same Shor exposure as above. Migration is being driven by Cloudflare and Go's TLS stack, not by us; we adopt as upstreams ship.
- Risk window
- Cryptanalytically-relevant quantum computers do not exist publicly. NIST projects 10–20 years to operational threat. Our agility makes the migration a routine rotation when it matters.
Honesty clause
We do not call Ed25519 “quantum-safe”. It isn’t. We do not market “post-quantum cryptography” as a shipping feature. It isn’t — yet. What we ship today is the strongest classical signature algorithm in widespread use, symmetric primitives that already meet the post-quantum bar, and the engineering hooks (JWKS alg / kid, hybrid-signature support in JOSE drafts) needed to land ML-DSA without a rewrite when the Go standard library and the IETF JOSE registries catch up.
03 / 06
Why Ed25519, not RSA-2048.
Engineering reasons. Not a quantum claim.
Ed25519 is not post-quantum. We migrated for size, speed, and the absence of parameter pitfalls — the same reasons SSH, Signal, and most modern protocols moved off RSA years ago.
Public key size
8× smaller
Signature size
4× smaller
Sign throughput
~17× faster
Verify throughput
RSA faster, off hot path
Measured on the production host, Go 1.26.2 / OpenSSL 3.0.13, x86_64, 2026-04-13. Signing is the IdP hot path — every issued JWT. Verification happens at relying parties, so Ed25519’s slower verify does not sit on our workload.
Side-channel resistance by construction
Ed25519 uses constant-time arithmetic on Curve25519. There is no scalar-blinding work for an implementer to forget. RSA-2048 has a long history of timing-attack classes — Bleichenbacher (1998), ROBOT (2017), and recurring padding-oracle CVEs across major TLS stacks.
No parameter pitfalls
Ed25519 has one curve, one cofactor, one set of domain parameters. RSA needs key length, padding scheme, exponent choice — three places to misconfigure. EdDSA also signs deterministically, so a bad RNG cannot leak the key.
Smaller JWTs on the wire
A 64-byte signature versus 256 bytes matters when ID tokens are passed through user-agent URL fragments, mobile push payloads, and WebSocket frames.
Algorithm agility, kept honest
JWKS publishes the alg explicitly. Verifiers reject unknown algorithms. Adding ML-DSA later means publishing a second key, not retrofitting a parser.
04 / 06
The migration path.
Four steps. No rewrite.
Crypto agility means the migration is operational, not architectural. Each step is additive; each step ships when its dependency upstream is stable. No customer code changes.
- 01
Today (shipping)
Ed25519 + AES-256-GCM + SHA-256
Classical best-in-class for signatures. Symmetric primitives already meet the post-quantum bar. JWKS carries explicit alg and kid headers; the verification path can route on either.
shipping - 02
Q3 2026 target
Hybrid JWT signatures — Ed25519 + ML-DSA
Sign JWTs with both algorithms simultaneously, per draft-ietf-cose-hybrid-jose. Verifiers trust the response if either signature validates. Pending Go stdlib ML-DSA support and JOSE registry assignment of the hybrid alg identifier.
planned - 03
When ML-DSA stabilizes
ML-DSA primary, Ed25519 verify-only
Promote ML-DSA (NIST FIPS 204, the standardized form of CRYSTALS-Dilithium) to the active signing key. Ed25519 keeps a kid in JWKS for legacy verifier compatibility, then is retired one rotation cycle later.
planned - 04
Operationally
No database migration. No API contract change.
Algorithm swap happens at the JWKS document. Customer integrations — NextAuth.js, Auth.js, raw OIDC clients — pick up the new key on the next refresh. The JWT structure is unchanged.
invariant
05 / 06
Verify it yourself.
Don’t take our word for it.
Banks’ cryptographers tend to want to see the bytes. Each command below queries production. Each one returns a fact, not a claim.
OpenID discovery — see signature algorithms
$ curl -s https://identity.wenme.net/.well-known/openid-configuration | jq '.id_token_signing_alg_values_supported'Expect
["EdDSA"]
The id_token_signing_alg_values_supported array advertises only EdDSA. RS256 has been removed from the discovery document.
JWKS — fetch the live Ed25519 public key
$ curl -s https://identity.wenme.net/.well-known/jwks.json | jq '.keys[] | {kid, kty, crv, alg}'Expect
{ "kid": "...", "kty": "OKP", "crv": "Ed25519", "alg": "EdDSA" }kty: OKP, crv: Ed25519, alg: EdDSA. The kid lets verifiers cache and rotate. Adding ML-DSA later adds a second object; this one stays for legacy verify.
Network ownership — APNIC WHOIS
$ whois -h whois.apnic.net 103.139.234.0/23Expect
inetnum: 103.139.234.0 - 103.139.235.255 netname: KK-BD descr: KaritKarma country: BD status: ALLOCATED PORTABLE mnt-by: MAINT-KK-BD
KaritKarma holds the /23 as a portable APNIC allocation. The announced /24 (103.139.235.0/24) originates from AS64005 (as-name KK-AS-AP) with a valid RPKI ROA. Any BGP looking-glass confirms the origin.
TLS posture — handshake on identity.wenme.net
$ echo | openssl s_client -connect identity.wenme.net:443 -tls1_3 2>/dev/null | grep -E "Protocol|Cipher"Expect
Protocol: TLSv1.3 Cipher: TLS_AES_256_GCM_SHA384
TLS 1.3 enforced. AES-256-GCM symmetric cipher with SHA-384 PRF. X25519 key exchange (visible in full handshake output).
06 / 06
What we don’t claim.
Important, written down.
A short list of things you should not infer from this page, because vendors who let you infer them get caught later.
Ed25519 is not post-quantum.
Shor’s algorithm breaks all current ECC. We chose Ed25519 because it is the strongest classical signature in production use, not because it survives a quantum adversary.
We are not FIPS 140-3 validated.
The Go runtime crypto modules are not FIPS-validated in our build. Banks needing FIPS 140-3 hardware modules should request the on-prem deployment with HSM-backed signing keys — supported, but not in the SaaS path.
ML-DSA is not yet shipped.
It is on the roadmap, with a concrete dependency on Go standard library availability. We will not pre-announce a date we don’t control.
Cloudflare terminates TLS for the marketing site.
wenme.net runs through Cloudflare. identity.wenme.net does not — it is direct TLS to the origin. Both endpoints are documented; the trust boundary is explicit.
For the cryptographer at the back of the room
Ask the hard questions.
We answer in algorithm names.
Threat model walk-through, source-tree access, on-prem HSM deployment options. Email goes straight to the engineer who owns the signing path.
Cryptographic assertions on this page are verifiable against the production JWKS at https://identity.wenme.net/.well-known/jwks.json.
last reviewed 2026-04-13