Ed448 is a digital signature algorithm on the edwards448 curve that uses SHAKE256 as its hash, with 57-byte public keys and 114-byte signatures. It is the larger sibling of Ed25519 in RFC 8032 and targets about 224 bits of security. FIPS 186-5 also approves it, and it is the choice when you want a wider margin than Ed25519 offers.
Ed448 follows the same EdDSA recipe as Ed25519 with larger numbers. The private key is 57 random bytes (456 bits). RFC 8032 hashes it with SHAKE256 to 114 bytes, uses part of the output to build the secret scalar, and multiplies the base point by that scalar. The 57-byte public key is that point in compressed form, and its last byte carries only a sign bit.
The curve is defined over the prime 2^448 - 2^224 - 1. Its group order is close to 2^446, and its cofactor is 4. The signature holds two 57-byte halves, R and S, so it is 114 bytes. Nonces are derived from the key and message, so Ed448 is deterministic like Ed25519.
One detail sets Ed448 apart in the specification. Every hash call starts with a domain separator called dom4, built from the ASCII string SigEd448, a flag byte and an optional context of up to 255 octets. Plain Ed448 uses flag 0 and an empty context by default. Ed25519 allows no context in its plain form. A signer and verifier must use the same context byte for byte, or verification fails.
The script below signs an empty message with the first Ed448 test key in RFC 8032, then flips one bit of the signature.
from cryptography.hazmat.primitives.asymmetric.ed448 import Ed448PrivateKey
from cryptography.hazmat.primitives import serialization as s
sk=Ed448PrivateKey.from_private_bytes(bytes.fromhex("6c82a562cb808d10d632be89c8513ebf6c929f34ddfa8c9f63c9960ef6e348a3528c8a3fcc2f044e39a3fc5b94492f8f032e7549a20098f95b"))
pub=sk.public_key().public_bytes(s.Encoding.Raw,s.PublicFormat.Raw)
sig=sk.sign(b"")
print("public:", pub.hex(), len(pub))
print("sig :", sig.hex(), len(sig))
sk.public_key().verify(sig,b""); print("verified")
try:
sk.public_key().verify(sig[:-1]+bytes([sig[-1]^1]),b"")
except Exception as e: print("tampered:", type(e).__name__)
public: 5fd7449b59b461fd2ce787ec616ad46a1da1342485a70e1f8a0ea75d80e96778edf124769b46c7061bd6783df1e50f6cd1fa1abeafe8256180 57
sig : 533a37f6bbe457251f023c0d88f976ae2dfb504a843e34d2074fd823d41a591f2b233f034f628281f2fd7a22ddd47d7828c59bd0a21bfd3980ff0d2028d4b18a9df63e006c5d1c2d345b925d8dc00b4104852db99ac5c7cdda8530a113a0f4dbb61149f05a7363268c71d95808ff2e652600 114
verified
tampered: InvalidSignature
An Ed448 signature is 114 bytes, and its public and private keys are 57 bytes each. That is about 1.8 times the size of Ed25519, which has 64-byte signatures and 32-byte keys. Node.js reports the same sizes: 57 for the public key and 114 for the signature, using generateKeyPairSync with the type ed448.
Choose Ed25519 by default and Ed448 when a policy demands a higher security level. Ed25519 has about 128 bits of strength and Ed448 about 224. RFC 8032 says Ed448 is for applications with relaxed performance needs that want a hedge against attacks on elliptic curves. Both fall to a sufficiently large quantum computer. TLS 1.3 gives Ed448 the signature scheme code 0x0808, and RFC 8709 defines it for SSH.