Ed25519 Sign & Verify (RFC 8032)
Sign a message with an Ed25519 key or verify a signature in the browser, with the public key derived from the seed and R and S shown.
How to use
- Load the RFC 8032 vector to see a signature with a published value, then change one byte of the message and watch it stop verifying.
- To sign your own data, paste a seed, a PEM key or an expanded key — or press random seed — enter the message, and sign.
- Check the hex box when the message is binary; leave it clear to sign the UTF-8 bytes of what you typed.
- To check someone else's signature, switch to verify and paste their public key, the message and the 64 signature bytes.
- Read R, S and the canonical note when comparing against an implementation you are writing; that is where hand-rolled versions differ.
About this tool
ShowHide
Sign a message with an Ed25519 key, or check a signature against a public key, without the bytes leaving the tab. The private key field takes the three shapes an Ed25519 key actually arrives in: the bare 32-byte seed the test vectors publish, a PKCS#8 key as openssl genpkey writes it, and the 64-byte expanded key libsodium and OpenSSH hand out, which is the seed with the public key stuck on the end. WebCrypto imports only PKCS#8, so a seed is wrapped in the sixteen fixed DER bytes that precede it before import, and the public key comes back out through a JWK export, because there is no call that derives a public key from a private one. Paste a 64-byte key whose tail does not match the key its seed produces and the tool says so: that pairing signs happily and verifies against nothing. Verification reports more than a yes or no. The 64 bytes are split into R, a compressed point, and S, a little-endian scalar, and S is compared against the group order. A signature with S at or above the order is invalid under RFC 8032 even though its equation still holds, which is why adding the order to S — the old malleability trick for turning one signature into two — is rejected here instead of being waved through. Signing is deterministic, so a key and a message have exactly one signature and re-signing is a comparison rather than a fresh result. Public keys are not points checked for validity: a string of 32 zero bytes imports without complaint and simply verifies nothing, so a verdict of invalid can mean the key is not a key at all.
Frequently asked questions
Which key formats can I paste?
A 32-byte seed, a PKCS#8 private key, or a 64-byte expanded key that is the seed followed by its public key. Each may be hex, base64, base64url or PEM, and whitespace and armour lines are ignored. Hex is tried first, so a string that happens to be valid as both is read as hex. An OpenSSH private key file is a different container and is not accepted; export it with ssh-keygen to PKCS#8 first.
Why does the tool show the public key when I only gave it a private one?
Because the public key is a function of the seed, and seeing it is the quickest way to tell whether the key you pasted is the key you meant. WebCrypto has no derive-public call, so the tool exports the imported private key as a JWK, whose x member is the public key, and displays that. The signature and the public key therefore come from the same implementation.
What is the S check for?
RFC 8032 requires S to be below the order of the base point. Both halves of a signature would still satisfy the verification equation if you added the order to S, and an implementation that skips the range check accepts that reshaped pair as a second valid signature over one message — which breaks anything using a signature as an identifier. Browsers do enforce it, so such a signature reads as invalid here, and the note tells you which reason applies.
Is a signature over a hash the same as a signature over the message?
No, and it is a common way for two systems to disagree. Ed25519 hashes the message internally with SHA-512 and needs the whole message; signing a digest you computed yourself produces a valid signature over those 32 or 64 bytes, not over the file. If your protocol pre-hashes, it must say so, and the verifier has to pre-hash identically. Ed25519ph is the standardised variant for that, and it is not the same algorithm as plain Ed25519.
Can I use this for a real signing key?
It runs in a browser tab and keeps what you type in local storage, so a key pasted here is a key on that machine's disk. For understanding a format, reproducing a vector, or checking a signature someone sent you, that is fine. For a key that signs releases or authenticates hosts, keep the private half in a hardware token or a reviewed tool and paste only the public key here.
Related tools
Keypair Generator (RSA, EC, Ed25519)
Generate an RSA, ECDSA, ECDH, Ed25519 or X25519 keypair in your browser and export it as PKCS#8 and SPKI PEM or as JWK.
Developer
scrypt Key Derivation (RFC 7914)
Derive a key from a password with scrypt in the browser, with the memory cost worked out and the PBKDF2 and ROMix stages shown.
Developer
JWK to PEM Converter (and back)
Turn a JWK or a whole JWKS into PEM public keys and back, with the RFC 7638 thumbprint for each — computed in your browser.
Developer
SSH Public Key Inspector
Read an SSH public key, authorized_keys or known_hosts line: algorithm, key size, SHA256 and MD5 fingerprints, comment and options.
Developer
Sign a PDF Online
Draw, type or upload your signature, place it on any page of a PDF, and download the signed file. Runs in your browser; nothing is uploaded.
File
PGP Public Key Inspector
Read an armored OpenPGP public key: full fingerprint, key ID, algorithm, size, creation and expiry dates, user IDs and subkeys.
Developer