# Sortix nightly manual

This manual documents Sortix nightly, a development build that has not been officially released. You can instead view this document in the latest official manual.

# NAME

**X25519**,

**X25519_keypair**,

**ED25519_keypair**,

**ED25519_sign**,

**ED25519_verify**— Elliptic Curve Diffie-Hellman and signature primitives based on Curve25519

# SYNOPSIS

**#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**() 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). 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}.`= 32`

bytes each.**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). 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*.

`= 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)*Cryptographic Hardware and Embedded Systems — CHES 2011*,

*Springer*,

*Lecture Notes in Computer Science*, vol 6917, https://doi.org/10.1007/978-3-642-23951-9_9, Nara, Japan, September 29, 2011.