]>
Curve25519 for ephemeral key exchange
in Transport Layer Security (TLS)
SJD ABsimon@josefsson.orgIndependent / PolarSSLmpg@elzevir.frTLS, Elliptic Curve Cryptography, Diffie-Hellman,
Curve25519This document specifies the use of Curve25519 for ephemeral key
exchange in the Transport Layer Security (TLS) protocol, as well
as its DTLS variant. It updates RFC 5246 (TLS 1.2) and RFC 4492
(Elliptic Curve Cryptography for TLS).In , a new elliptic curve
function for use in cryptographic applications was specified.
Curve25519 is a Diffie-Hellman function designed with
performance and security in mind. defines the usage of elliptic
curves for authentication and key agreement in TLS 1.0 and TLS
1.1, and these mechanisms are also applicable to TLS 1.2 . The use of ECC curves for key exchange
requires the definition and assignment of additional NamedCurve
IDs. This document specify that value for Curve25519, as well
as the minor changes in key selection and representation that
are required to accommodate for Curve25519's slightly different
nature.This document only describes usage of Curve25519 for ephemeral
key exchange (ECDHE). It does not define its use for signature,
since the primitive considered here is a Diffie-Hellman
function; the related signature scheme, Ed25519, is outside the
scope of this document. The use of Curve25519 with long-term
keys embedded in X.509 certificates is also out of scope
here.The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described
in .All cryptographic computations are done using the Curve25519
function defined in . In this memo,
this function is considered as a black box that takes as input
a (secret key, public key) pair and outputs a public key.
Public keys are defined as strings of 32 bytes. Secret keys are
defined as 255 bits numbers such as the high-order bit (bit
254) is set, and the three lowest-order bits are unset. In
addition, a common public key, denoted by G, is shared by
all users.An ECDHE key exchange using Curve25519 goes as follows. Each
party picks a secret key d uniformly at random and computes the
corresponding public key x = Curve25519(d, G). Parties exchange
their public keys (see ) and
compute a shared secret as x_S = Curve25519(d, x_peer). This
shared secret is used directly as the premaster secret, which
is always exactly 32 bytes when ECDHE with Curve25519 is
used.A complete description of the Curve25519 function, as well as
a few implementation notes, are provided in .Curve negotiation uses the mechanisms introduced by , without modification except the
following restriction: in the ECParameters structure, only
the named_curve case can be used with Curve25519.
Accordingly, arbitrary_explicit_prime_curves in the Supported
Curves extension does not imply support for Curve25519, even
though the Curve25519 function happens to be defined using
an elliptic curve over a prime field.The reason for this restriction is that explicit_prime is
only suited to the so-called Short Weierstrass representation
of elliptic curves, while Curve25519 uses a different
representation for performance and security reasons.This document adds a new NamedCurve value for Curve25519 as
follows.Curve25519 is suitable for use with DTLS .Since Curve25519 is not designed to be used in signatures,
clients who offer ECDHE_ECDSA ciphersuites and advertise
support for Curve25519 in the elliptic_curves ClientHello
extension SHOULD also advertise support for at least one
curve suitable for ECDSA. Servers MUST NOT select an
ECDHE_ECDSA ciphersuite if there are no common curves
suitable for ECDSA.This section defines a new point format suitable to
encode Curve25519 public keys, as well as an identifier to
negotiate this new format in TLS, and includes guidance on
their use.The curves defined in define a
public key as a point on the curve. In order to exchange
public keys, the points are serialized as a string of bytes
using one of the formats defined in .
These encodings begin with a leading byte identifying the
format, followed by a string of bytes, whose length is
uniquely determined by the leading byte and curve used.Since Curve25519 public keys already are string of bytes,
no serialization is needed. However, a leading byte with value
0x41 is prepended to the public key to identify the format.
The goal, besides consistency with the SEC1 formats, is to
allow using other formats with Curve25519 in the future if
needed.In order to negotiate this format in TLS, a new ECPointFormat
is defined as follows.This format is currently the only format defined for use with
Curve25519. Clients offering Curve25519 in the Supported
Elliptic Curves extension MUST also offer montgomery_x_le in
the Supported Point Format extension. Servers selecting
Curve25519 for key exchange MUST include montgomery_x_le in
their Supported Point Format extension. Servers willing to use
Curve25519 MUST NOT assume that the client supports the
montgomery_x_le format if the client did not advertise it
explicitly.When included in a ServerKeyExchange or ClientKeyExchange
message, the public key is wrapped in an ECPoint structure as
defined in , whose payload is as
described above. For example, a public key with value 2A ...
2A appears on the wire as follows (including the length byte
of ECPoint.point).With the curves defined by , each
party must validate the public key sent by its peer before
performing cryptographic computations with it. Failing to do
so allows attackers to gain information about the private key,
to the point that they may recover the entire private key in a
few requests, if that key is not really ephemeral.Curve25519 was designed in a way that the result of
Curve25519(x, d) will never reveal information about d,
provided is was chosen as prescribed, for any value of x.Let's define legitimate values of x as the values that can be
obtained as x = Curve25519(G, d') for some d, and call the
other values illegitimate. The definition of the Curve25519
function shows that legitimate values all share the following
property: the high-order bit of the last byte is not set.Since there are some implementation of the Curve25519
function that impose this restriction on their input and
others that don't, implementations of Curve25519 in TLS SHOULD
reject public keys when the high-order bit of the last byte is
set (in other words, when the value of the leftmost byte is
greater than 0x7F) in order to prevent implementation
fingerprinting.Other than this recommended check, implementations do not
need to ensure that the public keys they receive are
legitimate: this is not necessary for security with
Curve25519.IANA is requested to assign numbers for Curve25519 listed in
to the Transport Layer Security
(TLS) Parameters registry EC Named Curve as follows. ValueDescriptionDTLS-OKReferenceTBD1Curve25519YThis docIANA is also requested to assign numbers for Curve25519 listed in
to the Transport Layer Security
(TLS) Parameters registry EC Point Format as follows. ValueDescriptionDTLS-OKReferenceTBD2montgomery_x_leYThis docThe security considerations of and
most of the security considerations of
apply accordingly.Curve25519 is designed to facilitate the production of
high-performance constant-time implementations of the Curve25519
function. Implementors are encouraged to use a constant-time
implementation of the Curve25519 function. This point is of
crucial importance if the implementation chooses to reuse its
supposedly ephemeral key pair for many key exchanges, which some
implementations do in order to improve performance.Curve25519 is believed to be at least as secure as
the secp256r1 curve defined in , also know as NIST P-256. While the NIST
curves are advertised as being chosen verifiably at random, there
is no explanation for the seeds used to generate them. In
contrast, the process used to pick Curve25519 is fully documented
and rigid enough so that independent verification has been done.
This is widely seen as a security advantage for Curve25519, since
it prevents the generating party from maliciously manipulating
the parameters.Another family of curves available in TLS, generated in a fully
verifiable way, is the Brainpool curves . Specifically, brainpoolP256 is expected to provide a level
of security comparable to Curve25519 and NIST P-256. However,
due to the use of pseudo-random prime, it is significantly
slower than NIST P-256, which is itself slower than Curve25519.See for more comparisons between
curves.Several people provided comments and suggestions that helped
improve this document: Kurt Roeckx, Andrey Jivsov, Robert
Ransom, Rich Salz, David McGrew.
Curve25519: New Diffie-Hellman Speed Records
&rfc2119;
&rfc4492;
&rfc5246;
&rfc6347;
Transport Layer Security (TLS) ParametersInternet Assigned Numbers AuthoritySafeCurves: choosing safe curves for elliptic-curve
cryptography.
&rfc7027;
Standards for Efficient Cryptography (SEC) 1Explicit-Formulas Database: XZ coordinates for
Montgomery curvesCryptography in NaCLThis section completes by defining
the Curve25519 function and the common public key G.
It is meant as an alternative, self-contained specification
for the Curve25519 function, possibly easier to follow than
the original paper for most implementors.Throughout this section, P denotes the integer 2^255-19 =
0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED.
The letters X and Z, and their numbered variants such as x1,
z2, etc. denote integers modulo P, that is integers
between 0 and P-1 and every operation between them is
implictly done modulo P. For addition, subtraction and
multiplication this means doing the operation in the usual
way and then replacing the result with the remainder of its
division by P. For division, "X / Z" means mutliplying (mod P) X
by the modular inverse of Z mod P.A convenient way to define the modular inverse of Z mod P is
as Z^(P-2) mod P, that is Z to the power of 2^255-21 mod P. It
is also a practical way of computing it, using a
square-and-multiply method.The four operations +, -, *, / modulo P are known as the
field operations. Techniques for efficient implementation
of the field operations are outside the scope of this
document.For the purpose of this section, we will define a
Curve25519 point as a pair (X, Z) were X and Z are integers
mod P (as defined above). Though public keys were defined to
be strings of 32 bytes, internally they are represented as
curve points. This subsection describes the conversion
process as two functions: PubkeyToPoint and PointToPubkey.We first introduce the DoubleAndAdd function, defined as
follows (formulas taken from ).This may be taken as the abstract definition of an
arbitrary-looking function. However, let's mention "the true
meaning" of this function, without justification, in order
to help the reader make more sense of it. It is possible to
define operations "+" and "-" between Curve25519 points.
Then, assuming (X2, Z2) - (X3, Z3) = (X1, 1), the
DoubleAndAdd function returns points such that (X4, Z4) =
(X2, Z2) + (X2, Z2) and (X5, Z5) = (X2, Z2) + (X3, Z3).Taking the "+" operation as granted, we can define
multiplication of a Curve25519 point by a positive integer
as N * (X, Z) = (X, Z) + ... + (X, Z), with N point
additions. It is possible to compute this operation, known
as scalar multiplication, using an algorithm called the
Montgomery ladder, as follows.We are now ready to define the Curve25519 function
itself.The common public key G mentioned in the first paragraph of
is defined as G = PointToPubkey((9,
1).The following test vectors are taken from . Compared to this reference, the private key strings
have been applied the ClampC function of the reference and
converted to integers in order to fit the description given in
and the present memo.The secret key of party A is denoted by S_a, it public key by
P_a, and similarly for party B. The shared secret is SS.Curve25519 was specifically designed so that correct, fast,
constant-time implementations are easier to produce. In
particular, using a Montgomery ladder as described in the
previous section ensures that, for any valid value of the
secret key, the same sequence of field operations are
performed, which eliminates a major source of side-channel
leakage.However, merely using Curve25519 with a Montgomery ladder does
not prevent all side-channels by itself, and some point are the
responsibility of implementors:
In step 3 of SclarMult, avoid branches depending on
b_i, as well as memory access patterns depending on b_i,
for example by using safe conditional swaps on the inputs
and outputs of DoubleAndAdd.Avoid data-dependant branches and memory access patterns
in the implementation of field operations.Techniques for implementing the field operations in constant
time and with high performance are out of scope of this
document. Let's mention however that, provided constant-time
multiplication is available, division can be computed in
constant time using exponentiation as described in .If using constant-time implementations of the field
operations is not convenient, an option to reduce the
information leaked this way is to replace step 2 of the
SclarMult function with:This method is known as randomizing projective coordinates.
However, it is no guaranteed to avoid all side-channel leaks
related to field operations.Side-channel attacks are an active reseach domain that still
sees new significant results, so implementors of the
Curve25519 function are advised to follow recent security
research closely.