3 Arithmetic and tables for curve25519,
5 Copyright (C) 2014 Niels Möller
7 This file is part of GNU Nettle.
9 GNU Nettle is free software: you can redistribute it and/or
10 modify it under the terms of either:
12 * the GNU Lesser General Public License as published by the Free
13 Software Foundation; either version 3 of the License, or (at your
14 option) any later version.
18 * the GNU General Public License as published by the Free
19 Software Foundation; either version 2 of the License, or (at your
20 option) any later version.
22 or both in parallel, as here.
24 GNU Nettle is distributed in the hope that it will be useful,
25 but WITHOUT ANY WARRANTY; without even the implied warranty of
26 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 General Public License for more details.
29 You should have received copies of the GNU General Public License and
30 the GNU Lesser General Public License along with this program. If
31 not, see http://www.gnu.org/licenses/.
40 #include "ecc-internal.h"
44 #include "ecc-curve25519.h"
46 #define PHIGH_BITS (GMP_NUMB_BITS * ECC_LIMB_SIZE - 255)
48 #if HAVE_NATIVE_ecc_curve25519_modp
50 #define ecc_curve25519_modp _nettle_ecc_curve25519_modp
52 ecc_curve25519_modp (const struct ecc_modulo
*m
, mp_limb_t
*rp
, mp_limb_t
*xp
);
56 #error Unsupported limb size */
60 ecc_curve25519_modp(const struct ecc_modulo
*m UNUSED
, mp_limb_t
*rp
, mp_limb_t
*xp
)
64 cy
= mpn_addmul_1 (xp
, xp
+ ECC_LIMB_SIZE
, ECC_LIMB_SIZE
,
65 (mp_limb_t
) 19 << PHIGH_BITS
);
66 hi
= xp
[ECC_LIMB_SIZE
-1];
67 cy
= (cy
<< PHIGH_BITS
) + (hi
>> (GMP_NUMB_BITS
- PHIGH_BITS
));
68 rp
[ECC_LIMB_SIZE
-1] = (hi
& (GMP_NUMB_MASK
>> PHIGH_BITS
))
69 + sec_add_1 (rp
, xp
, ECC_LIMB_SIZE
- 1, 19 * cy
);
71 #endif /* HAVE_NATIVE_ecc_curve25519_modp */
73 #define QHIGH_BITS (GMP_NUMB_BITS * ECC_LIMB_SIZE - 252)
76 #error Unsupported limb size */
80 ecc_curve25519_modq (const struct ecc_modulo
*q
, mp_limb_t
*rp
, mp_limb_t
*xp
)
85 /* n is the offset where we add in the next term */
86 for (n
= ECC_LIMB_SIZE
; n
-- > 0;)
88 cy
= mpn_submul_1 (xp
+ n
,
89 q
->B_shifted
, ECC_LIMB_SIZE
,
90 xp
[n
+ ECC_LIMB_SIZE
]);
91 /* Top limb of mBmodq_shifted is zero, so we get cy == 0 or 1 */
92 assert_maybe (cy
< 2);
93 mpn_cnd_add_n (cy
, xp
+n
, xp
+n
, q
->m
, ECC_LIMB_SIZE
);
96 cy
= mpn_submul_1 (xp
, q
->m
, ECC_LIMB_SIZE
,
97 xp
[ECC_LIMB_SIZE
-1] >> (GMP_NUMB_BITS
- QHIGH_BITS
));
98 assert_maybe (cy
< 2);
99 mpn_cnd_add_n (cy
, rp
, xp
, q
->m
, ECC_LIMB_SIZE
);
102 /* Computes a^{(p-5)/8} = a^{2^{252}-3} mod m. Needs 4 * n scratch
105 ecc_mod_pow_252m3 (const struct ecc_modulo
*m
,
106 mp_limb_t
*rp
, const mp_limb_t
*ap
, mp_limb_t
*scratch
)
109 #define t0 (scratch + ECC_LIMB_SIZE)
110 #define tp (scratch + 2*ECC_LIMB_SIZE)
112 /* a^{2^252 - 3} = a^{(p-5)/8}, using the addition chain
116 = 1 + 4 (2^125+1)(2^125-1)
117 = 1 + 4 (2^125+1)(1+2(2^124-1))
118 = 1 + 4 (2^125+1)(1+2(2^62+1)(2^62-1))
119 = 1 + 4 (2^125+1)(1+2(2^62+1)(2^31+1)(2^31-1))
120 = 1 + 4 (2^125+1)(1+2(2^62+1)(2^31+1)(7+8(2^28-1)))
121 = 1 + 4 (2^125+1)(1+2(2^62+1)(2^31+1)(7+8(2^14+1)(2^14-1)))
122 = 1 + 4 (2^125+1)(1+2(2^62+1)(2^31+1)(7+8(2^14+1)(2^7+1)(2^7-1)))
123 = 1 + 4 (2^125+1)(1+2(2^62+1)(2^31+1)(7+8(2^14+1)(2^7+1)(1+2(2^6-1))))
124 = 1 + 4 (2^125+1)(1+2(2^62+1)(2^31+1)(7+8(2^14+1)(2^7+1)(1+2(2^3+1)*7)))
127 ecc_mod_pow_2kp1 (m
, a7
, ap
, 1, tp
); /* a^3 */
128 ecc_mod_sqr (m
, a7
, a7
, tp
); /* a^6 */
129 ecc_mod_mul (m
, a7
, a7
, ap
, tp
); /* a^7 */
130 ecc_mod_pow_2kp1 (m
, rp
, a7
, 3, tp
); /* a^63 = a^{2^6-1} */
131 ecc_mod_sqr (m
, rp
, rp
, tp
); /* a^{2^7-2} */
132 ecc_mod_mul (m
, rp
, rp
, ap
, tp
); /* a^{2^7-1} */
133 ecc_mod_pow_2kp1 (m
, t0
, rp
, 7, tp
); /* a^{2^14-1}*/
134 ecc_mod_pow_2kp1 (m
, rp
, t0
, 14, tp
); /* a^{2^28-1} */
135 ecc_mod_sqr (m
, rp
, rp
, tp
); /* a^{2^29-2} */
136 ecc_mod_sqr (m
, rp
, rp
, tp
); /* a^{2^30-4} */
137 ecc_mod_sqr (m
, rp
, rp
, tp
); /* a^{2^31-8} */
138 ecc_mod_mul (m
, rp
, rp
, a7
, tp
); /* a^{2^31-1} */
139 ecc_mod_pow_2kp1 (m
, t0
, rp
, 31, tp
); /* a^{2^62-1} */
140 ecc_mod_pow_2kp1 (m
, rp
, t0
, 62, tp
); /* a^{2^124-1}*/
141 ecc_mod_sqr (m
, rp
, rp
, tp
); /* a^{2^125-2} */
142 ecc_mod_mul (m
, rp
, rp
, ap
, tp
); /* a^{2^125-1} */
143 ecc_mod_pow_2kp1 (m
, t0
, rp
, 125, tp
);/* a^{2^250-1} */
144 ecc_mod_sqr (m
, rp
, t0
, tp
); /* a^{2^251-2} */
145 ecc_mod_sqr (m
, rp
, rp
, tp
); /* a^{2^252-4} */
146 ecc_mod_mul (m
, rp
, rp
, ap
, tp
); /* a^{2^252-3} */
152 /* Scratch as for ecc_mod_pow_252m3 above. */
153 #define ECC_25519_INV_ITCH (4*ECC_LIMB_SIZE)
156 ecc_curve25519_inv (const struct ecc_modulo
*p
,
157 mp_limb_t
*rp
, const mp_limb_t
*ap
,
163 = 1 + 2 (1 + 4 (2^{252}-3))
165 ecc_mod_pow_252m3 (p
, rp
, ap
, scratch
);
166 ecc_mod_sqr (p
, rp
, rp
, scratch
);
167 ecc_mod_sqr (p
, rp
, rp
, scratch
);
168 ecc_mod_mul (p
, rp
, ap
, rp
, scratch
);
169 ecc_mod_sqr (p
, rp
, rp
, scratch
);
170 ecc_mod_mul (p
, rp
, ap
, rp
, scratch
);
174 ecc_curve25519_zero_p (const struct ecc_modulo
*p
, mp_limb_t
*xp
)
176 /* First, reduce to < 2p. */
178 mp_limb_t hi
= xp
[ECC_LIMB_SIZE
-1];
179 xp
[ECC_LIMB_SIZE
-1] = (hi
& (GMP_NUMB_MASK
>> PHIGH_BITS
))
180 + sec_add_1 (xp
, xp
, ECC_LIMB_SIZE
- 1, 19 * (hi
>> (GMP_NUMB_BITS
- PHIGH_BITS
)));
183 return ecc_mod_zero_p (p
, xp
);
186 /* Compute x such that x^2 = u/v (mod p). Returns one on success, zero
187 on failure. We use the e = 2 special case of the Shanks-Tonelli
188 algorithm (see http://www.math.vt.edu/people/brown/doc/sqrts.pdf,
189 or Henri Cohen, Computational Algebraic Number Theory, 1.5.1).
191 To avoid a separate inversion, we also use a trick of djb's, to
192 compute the candidate root as
194 x = (u/v)^{(p+3)/8} = u v^3 (u v^7)^{(p-5)/8}.
197 #error Broken curve25519 parameters
200 /* Needs 2*n space + scratch for ecc_mod_pow_252m3. */
201 #define ECC_25519_SQRT_RATIO_ITCH (6*ECC_LIMB_SIZE)
204 ecc_curve25519_sqrt_ratio(const struct ecc_modulo
*p
, mp_limb_t
*rp
,
205 const mp_limb_t
*up
, const mp_limb_t
*vp
,
211 #define uv7 (scratch + ECC_LIMB_SIZE)
217 #define scratch_out (scratch + 2 * ECC_LIMB_SIZE)
220 #define vx2 (scratch + ECC_LIMB_SIZE)
221 #define t0 (scratch + 2*ECC_LIMB_SIZE)
224 ecc_mod_sqr (p
, v2
, vp
, scratch_out
); /* v2 */
225 ecc_mod_mul (p
, uv
, up
, vp
, scratch_out
); /* uv, v2 */
226 ecc_mod_mul (p
, uv3
, uv
, v2
, scratch_out
); /* uv3, v2 */
227 ecc_mod_sqr (p
, v4
, v2
, scratch_out
); /* uv3, v4 */
228 ecc_mod_mul (p
, uv7
, uv3
, v4
, scratch_out
); /* uv7 */
229 ecc_mod_pow_252m3 (p
, rp
, uv7
, scratch_out
); /* uv3, uv7p */
230 ecc_mod_mul (p
, rp
, rp
, uv3
, scratch_out
); /* none */
232 /* Check sign. If square root exists, have v x^2 = ±u */
233 ecc_mod_sqr (p
, x2
, rp
, t0
);
234 ecc_mod_mul (p
, vx2
, x2
, vp
, t0
);
235 ecc_mod_add (p
, t0
, vx2
, up
);
236 neg
= ecc_curve25519_zero_p (p
, t0
);
237 ecc_mod_sub (p
, t0
, up
, vx2
);
238 pos
= ecc_curve25519_zero_p (p
, t0
);
240 ecc_mod_mul (p
, t0
, rp
, ecc_sqrt_z
, t0
);
241 cnd_copy (neg
, rp
, t0
, ECC_LIMB_SIZE
);
255 const struct ecc_curve _nettle_curve25519
=
264 ECC_25519_SQRT_RATIO_ITCH
,
277 ecc_curve25519_sqrt_ratio
,
284 ECC_MOD_INV_ITCH (ECC_LIMB_SIZE
),
290 ecc_mBmodq_shifted
, /* Use q - 2^{252} instead. */
306 ECC_ADD_TH_ITCH (ECC_LIMB_SIZE
),
307 ECC_ADD_THH_ITCH (ECC_LIMB_SIZE
),
308 ECC_DUP_TH_ITCH (ECC_LIMB_SIZE
),
309 ECC_MUL_A_EH_ITCH (ECC_LIMB_SIZE
),
310 ECC_MUL_G_EH_ITCH (ECC_LIMB_SIZE
),
311 ECC_EH_TO_A_ITCH (ECC_LIMB_SIZE
, ECC_25519_INV_ITCH
),
320 ecc_b
, /* Edwards curve constant. */