Generate key pairs, sign any value, and validate signatures — all in your browser. Three panes are post-quantum : pane 1 is SLH-DSA (FIPS 205, formerly SPHINCS+), pane 4 is ML-DSA (FIPS 204, formerly CRYSTALS-Dilithium), and pane 5 is Composite ML-DSA , which pairs ML-DSA with ECDSA or EdDSA so that a break of either leaves the other holding. Panes 1 and 4 also offer the context string and the pre-hash variants (HashML-DSA / HashSLH-DSA), which are different algorithms rather than options. Pane 2 uses RSA (PKCS#1 v1.5 and PSS); pane 3 uses ECC (ECDSA over P-256/P-384/P-521/secp256k1, EdDSA over Ed25519/Ed448, Schnorr over secp256k1, and BLS over BLS12-381); pane 6 uses BBS over BLS12-381 (both ciphersuites), which signs a list of messages and can derive an unlinkable proof over any subset of them. Panes 7 and 8 are about an envelope rather than a primitive: pane 7 is JWS (RFC 7515) over a JSON payload — every registered algorithm including all eleven post-quantum ones, all three serializations, detached and unencoded payloads; pane 8 is the W3C XML Digital Signature — enveloped, enveloping and detached, four canonicalization methods, and a configurable transform chain. Both refuse to sign input that does not parse. The RSA and ECDSA panes let you pair the signature with a wide range of hash algorithms — SHA-2, SHA-3, BLAKE2b, BLAKE3, and the legacy RIPEMD-160 / SHA-1 / MD5. Those eight panes are digital signature panes (the JWS and XML ones can also carry an HMAC, which is not one); the panes below them are symmetric MACs (keyed-hash: HMAC / KMAC / keyed-BLAKE; block-cipher: AES-CMAC / CBC-MAC / GMAC; universal-hash: Poly1305 / SipHash), labelled separately because a MAC uses a shared secret and is not a true digital signature. No key material is stored: keys live only in this page and are never written to local storage.
SLH-DSA Digital Signature Asymmetric ⏳ Heads up: SLH-DSA runs entirely in JavaScript, so key generation and especially signing can take several seconds — the small-signature (s) and 256-bit parameter sets are the slowest. This is expected; give each operation a moment to finish.
Value Copy
Signature (Base64) Copy
Variant — context string and pre-hash
These two controls select a different algorithm , not an option on this one. A context string (FIPS 205 §10.2) is mixed into the formatted message, so a signature made for one application cannot be replayed into another — a verifier using a different context, or none, will refuse it. A pre-hash selects HashSLH-DSA (FIPS 205 §10.2.2), which signs a digest of the message and puts the hash function’s OID into the signed bytes; a pure verifier will not accept a pre-hashed signature or vice versa. RFC 9964 requires the context to be EMPTY for the JOSE algorithms , so a non-empty context here is a raw-primitive feature and the JWS pane below does not offer it.
Stateful Hash-Based Signatures — LMS/HSS and XMSS/XMSS^MT Asymmetric Post-quantum Stateful The private key below changes every time you sign, and that is the whole subject. These are the two schemes NIST SP 800-208 approves — LMS/HSS (RFC 8554, with RFC 9858's SHA-256/192 and SHAKE256 parameter sets) and XMSS/XMSS^MT (RFC 8391, with SP 800-208's). Like SLH-DSA above they are Merkle trees over one-time signatures and secure if the hash function is; unlike it they are stateful , so the signer must remember which one-time keys it has spent. Spend one twice on different messages and an attacker gets the material to forge a third — which is why SP 800-208 §1 restricts these to places where the state can be guaranteed, firmware signing above all, and why RFC 8554 §5.4.1 requires the new index to reach storage before the signature is released. The pane keeps the index in the private key box and rewrites it on every Sign.
⏳ Why some parameter sets say “verify only here”. Generating a key means building a whole tree, and every leaf of it is a full one-time key pair — 220 of them for LMS_SHA256_M32_H20, which is hours in any language and days in a browser. Verification is untouched by this : it hashes one authentication path, so every parameter set in both registries verifies and describes here at once. That gap is also the entire argument for the multi-tree variants, and you can watch it: XMSS-SHA2_20_256 cannot be generated at all, while XMSSMT-SHA2_20/4_256 reaches the same 220 signatures out of trees of 32 leaves and generates in a fraction of a second.
Value Copy
Signature (Base64) Copy
Scheme & parameter set
LM-OTS parameter set (RFC 8554 Table 1, RFC 9858 Table 1) LMOTS_SHA256_N32_W1 — n=32, w=1, p=265 LMOTS_SHA256_N32_W2 — n=32, w=2, p=133 LMOTS_SHA256_N32_W4 — n=32, w=4, p=67 LMOTS_SHA256_N32_W8 — n=32, w=8, p=34 LMOTS_SHA256_N24_W1 — n=24, w=1, p=200 LMOTS_SHA256_N24_W2 — n=24, w=2, p=101 LMOTS_SHA256_N24_W4 — n=24, w=4, p=51 LMOTS_SHA256_N24_W8 — n=24, w=8, p=26 LMOTS_SHAKE_N32_W1 — n=32, w=1, p=265 LMOTS_SHAKE_N32_W2 — n=32, w=2, p=133 LMOTS_SHAKE_N32_W4 — n=32, w=4, p=67 LMOTS_SHAKE_N32_W8 — n=32, w=8, p=34 LMOTS_SHAKE_N24_W1 — n=24, w=1, p=200 LMOTS_SHAKE_N24_W2 — n=24, w=2, p=101 LMOTS_SHAKE_N24_W4 — n=24, w=4, p=51 LMOTS_SHAKE_N24_W8 — n=24, w=8, p=26
LMS parameter set (RFC 8554 Table 2, RFC 9858 Table 2) LMS_SHA256_M32_H5 — m=32, 2^5 signatures LMS_SHA256_M32_H10 — m=32, 2^10 signatures LMS_SHA256_M32_H15 — m=32, 2^15 signatures LMS_SHA256_M32_H20 — m=32, 2^20 signatures LMS_SHA256_M32_H25 — m=32, 2^25 signatures LMS_SHA256_M24_H5 — m=24, 2^5 signatures LMS_SHA256_M24_H10 — m=24, 2^10 signatures LMS_SHA256_M24_H15 — m=24, 2^15 signatures LMS_SHA256_M24_H20 — m=24, 2^20 signatures LMS_SHA256_M24_H25 — m=24, 2^25 signatures LMS_SHAKE_M32_H5 — m=32, 2^5 signatures LMS_SHAKE_M32_H10 — m=32, 2^10 signatures LMS_SHAKE_M32_H15 — m=32, 2^15 signatures LMS_SHAKE_M32_H20 — m=32, 2^20 signatures LMS_SHAKE_M32_H25 — m=32, 2^25 signatures LMS_SHAKE_M24_H5 — m=24, 2^5 signatures LMS_SHAKE_M24_H10 — m=24, 2^10 signatures LMS_SHAKE_M24_H15 — m=24, 2^15 signatures LMS_SHAKE_M24_H20 — m=24, 2^20 signatures LMS_SHAKE_M24_H25 — m=24, 2^25 signatures
HSS levels (L) L = 1 — a single LMS tree L = 2 L = 3 L = 4 L = 5 L = 6 L = 7 L = 8 — the maximum RFC 8554 allows
XMSS parameter set (IANA registry; RFC 8391 §5.3–5.4 and SP 800-208 §5) XMSS-SHA2_10_256 — 2^10 signatures, slow to generate XMSS-SHA2_16_256 — 2^16 signatures, verify only here XMSS-SHA2_20_256 — 2^20 signatures, verify only here XMSS-SHA2_10_512 — 2^10 signatures, slow to generate XMSS-SHA2_16_512 — 2^16 signatures, verify only here XMSS-SHA2_20_512 — 2^20 signatures, verify only here XMSS-SHAKE_10_256 — 2^10 signatures, slow to generate XMSS-SHAKE_16_256 — 2^16 signatures, verify only here XMSS-SHAKE_20_256 — 2^20 signatures, verify only here XMSS-SHAKE_10_512 — 2^10 signatures, slow to generate XMSS-SHAKE_16_512 — 2^16 signatures, verify only here XMSS-SHAKE_20_512 — 2^20 signatures, verify only here XMSS-SHA2_10_192 — 2^10 signatures, slow to generate XMSS-SHA2_16_192 — 2^16 signatures, verify only here XMSS-SHA2_20_192 — 2^20 signatures, verify only here XMSS-SHAKE256_10_256 — 2^10 signatures, slow to generate XMSS-SHAKE256_16_256 — 2^16 signatures, verify only here XMSS-SHAKE256_20_256 — 2^20 signatures, verify only here XMSS-SHAKE256_10_192 — 2^10 signatures, slow to generate XMSS-SHAKE256_16_192 — 2^16 signatures, verify only here XMSS-SHAKE256_20_192 — 2^20 signatures, verify only here XMSSMT-SHA2_20/2_256 — 2^20 signatures, slow to generate XMSSMT-SHA2_20/4_256 — 2^20 signatures XMSSMT-SHA2_40/2_256 — 2^40 signatures, verify only here XMSSMT-SHA2_40/4_256 — 2^40 signatures, verify only here XMSSMT-SHA2_40/8_256 — 2^40 signatures XMSSMT-SHA2_60/3_256 — 2^60 signatures, verify only here XMSSMT-SHA2_60/6_256 — 2^60 signatures, verify only here XMSSMT-SHA2_60/12_256 — 2^60 signatures, slow to generate XMSSMT-SHA2_20/2_512 — 2^20 signatures, verify only here XMSSMT-SHA2_20/4_512 — 2^20 signatures XMSSMT-SHA2_40/2_512 — 2^40 signatures, verify only here XMSSMT-SHA2_40/4_512 — 2^40 signatures, verify only here XMSSMT-SHA2_40/8_512 — 2^40 signatures, slow to generate XMSSMT-SHA2_60/3_512 — 2^60 signatures, verify only here XMSSMT-SHA2_60/6_512 — 2^60 signatures, verify only here XMSSMT-SHA2_60/12_512 — 2^60 signatures, slow to generate XMSSMT-SHAKE_20/2_256 — 2^20 signatures, slow to generate XMSSMT-SHAKE_20/4_256 — 2^20 signatures XMSSMT-SHAKE_40/2_256 — 2^40 signatures, verify only here XMSSMT-SHAKE_40/4_256 — 2^40 signatures, verify only here XMSSMT-SHAKE_40/8_256 — 2^40 signatures XMSSMT-SHAKE_60/3_256 — 2^60 signatures, verify only here XMSSMT-SHAKE_60/6_256 — 2^60 signatures, verify only here XMSSMT-SHAKE_60/12_256 — 2^60 signatures, slow to generate XMSSMT-SHAKE_20/2_512 — 2^20 signatures, verify only here XMSSMT-SHAKE_20/4_512 — 2^20 signatures XMSSMT-SHAKE_40/2_512 — 2^40 signatures, verify only here XMSSMT-SHAKE_40/4_512 — 2^40 signatures, verify only here XMSSMT-SHAKE_40/8_512 — 2^40 signatures, slow to generate XMSSMT-SHAKE_60/3_512 — 2^60 signatures, verify only here XMSSMT-SHAKE_60/6_512 — 2^60 signatures, verify only here XMSSMT-SHAKE_60/12_512 — 2^60 signatures, slow to generate XMSSMT-SHA2_20/2_192 — 2^20 signatures, slow to generate XMSSMT-SHA2_20/4_192 — 2^20 signatures XMSSMT-SHA2_40/2_192 — 2^40 signatures, verify only here XMSSMT-SHA2_40/4_192 — 2^40 signatures, verify only here XMSSMT-SHA2_40/8_192 — 2^40 signatures XMSSMT-SHA2_60/3_192 — 2^60 signatures, verify only here XMSSMT-SHA2_60/6_192 — 2^60 signatures, verify only here XMSSMT-SHA2_60/12_192 — 2^60 signatures XMSSMT-SHAKE256_20/2_256 — 2^20 signatures, slow to generate XMSSMT-SHAKE256_20/4_256 — 2^20 signatures XMSSMT-SHAKE256_40/2_256 — 2^40 signatures, verify only here XMSSMT-SHAKE256_40/4_256 — 2^40 signatures, verify only here XMSSMT-SHAKE256_40/8_256 — 2^40 signatures XMSSMT-SHAKE256_60/3_256 — 2^60 signatures, verify only here XMSSMT-SHAKE256_60/6_256 — 2^60 signatures, verify only here XMSSMT-SHAKE256_60/12_256 — 2^60 signatures, slow to generate XMSSMT-SHAKE256_20/2_192 — 2^20 signatures, slow to generate XMSSMT-SHAKE256_20/4_192 — 2^20 signatures XMSSMT-SHAKE256_40/2_192 — 2^40 signatures, verify only here XMSSMT-SHAKE256_40/4_192 — 2^40 signatures, verify only here XMSSMT-SHAKE256_40/8_192 — 2^40 signatures XMSSMT-SHAKE256_60/3_192 — 2^60 signatures, verify only here XMSSMT-SHAKE256_60/6_192 — 2^60 signatures, verify only here XMSSMT-SHAKE256_60/12_192 — 2^60 signatures
Key pair — and its remaining state
Both specifications define the public key and the signature to the byte and leave the private key to the implementation (RFC 8554 §5.2, RFC 8391 §4.1.3), because nothing interoperable depends on it. What is below is therefore this tool's own format — a seed and an index, tagged LMSK or XMSK so it can never be mistaken for something another tool reads. The public key and the signature are the standard encodings exactly.
Private Key (Base64 — this tool's format) Copy
Public Key (Base64 — the standard encoding) Copy
What happens if one index is used twice
This is the failure SP 800-208 exists to prevent, on demand. It signs the Value and the second value below from the same index and leaves the key's index untouched. Both signatures verify — nothing about either is detectably wrong to a verifier, which is exactly why the rule has to be enforced at the signer . What an attacker holds afterwards is two Winternitz chains revealed at two different heights, which is the material a forgery on a third message is built from. Use it on this throwaway key; never let it happen to a real one.
Second value Copy
Fields Copy
RSA Digital Signature Asymmetric Pick a padding scheme and any hash. Hashes marked legacy /insecure /broken are supported for interop/testing only — don't use them for real signatures. BLAKE2b-512 and BLAKE3-256 have no PKCS#1 v1.5 identifier, so use PSS with them.
Value Copy
Signature (Base64) Copy
Key Pair
Padding PKCS#1 v1.5 (RS*) PSS (PS*)
Hash SHA-256 SHA-384 SHA-512 SHA3-256 SHA3-384 SHA3-512 BLAKE2b-512 (PSS only) BLAKE3-256 (PSS only) RIPEMD-160 (legacy) SHA-1 (insecure) MD5 (broken)
Private Key Copy
Public Key Copy
PEM JWK DER PKCS#12
ECC Digital Signature Asymmetric ECDSA over any curve can use any hash. EdDSA (Ed25519 / Ed448), Schnorr (BIP-340) and BLS (BLS12-381) hash the message themselves, so the Hash selection is ignored for those. Schnorr and BLS keys export only as hex (no standard JWK). Hashes marked legacy /insecure /broken are for interop/testing only.
Value Copy
Signature (Base64) Copy
ML-DSA Digital Signature Asymmetric Post-quantum ML-DSA (FIPS 204, formerly CRYSTALS-Dilithium). The primary NIST post-quantum signature standard; fast lattice-based signing. Its JOSE and COSE binding is RFC 9964 — a published standard, not a draft.
🔑 The private key here is the 32-byte SEED, not the expanded key. RFC 9964 §3.2 requires an ML-DSA JWK’s priv parameter to be the seed, and the expanded 2560/4032/4896-byte signing key is re-derived from it on every use. That is why the Private Key box is short. A JWK carrying the expanded key is readable by almost nothing.
Value Copy
Signature (Base64) Copy
Variant — context string and pre-hash
These two controls select a different algorithm , not an option on this one. A context string (FIPS 204 §5.2) is mixed into the formatted message, so a signature made for one application cannot be replayed into another — a verifier using a different context, or none, will refuse it. A pre-hash selects HashML-DSA (FIPS 204 §5.4), which signs a digest of the message and puts the hash function’s OID into the signed bytes; a pure verifier will not accept a pre-hashed signature or vice versa. RFC 9964 requires the context to be EMPTY for the JOSE algorithms , so a non-empty context here is a raw-primitive feature and the JWS pane below does not offer it.
Composite ML-DSA Signature Asymmetric PQ/T hybrid Draft standard Draft standard — draft-ietf-jose-pq-composite-sigs-03. The combiner and the domain-separation labels below are taken verbatim from that revision; the JOSE algorithm names have no IANA assignment yet. The sibling document for X.509 is draft-ietf-lamps-pq-composite-sigs, which differs from this one in how the ECDSA component is encoded.
A composite signature is one signature made of two: an ML-DSA signature and a traditional ECDSA or EdDSA one, over the same message, verified together. It exists because nobody yet wants to bet a long-lived signature on lattices alone — the composite stays valid if either component survives, so a break of ML-DSA leaves ECDSA holding and a quantum computer leaves ML-DSA holding. Both halves must verify. If only one did, the construction would be strictly worse than the stronger component on its own.
The signed message is M’ = Prefix || Label || 0x00 || PH(M), where Prefix is the ASCII “CompositeAlgorithmSignatures2025”, Label identifies the exact combination, 0x00 encodes an empty application context as a length (it is not a string terminator), and PH is the per-algorithm pre-hash. The label is then used a second time as the ML-DSA context, which is what stops a component signature being lifted out of a composite and replayed as a standalone ML-DSA signature. The signature is the ML-DSA signature followed by the traditional one, both fixed length.
Value Copy
Signature (Base64) Copy
BBS Digital Signature Asymmetric Selective disclosure BBS over BLS12-381 (draft-irtf-cfrg-bbs-signatures), the same implementation the SD-JWT VC workflow uses for bbs-2023. It signs an ordered list of messages rather than one value, and the holder can then derive a proof that reveals only the messages they choose — each derivation is freshly randomised, so two proofs from one signature are unlinkable . Both ciphersuites the draft defines are here; they differ in more than a hash name (XMD/SHA-256 vs XOF/SHAKE-256, and each has its own fixed P1), so a key and a signature belong to one suite. Octet-string inputs — messages, header, presentation header, key info, key DST — are read as UTF-8 text or as hex, per the selector below; choose hex to reproduce the draft's own test vectors.
Messages (one per line) Copy
Input encoding UTF-8 text Hex octets
Header
Signature (Base64) Copy
JWS — JSON Web Signature Asymmetric or MAC RFC 7515 over a JSON payload, with every algorithm the JOSE registry defines: HS* (RFC 7518 §3.2), RS*, PS*, ES*, EdDSA over Ed25519 and Ed448 (RFC 8037), ES256K (RFC 8812) and the unsecured none. Only HS256 is Required ; RS256 and ES256 are Recommended and everything else is Optional — each option below says which. The signature covers BASE64URL(header) + "." + BASE64URL(payload), so the payload's own whitespace is inside the signature: this pane never reformats it for you. Sign refuses a payload that is not well-formed JSON. Note HS* is a MAC with a shared secret — a JWS, but not a digital signature.
Payload (JSON) Copy
JWS Copy
Decoded Copy
XML Digital Signature Asymmetric or MAC ⓘ No post-quantum algorithms are offered here, and that is not a gap in this page. The panes above sign with ML-DSA, SLH-DSA, FN-DSA and the PQ/T composites, and the JWS pane offers all thirteen as alg values — but no post-quantum algorithm URI has been registered for XML Signature by W3C or IANA, and none is proposed in any draft. There is therefore nothing to put in a <SignatureMethod Algorithm="…">, and inventing one would produce a document that no other implementation could ever read. When such a URI is registered it belongs here; until then this pane stops at RSASSA-PSS.
W3C XMLDSIG (RFC 3275) over an XML document, using the same in-browser engine the SAML, WS-Trust and WS-Federation workflows sign with. All three signature types are here — enveloped (the Signature goes inside the document), enveloping (the document goes inside a ds:Object in the Signature), detached (the Signature stands alone and names what it covers). Sign refuses XML that is not well-formed , and nothing here rewrites your input: a signature covers the exact octets that get canonicalized, so any "cleaning" would invalidate what it is about to produce. The transforms are an ordered chain and are applied in the order shown below the fields — a canonicalization ends the chain. HMAC-* is a MAC with a shared secret, not a digital signature. C14N 1.1 is not offered: its whole difference from 1.0 is xml:base inheritance, which this engine does not implement, and naming a method it does not perform would be worse than leaving it out.
XML Copy
Signed XML / ds:Signature Copy
Signature
Signature Type Enveloped Enveloping (ds:Object) Detached
SignatureMethod RSA-SHA256 RSA-SHA384 RSA-SHA512 RSA-SHA1 (insecure) RSASSA-PSS SHA-256 (RFC 9231) RSASSA-PSS SHA-384 (RFC 9231) RSASSA-PSS SHA-512 (RFC 9231) ECDSA-SHA256 ECDSA-SHA384 ECDSA-SHA512 ECDSA-SHA1 (insecure) HMAC-SHA256 (a MAC) HMAC-SHA384 (a MAC) HMAC-SHA512 (a MAC) HMAC-SHA1 (a MAC, insecure)
DigestMethod SHA-256 SHA-384 SHA-512 SHA-1 (insecure)
CanonicalizationMethod Exclusive C14N 1.0 Exclusive C14N 1.0 with comments Inclusive C14N 1.0 Inclusive C14N 1.0 with comments
Detail Copy
Keyed-Hash MACs Symmetric (MAC) A MAC authenticates with a single shared secret — it proves integrity and origin but gives no non-repudiation (both parties hold the same key), so it is not a digital signature. Compute a tag, or Verify a pasted tag.
Value Copy
MAC (Base64) Copy
Secret Key
Secret Key (hex) Copy
Block-Cipher MACs Symmetric (MAC) AES-based MACs. AES-CBC-MAC is legacy (insecure for variable-length messages). AES-GMAC here uses a fixed all-zero nonce for a deterministic demo tag — real GMAC needs a unique nonce per message.
Value Copy
MAC (Base64) Copy
Secret Key
Secret Key (hex) Copy
Universal-Hash MACs Symmetric (MAC) Poly1305 is a one-time authenticator — its 32-byte key must be unique per message. UMAC, VMAC, and PMAC are not offered: no maintained pure-JS implementation exists.
Value Copy
MAC (Base64) Copy
Secret Key
Secret Key (hex) Copy