User Rating 0.0 โ˜…โ˜…โ˜…โ˜…โ˜…
Total Usage 0 times
Category Security
64 hex characters representing 32 bytes
64 hex chars (seed only) or 128 hex chars (seed + public key)
Curve25519 Public Key
Curve25519 Secret Key
Is this tool helpful?

Your feedback helps us improve.

โ˜… โ˜… โ˜… โ˜… โ˜…

About

Ed25519 and Curve25519 share the same underlying finite field GF(2255 โˆ’ 19) but operate on birationally equivalent curves. Ed25519 uses a twisted Edwards curve for signatures. Curve25519 uses a Montgomery curve for Diffie-Hellman key exchange. Converting between them avoids distributing two separate public keys (saving 32 bytes), but no formal proof exists that reusing a single keypair across both protocols is universally safe. This tool performs the birational map on public keys and the SHA-512 clamping procedure on secret keys entirely client-side. No key material leaves your browser. The field arithmetic implements the full TweetNaCl limb representation with 16-element integer arrays and modular inversion via Fermat's little theorem.

Incorrect key conversion breaks encryption silently. A single flipped bit in the field inversion produces a valid-looking but wrong Curve25519 key, meaning messages encrypted to it are irrecoverable. This tool validates Ed25519 point decompression and rejects keys that do not lie on the curve. It handles the edge case where the input y-coordinate yields a non-square x2, returning an explicit error rather than garbage output. The conversion is compatible with libsodium, TweetNaCl, and agl/extra25519 implementations.

ed25519 curve25519 key-converter nacl diffie-hellman cryptography tweetnacl elliptic-curve

Formulas

The public key conversion decompresses the Ed25519 point and applies the Edwards-to-Montgomery birational equivalence.

Given compressed Ed25519 public key encoding y with sign bit s, recover x:

x2 = y2 โˆ’ 1d โ‹… y2 + 1

where d = โˆ’121665121666 โˆˆ GF(p)

Square root via x = (x2)p + 38 with conditional multiply by โˆšโˆ’1

Then the Montgomery u-coordinate:

u = 1 + y1 โˆ’ y โˆˆ GF(p)

The secret key conversion applies SHA-512 hashing followed by bit clamping.

h = SHA512(seed[0..31])

h[0] = h[0] โˆง 248

h[31] = h[31] โˆง 127

h[31] = h[31] โˆจ 64

curveSecretKey = h[0..31]

Where p = 2255 โˆ’ 19, seed is the first 32 bytes of the Ed25519 secret key, y is the decoded Edwards y-coordinate from the compressed public key, d is the Edwards curve constant, and u is the resulting Curve25519 u-coordinate (the output public key).

Reference Data

PropertyEd25519 (Edwards)Curve25519 (Montgomery)
Curve typeTwisted EdwardsMontgomery
Equationโˆ’x2 + y2 = 1 + dx2y2v2 = u3 + 486662u2 + u
Field prime p2255 โˆ’ 19
Group order2252 + 27742317777372353535851937790883648493
Cofactor8
Key size (public)32 bytes32 bytes
Key size (secret)64 bytes (seed + pub)32 bytes
Primary useDigital signaturesKey exchange (ECDH)
Coordinate systemExtended (x, y)Montgomery u-coordinate
Compressed point encodingy-coord + sign bit of xu-coord (little-endian)
Constant dโˆ’121665 รท 121666N/A
Birational map (pub)u = (1 + y) โ‹… (1 โˆ’ y)โˆ’1
Secret key transformSHA-512 of seed, take first 32 bytes, clamp
Clamping (secret)Clear bits 0,1,2; clear bit 255; set bit 254
Compatible librariesTweetNaCl, libsodium, agl/extra25519, Chaos.NaCl
Incompatible approachtrevp/curve_sigs (converts opposite direction, stores sign bit in signature)
Security caveatNo formal proof of cross-protocol safety exists
Standard referenceRFC 8032RFC 7748

Frequently Asked Questions

Not every 32-byte string is a valid Ed25519 public key. The bytes encode a compressed Edwards point (y-coordinate plus sign bit). During decompression, the tool computes xยฒ = (yยฒ โˆ’ 1) / (dยทyยฒ + 1) in GF(2ยฒโตโต โˆ’ 19). If the result is a quadratic non-residue (no square root exists in the field), the input does not represent a point on the Edwards curve and conversion is impossible. The tool returns null and displays an error rather than producing an incorrect Curve25519 key.
There is currently no formal cryptographic proof that reusing a single Ed25519 keypair for both EdDSA signatures and Curve25519 ECDH is safe. The conversion is mathematically correct and widely used (libsodium, Signal Protocol), but a theoretical cross-protocol attack could potentially exist. For high-security applications, distribute both a 32-byte Ed25519 public key and a separate 32-byte Curve25519 public key (64 bytes total).
Clamping modifies three bit positions in the hashed secret key. Clearing the lowest 3 bits (AND 248) ensures the scalar is a multiple of 8, which matches the cofactor and prevents small-subgroup attacks. Clearing bit 255 (AND 127) keeps the scalar below the field prime. Setting bit 254 (OR 64) ensures constant-time ladder computation by guaranteeing the scalar has a fixed bit length. Without clamping, the Curve25519 scalar multiplication may leak timing information or produce points in a small subgroup.
Yes. This tool implements the identical birational map used by libsodium, TweetNaCl, agl/extra25519 (Go), Chaos.NaCl (C#), and nightcracker/ed25519 (C). The output bytes are interchangeable. Note that trevp/curve_sigs uses an incompatible approach that converts in the opposite direction and stores the sign bit differently.
Yes. The Ed25519 secret key in NaCl is 64 bytes: the first 32 bytes are the seed, and the last 32 bytes are the public key appended for convenience. The secret key conversion only uses the first 32-byte seed (it hashes this seed with SHA-512 and clamps the result). You may input either 32 or 64 bytes for the secret key. If you provide 64, only the first 32 are used.
The field GF(2ยฒโตโต โˆ’ 19) uses a limb representation: each field element is stored as an array of 16 integers, each holding approximately 16 bits. Multiplication uses schoolbook O(nยฒ) with carry propagation. Inversion uses Fermat's little theorem: aโปยน = a^(pโˆ’2) mod p, computed via a carefully optimized addition chain of squarings and multiplications totaling 254 squarings and 11 multiplications. No big-integer library is needed because the limb arithmetic stays within JavaScript's safe integer range.