# When using Curve25519, why does the private key always have a fixed bit at 2^254?

When using Curve25519, the private key always seems to have a fixed bit set at position $$2^{254}$$.

Why is that? Is there any good reason to use a fixed positioned most-significant-bit in the private key?

• You might consider choosing a different answer. I think there are better answers then "read the paper".
– user10496
Dec 15, 2018 at 19:44

Did you take a look at DjB's paper?

One of his design criterias in order to improve performance is "Use a fixed position for the leading 1 in the secret key".

The set of secret keys is defined to be $\{\underline{n} : n \in 2^{254} + 8\{0, 1, 2, 3,\ldots, 2^{251}-1\}\}$.

• That this answer is tautological. I read the paper including those paragraphs and still Why does having a fixed position for the leading 1 improve performance? I didn't notice an algorithm in the code that relies on this bit being set. Does the code produce incorrect results if this bit is wrong? Nov 20, 2013 at 13:12
• @CodesInChaos I just cited the paper to answer "why it is set to one" as it is listed as a design choice. I did not take a closer look at the arithmetic to find a justification. Nov 20, 2013 at 13:16
• @CodesInChaos I guess the answer is sufficient. The sentence "When using Curve25519, the private key always seems to have a fixed bit set at position 2^254." hints at a question about an implementation. The fact that this is hinted at in a paper is sufficient; why the paper specifies it as such is an interesting but different question. Nov 20, 2013 at 14:22
• The algorithm is intended to be used with mostly floating point operations, the fixed bit is probably there to prevent overflows or something... Nov 20, 2013 at 19:26
• @RichieFrame How would it prevent overflows?
– forest
Dec 9, 2018 at 7:56

Curve25519 was designed to take advantage of the Montgomery ladder, which combined with Montgomery curves forgoes the $Y$ coordinates, is side-channel resistant, and enables public keys to be any 255-bit string. The ladder looks something like this (pseudocode):

Q = P;
Q = 2*P;
for(int i = log2(exponent) - 2; i >= 0; --i)
{
Q[ bit(exponent, i)] = 2*Q[ bit(exponent, i)];
Q[!bit(exponent, i)] = Q + Q;
}
return Q;


You might notice the format of the loop: the counter is initialized with the index of the most significant bit of the exponent (i.e., the private key), and goes down to 0.

In practice, the first step of the ladder will be to find the most significant bit of the exponent. This is not hard, of course, but doing so may leak, through timing, information about the most significant bits of the exponent: exponents with bit 254 set to 0 will run faster than with that bit set to 1. This can lead to real problems.

Curve25519 completely avoids this problem by always setting the most significant bit to 1. This way, the loop always has the same amount of iterations, and no timing information can accidentally be leaked by the variable iteration count.

• Thanks for actually explainingthe underlying reasoning, rather than saying "because djb said so".
– orlp
Nov 21, 2013 at 8:39
• Sorry but I still don't get it. 1) The actual code starts with $P$ and $\infty = (x=1,z=0)$ 2) Why does the code not work if it always starts the ladder at bit 254, but that bit happens to be 0? Nov 21, 2013 at 8:55
• It is true that the reference code protects against this by starting with $(P, \infty)$; however, every textbook displays the version I described, so there's a good chance that an independent implementer could make that mistake. Setting that bit to 1 is a preventive measure that costs almost nothing. Nov 21, 2013 at 14:55
• @AndrewPoelstra You don't want to fix a bit (read: introduce a bias) in the nonce, precisely to avoid Bleichenbacher-style attacks. May 27, 2017 at 21:35
• @AndrewPoelstra It's certainly inconsistent, yes, but also note that the scalar multiplication here is by a fixed base point, unlike in the Diffie-Hellman case. This means that the algorithm used is most likely a comb, which will (likely) not leak the MSB in the same way a Montgomery ladder would. In any case, I suspect this was done in ed25519 more as a backwards-compatibility measure with curve25519 than anything else. May 28, 2017 at 12:19