Wenme

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
Ed25519
EdDSA · RFC 8032 · since Mar 2026
At rest
AES-256-GCM
Authenticated · Grover-resistant
Digest
SHA-256 / 512
NIST quantum-safe at 128-bit PQ
Transport
TLS 1.3
Cloudflare edge · direct HTTPS to identity
Passwords
None
Zero 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)

Ed25519 (EdDSA)RFC 8032

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)

AES-256-GCMNIST SP 800-38D

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

SHA-256 / SHA-512FIPS 180-4

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

TLS 1.3RFC 8446

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

bcrypt · cost 12OpenBSD spec

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

NONE

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

RSA-2048256 bytes
Ed2551932 bytes

8× smaller

Signature size

RSA-2048256 bytes
Ed2551964 bytes

4× smaller

Sign throughput

RSA-2048~1,200 ops/s
Ed25519~20,000 ops/s

~17× faster

Verify throughput

RSA-2048~25,000 ops/s
Ed25519~9,000 ops/s

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.

01

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.

02

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.

03

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.

04

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.

  1. 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
  2. 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
  3. 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
  4. 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/23

Expect

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