Recommended Free Tools
To sign and verify data with Ed25519 in Python, use the cryptography package. Call sign() on an Ed25519PrivateKey to produce a 64-byte signature, then call verify() on the matching public key with the same signature and the same bytes. A successful verify() returns None. A signature that does not match raises cryptography.exceptions.InvalidSignature.
A complete signing and verification example
The pyca/cryptography documentation for release 46.0.4 demonstrates the basic pattern. The flow has three steps:
As an Amazon Associate I earn from qualifying purchases.
- Generate a private key with
Ed25519PrivateKey.generate(). - Sign the message bytes with
private_key.sign(message). - Derive the public key with
private_key.public_key()and check the signature withpublic_key.verify(signature, message).
from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
private_key = Ed25519PrivateKey.generate()
public_key = private_key.public_key()
message = b"invoice-1042:amount=350.00:currency=USD"
signature = private_key.sign(message)
try:
public_key.verify(signature, message)
print("signature valid")
except InvalidSignature:
print("signature invalid")
The verifying side needs only the public key, the signature, and the message. The private key never leaves the signer.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Signing text and matching the exact bytes
The sign() and verify() methods accept bytes-like data, not Python str objects. Text must be encoded deliberately, and the same encoding must be applied on both sides:
#1 Best Overall
message_text = "Order 1042 shipped"
message = message_text.encode("utf-8")
signature = private_key.sign(message)
# The verifier must reconstruct the identical byte sequence.
public_key.verify(signature, "Order 1042 shipped".encode("utf-8"))
Ed25519 signs the exact byte sequence. Re-serializing JSON, changing line endings, trimming whitespace, or decoding and re-encoding text can all change the bytes, and verification will then fail even though the data looks the same to a person.
What InvalidSignature means
Verification raises InvalidSignature when the signature does not match the public key and the message together. The exception does not say which input is wrong, so troubleshooting means checking each input against the signer.
Rank #2
Common causes
- Different message bytes. The verifier received altered, re-encoded, or re-formatted data. Compare the raw bytes on both sides, for example by hashing them.
- Wrong public key. The public key belongs to a different private key, or a key was rotated and the verifier still holds the old one.
- Corrupted or truncated signature. A valid Ed25519 signature is 64 bytes. A signature stored as text, such as hexadecimal or base64, must be decoded back to the original 64 bytes before verification.
- Wrong key representation. Raw key bytes were loaded where a PEM or DER container was expected, or the reverse. See the serialization section below.
Treat InvalidSignature as a reject decision. Do not catch it and continue processing the data.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteKey and signature sizes
RFC 8032, published by the Internet Research Task Force in January 2017, specifies Ed25519 public keys as 32 bytes and signatures as 64 bytes. These are format sizes from the specification, not performance measurements. A length check is a useful sanity test before handing bytes to the library, because a wrong length usually points to an encoding or decoding error.
Serializing keys for other systems
The library can write and read private and public keys in several encodings. The encoding and the format must be chosen together, because each encoding pairs with a specific format:
| Encoding | Public-key format it pairs with | What to expect |
|---|---|---|
| Raw | Raw | Bare 32-byte key with no header or container |
| PEM | SubjectPublicKeyInfo | Base64 text between BEGIN and END lines |
| DER | SubjectPublicKeyInfo | Binary ASN.1 structure with the same content as PEM |
| OpenSSH | OpenSSH | Single-line ssh-ed25519 public key text |
Raw key bytes and PEM or DER containers are not interchangeable wire formats. The receiving system dictates which one to use, and the peer’s accepted format must be confirmed before a key is exported. Whether a particular peer or backend accepts each form is not stated by the library documentation and must be checked against that system.
Raw public keys
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
raw_public = public_key.public_bytes(
encoding=serialization.Encoding.Raw,
format=serialization.PublicFormat.Raw,
)
assert len(raw_public) == 32
loaded_public_key = Ed25519PublicKey.from_public_bytes(raw_public)
loaded_public_key.verify(signature, message)
PEM public and private keys
pem_public = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo,
)
pem_private = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption(),
)
NoEncryption() writes the private key in plaintext. Use it only when the file is protected by other means, such as restricted file permissions or a secrets manager. For stored keys, pass serialization.BestAvailableEncryption(passphrase) with a passphrase obtained from a secret store, and load the key later with serialization.load_pem_private_key(pem_private, password=passphrase).
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteEd25519 or Ed25519ph
RFC 8032 defines two signature choices that are easy to confuse. Plain Ed25519 is the PureEdDSA variant: it signs the message directly. Ed25519ph is a prehash variant: it hashes the message with SHA-512 before signing. The two produce different signatures for the same input, so a verifier using one variant cannot accept signatures made with the other.
Best Value
| Variant | Message processing | Context |
|---|---|---|
| Ed25519 | Signs the message directly (PureEdDSA) | Empty context |
| Ed25519ph | Hashes the message with SHA-512, then signs the hash | Context is a feature of the distinct variants, not of plain Ed25519 |
Do not pre-hash input before calling the ordinary Ed25519 API. Use the prehash variant only when the protocol specifies it and both parties agree on it. Confirm that the library you plan to use exposes the variant you need; the Ed25519 API documented for release 46.0.4 covers the ordinary variant.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Handling keys and choosing this primitive
The pyca/cryptography documentation describes the Ed25519 API as a hazardous-materials interface. That label means the primitive is low-level and security-sensitive: it is not a substitute for a higher-level protocol design. Application code should use an established library, not a hand-written curve implementation.
The library documentation states: “If you do not have legacy interoperability concerns then you should strongly consider using this signature algorithm.” If your peers require older algorithms, follow their requirements. Otherwise Ed25519 is a strong default for new signing flows.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Key custody and rotation are not handled by the signing code. Store private keys in a protected location, limit who can read them, and follow the rotation schedule your protocol requires. The verifying side must also know which public key is current, so rotation needs a plan for updating every verifier.
Checklist before shipping a signature flow
- Confirm the installed version with
pip show cryptographyand check the matching documentation. The sizes and API details here reflect release 46.0.4; the main-branch documentation is not pinned to a release. - Define the exact byte sequence that is signed, including encoding and any serialization step.
- Match the key encoding and format to the receiving system, and test the round trip with that system.
- Decide which Ed25519 variant the protocol uses before writing any code.
- Reject on
InvalidSignatureand log the failure without logging private key material. - Store private keys with restricted access and document the rotation process for public keys.
This guidance is based on pyca/cryptography 46.0.4 documentation and RFC 8032 (January 2017). It does not cover a specific deployment’s key-management controls or the backend support of every build, so verify those in your own environment.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




