---
name: "libressl-X25519"
section: "3"
platform: "linux"
package: "libressl"
version: "4.4.0-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/libressl-X25519"
---

# libressl-X25519(3)

Elliptic Curve Diffie-Hellman and signature primitives based on Curve25519

## NAME

**X25519**, **X25519\_keypair**, **ED25519\_keypair**, **ED25519\_sign**, **ED25519\_verify** – Elliptic Curve Diffie-Hellman and signature primitives based on Curve25519

## SYNOPSIS

Crypto Library (libcrypto, -lcrypto)

**#include \<openssl/curve25519.h\>**

*int*\

**X25519**(*uint8\_t out\_shared\_key\[X25519\_KEY\_LENGTH\]*, *const uint8\_t private\_key\[X25519\_KEY\_LENGTH\]*, *const uint8\_t peer\_public\_value\[X25519\_KEY\_LENGTH\]*);

*void*\

**X25519\_keypair**(*uint8\_t out\_public\_value\[X25519\_KEY\_LENGTH\]*, *uint8\_t out\_private\_key\[X25519\_KEY\_LENGTH\]*);

*void*\

**ED25519\_keypair**(*uint8\_t out\_public\_key\[ED25519\_PUBLIC\_KEY\_LENGTH\]*, *uint8\_t out\_private\_key\[ED25519\_PRIVATE\_KEY\_LENGTH\]*);

*int*\

**ED25519\_sign**(*uint8\_t \*out\_sig*, *const uint8\_t \*message*, *size\_t message\_len*, *const uint8\_t public\_key\[ED25519\_PUBLIC\_KEY\_LENGTH\]*, *const uint8\_t private\_key\_seed\[ED25519\_PRIVATE\_KEY\_LENGTH\]*);

*int*\

**ED25519\_verify**(*const uint8\_t \*message*, *size\_t message\_len*, *const uint8\_t signature\[ED25519\_SIGNATURE\_LENGTH\]*, *const uint8\_t public\_key\[ED25519\_PUBLIC\_KEY\_LENGTH\]*);

## DESCRIPTION

Curve25519 is an elliptic curve over a prime field specified in RFC 7748 section 4.1. The prime field is defined by the prime number 2^255 - 19.

X25519 is the Diffie-Hellman primitive built from Curve25519 as described in RFC 7748 section 5. Section 6.1 describes the intended use in an Elliptic Curve Diffie-Hellman (ECDH) protocol.

**X25519**() writes a shared key to *out\_shared\_key* that is calculated from the given *private\_key* and the *peer\_public\_value* by scalar multiplication. Do not use the shared key directly, rather use a key derivation function and also include the two public values as inputs.

**X25519\_keypair**() sets *out\_public\_value* and *out\_private\_key* to a freshly generated public/private key pair. First, the *out\_private\_key* is generated with [arc4random\_buf(3)](/arc4random_buf/3.md). Then, the opposite of the masking described in RFC 7748 section 5 is applied to it to make sure that the generated private key is never correctly masked. The purpose is to cause incorrect implementations on the peer side to consistently fail. Correct implementations will decode the key correctly even when it is not correctly masked. Finally, the *out\_public\_value* is calculated from the *out\_private\_key* by multiplying it with the Montgomery base point *uint8\_t* *u\[32\]* = {9}.

The size of a public and private key is X25519\_KEY\_LENGTH = 32 bytes each.

Ed25519 is a signature scheme using a twisted Edwards curve that is birationally equivalent to Curve25519.

**ED25519\_keypair**() sets *out\_public\_key* and *out\_private\_key* to a freshly generated public/private key pair. First, the *out\_private\_key* is generated with [arc4random\_buf(3)](/arc4random_buf/3.md). Then, the *out\_public\_key* is calculated from the private key.

**ED25519\_sign**() signs the *message* of *message\_len* bytes using the *public\_key* and the *private\_key* and writes the signature to *out\_sig*.

**ED25519\_verify**() checks that signing the *message* of *message\_len* bytes using the *public\_key* would indeed result in the given *signature*.

The sizes of a public and private keys are ED25519\_PUBLIC\_KEY\_LENGTH and ED25519\_PRIVATE\_KEY\_LENGTH, which are both 32 bytes, and the size of a signature is ED25519\_SIGNATURE\_LENGTH = 64 bytes.

## RETURN VALUES

**X25519**() and **ED25519\_sign**() return 1 on success or 0 on error. **X25519**() can fail if the input is a point of small order. **ED25519\_sign**() always succeeds in LibreSSL, but the API reserves the return value 0 for memory allocation failure.

**ED25519\_verify**() returns 1 if the *signature* is valid or 0 otherwise.

## SEE ALSO

ECDH\_compute\_key(3), EVP\_DigestSign(3), EVP\_DigestVerify(3), EVP\_PKEY\_derive(3), EVP\_PKEY\_keygen(3) Daniel J. Bernstein, A state-of-the-art Diffie-Hellman function: How do I use Curve25519 in my own software?, https://cr.yp.to/ecdh.html. Daniel J. Bernstein, Niels Duif, Tanja Lange, Peter Schwabe, and Bo-Yin Yang, “High-Speed High-Security Signatures”, *Cryptographic Hardware and Embedded Systems — CHES 2011*, *Lecture Notes in Computer Science*, Springer, vol 6917, Nara, Japan, September 29, 2011, https://doi.org/10.1007/978-3-642-23951-9\_9.

## STANDARDS

RFC 7748: Elliptic Curves for Security

RFC 8032: Edwards-Curve Digital Signature Algorithm (EdDSA)
