]> git.ipfire.org Git - thirdparty/nettle.git/blame - ecc-curve448.c
Avoid warnings for assert_maybe.
[thirdparty/nettle.git] / ecc-curve448.c
CommitLineData
abfaf8be 1/* ecc-curve448.c
389c787e
DU
2
3 Arithmetic and tables for curve448,
4
5 Copyright (C) 2017 Daiki Ueno
6 Copyright (C) 2017 Red Hat, Inc.
7
8 This file is part of GNU Nettle.
9
10 GNU Nettle is free software: you can redistribute it and/or
11 modify it under the terms of either:
12
13 * the GNU Lesser General Public License as published by the Free
14 Software Foundation; either version 3 of the License, or (at your
15 option) any later version.
16
17 or
18
19 * the GNU General Public License as published by the Free
20 Software Foundation; either version 2 of the License, or (at your
21 option) any later version.
22
23 or both in parallel, as here.
24
25 GNU Nettle is distributed in the hope that it will be useful,
26 but WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 General Public License for more details.
29
30 You should have received copies of the GNU General Public License and
31 the GNU Lesser General Public License along with this program. If
32 not, see http://www.gnu.org/licenses/.
33*/
34
35#if HAVE_CONFIG_H
36# include "config.h"
37#endif
38
2bea3db4
NM
39#include <assert.h>
40
389c787e
DU
41#include "ecc-internal.h"
42
43#define USE_REDC 0
44
abfaf8be 45#include "ecc-curve448.h"
389c787e 46
d13bb312 47#if HAVE_NATIVE_ecc_curve448_modp
0a5e2524 48#define ecc_curve448_modp _nettle_ecc_curve448_modp
d13bb312 49void
f4f5625e 50ecc_curve448_modp (const struct ecc_modulo *m, mp_limb_t *rp, mp_limb_t *xp);
d13bb312 51#elif GMP_NUMB_BITS == 64
2bea3db4 52static void
f4f5625e 53ecc_curve448_modp(const struct ecc_modulo *m, mp_limb_t *rp, mp_limb_t *xp)
2bea3db4
NM
54{
55 /* Let B = 2^64, b = 2^32 = sqrt(B).
56 p = B^7 - b B^3 - 1 ==> B^7 = b B^3 + 1
57
58 We use this to reduce
59
60 {r_{13}, ..., r_0} =
61 {r_6,...,r_0}
62 + {r_{10},...,r_7}
63 + 2 {r_{13},r_{12}, r_{11}} B^4
64 + b {r_{10},...,r_7,r_{13},r_{12},r_{11} (mod p)
65
66 or
67
68 +----+----+----+----+----+----+----+
69 |r_6 |r_5 |r_4 |r_3 |r_2 |r_1 |r_0 |
70 +----+----+----+----+----+----+----+
71 |r_10|r_9 |r_8 |r_7 |
72 +----+----+----+----+----+----+----+
73 2 * |r_13|r_12|r_11|
74 +----+----+----+----+----+----+----+
75 + b * |r_10|r_9 |r_8 |r_7 |r_13|r_12|r_11|
76 -------+----+----+----+----+----+----+----+
77 c_7 |r_6 |r_5 |r_4 |r_3 |r_2 |r_1 |r_0 |
78 +----+----+----+----+----+----+----+
79 */
80 mp_limb_t c3, c4, c7;
f4f5625e 81 mp_limb_t *tp = xp + 7;
2bea3db4 82
f4f5625e
NM
83 c4 = mpn_add_n (xp, xp, xp + 7, 4);
84 c7 = mpn_addmul_1 (xp + 4, xp + 11, 3, 2);
85 c3 = mpn_addmul_1 (xp, xp + 11, 3, (mp_limb_t) 1 << 32);
86 c7 += mpn_addmul_1 (xp + 3, xp + 7, 4, (mp_limb_t) 1 << 32);
2bea3db4
NM
87 tp[0] = c7;
88 tp[1] = tp[2] = 0;
89 tp[3] = c3 + (c7 << 32);
90 tp[4] = c4 + (c7 >> 32) + (tp[3] < c3);
91 tp[5] = tp[6] = 0;
f4f5625e 92 c7 = mpn_add_n (rp, xp, tp, 7);
2f3c633e 93 c7 = mpn_cnd_add_n (c7, rp, rp, m->B, 7);
0404c147 94 assert_maybe (c7 == 0);
2bea3db4
NM
95}
96#else
0a5e2524 97#define ecc_curve448_modp ecc_mod
2bea3db4
NM
98#endif
99
1492e9d6 100/* Computes a^{(p-3)/4} = a^{2^446-2^222-1} mod m. Needs 4 * n scratch
389c787e
DU
101 space. */
102static void
103ecc_mod_pow_446m224m1 (const struct ecc_modulo *p,
104 mp_limb_t *rp, const mp_limb_t *ap,
105 mp_limb_t *scratch)
106{
b641a4b8 107/* Note overlap: operations writing to t0 clobber t1. */
389c787e 108#define t0 scratch
1492e9d6
NM
109#define t1 (scratch + ECC_LIMB_SIZE)
110#define tp (scratch + 2*ECC_LIMB_SIZE)
111
112 /* Set t0 = a^7 */
113 ecc_mod_sqr (p, t0, ap, tp); /* a^2 */
114 ecc_mod_mul (p, t0, ap, t0, tp); /* a^3 */
115 ecc_mod_sqr (p, t0, t0, tp); /* a^6 */
116 ecc_mod_mul (p, t0, ap, t0, tp); /* a^{2^3-1} */
117
118 /* Set t0 = a^{2^18-1} */
119 ecc_mod_pow_2kp1 (p, rp, t0, 3, tp); /* a^{2^6-1} */
120 ecc_mod_pow_2k (p, rp, rp, 3, tp); /* a^{2^9-2^3} */
121 ecc_mod_mul (p, rp, rp, t0, tp); /* a^{2^9-1} */
122 ecc_mod_pow_2kp1 (p, t0, rp, 9, tp); /* a^{2^18-1} */
123
124 /* Set t0 = a^{2^37-1} */
125 ecc_mod_sqr (p, rp, t0, tp); /* a^{2^19-2} */
126 ecc_mod_mul (p, rp, ap, rp, tp); /* a^{2^19-1} */
127 ecc_mod_pow_2k (p, t1, rp, 18, tp); /* a^{2^37-2^18} */
128 ecc_mod_mul (p, t0, t0, t1, tp); /* a^{2^37-1} */
129
130 /* Set t0 = a^{2^222-1} */
131 ecc_mod_pow_2kp1 (p, rp, t0, 37, tp); /* a^{2^74-1} */
132 ecc_mod_pow_2k (p, t1, rp, 37, tp); /* a^{2^111-2^37} */
133 ecc_mod_mul (p, t1, t1, t0, tp); /* a^{2^111-1} */
134 ecc_mod_pow_2kp1 (p, t0, t1, 111, tp);/* a^{2^222-1} */
135
136 ecc_mod_sqr (p, rp, t0, tp); /* a^{2^223-2} */
137 ecc_mod_mul (p, rp, rp, ap, tp); /* a^{2^223-1} */
138 ecc_mod_pow_2k (p, t1, rp, 223, tp); /* a^{2^446-2^223} */
139 ecc_mod_mul (p, rp, t1, t0, tp); /* a^{2^446-2^222-1} */
389c787e
DU
140#undef t0
141#undef t1
1492e9d6 142#undef tp
389c787e
DU
143}
144
1492e9d6 145#define ECC_CURVE448_INV_ITCH (4*ECC_LIMB_SIZE)
389c787e 146
0a5e2524 147static void ecc_curve448_inv (const struct ecc_modulo *p,
389c787e 148 mp_limb_t *rp, const mp_limb_t *ap,
1492e9d6 149 mp_limb_t *tp)
389c787e 150{
1492e9d6
NM
151 ecc_mod_pow_446m224m1 (p, rp, ap, tp);/* a^{2^446-2^222-1} */
152 ecc_mod_sqr (p, rp, rp, tp); /* a^{2^447-2^223-2} */
153 ecc_mod_sqr (p, rp, rp, tp); /* a^{2^448-2^224-4} */
154 ecc_mod_mul (p, rp, ap, rp, tp); /* a^{2^448-2^224-3} */
389c787e
DU
155}
156
652bdc79
NM
157/* To guarantee that inputs to ecc_mod_zero_p are in the required range. */
158#if ECC_LIMB_SIZE * GMP_NUMB_BITS != 448
159#error Unsupported limb size
160#endif
389c787e
DU
161
162/* Compute x such that x^2 = u/v (mod p). Returns one on success, zero
163 on failure.
164
165 To avoid a separate inversion, we use a trick of djb's, to
166 compute the candidate root as
167
168 x = (u/v)^{(p+1)/4} = u^3 v (u^5 v^3)^{(p-3)/4}.
169*/
170
1492e9d6 171/* Needs 2*n space + scratch for ecc_mod_pow_446m224m1. */
c2726388 172#define ECC_CURVE448_SQRT_RATIO_ITCH (6*ECC_LIMB_SIZE)
389c787e
DU
173
174static int
c2726388
NM
175ecc_curve448_sqrt_ratio(const struct ecc_modulo *p, mp_limb_t *rp,
176 const mp_limb_t *up, const mp_limb_t *vp,
177 mp_limb_t *scratch)
389c787e 178{
1492e9d6
NM
179#define uv scratch
180#define u3v (scratch + ECC_LIMB_SIZE)
181#define u5v3 uv
182
183#define t0 scratch
184#define scratch_out (scratch + 2*ECC_LIMB_SIZE)
185 /* Live values */
186 ecc_mod_mul (p, uv, up, vp, scratch_out); /* uv */
187 ecc_mod_sqr (p, u3v, up, scratch_out); /* uv, u3v */
188 ecc_mod_mul (p, u3v, u3v, uv, scratch_out); /* uv, u3v */
189
190 ecc_mod_sqr (p, u5v3, uv, scratch_out); /* u5v3, u3v */
191 ecc_mod_mul (p, u5v3, u5v3, u3v, scratch_out);/* u5v3, u3v */
192
193 ecc_mod_pow_446m224m1 (p, rp, u5v3, scratch_out); /* u3v */
194 ecc_mod_mul (p, rp, rp, u3v, scratch_out);
389c787e
DU
195
196 /* If square root exists, have v x^2 = u */
1492e9d6
NM
197 ecc_mod_sqr (p, t0, rp, scratch_out); /* x^2 */
198 ecc_mod_mul (p, t0, t0, vp, scratch_out); /* v x^2 */
199 ecc_mod_sub (p, t0, t0, up);
389c787e 200
652bdc79 201 return ecc_mod_zero_p (p, t0);
1492e9d6 202#undef uv
389c787e
DU
203#undef u3v
204#undef u5v3
389c787e 205#undef t0
1492e9d6 206#undef scratch_out
389c787e
DU
207}
208
209const struct ecc_curve _nettle_curve448 =
210{
211 {
212 448,
213 ECC_LIMB_SIZE,
214 ECC_BMODP_SIZE,
215 0,
0a5e2524 216 ECC_CURVE448_INV_ITCH,
35f12552 217 0,
c2726388 218 ECC_CURVE448_SQRT_RATIO_ITCH,
389c787e
DU
219
220 ecc_p,
221 ecc_Bmodp,
222 ecc_Bmodp_shifted,
62c74f1f 223 ecc_Bm2p,
389c787e
DU
224 NULL,
225 ecc_pp1h,
226
0a5e2524
DES
227 ecc_curve448_modp,
228 ecc_curve448_modp,
229 ecc_curve448_inv,
35f12552 230 NULL,
c2726388 231 ecc_curve448_sqrt_ratio,
389c787e
DU
232 },
233 {
234 446,
235 ECC_LIMB_SIZE,
236 ECC_BMODQ_SIZE,
237 0,
238 ECC_MOD_INV_ITCH (ECC_LIMB_SIZE),
239 0,
35f12552 240 0,
389c787e
DU
241
242 ecc_q,
243 ecc_Bmodq,
244 ecc_Bmodq_shifted,
62c74f1f 245 ecc_Bm2q,
389c787e
DU
246 NULL,
247 ecc_qp1h,
248
52c86f94
NM
249 ecc_mod,
250 ecc_mod,
389c787e
DU
251 ecc_mod_inv,
252 NULL,
35f12552 253 NULL,
389c787e
DU
254 },
255
256 0, /* No redc */
257 ECC_PIPPENGER_K,
258 ECC_PIPPENGER_C,
259
260 ECC_ADD_EH_ITCH (ECC_LIMB_SIZE),
261 ECC_ADD_EHH_ITCH (ECC_LIMB_SIZE),
262 ECC_DUP_EH_ITCH (ECC_LIMB_SIZE),
263 ECC_MUL_A_EH_ITCH (ECC_LIMB_SIZE),
264 ECC_MUL_G_EH_ITCH (ECC_LIMB_SIZE),
0a5e2524 265 ECC_EH_TO_A_ITCH (ECC_LIMB_SIZE, ECC_CURVE448_INV_ITCH),
389c787e 266
923cc6ae
NM
267 ecc_add_eh,
268 ecc_add_ehh,
269 ecc_dup_eh,
389c787e
DU
270 ecc_mul_a_eh,
271 ecc_mul_g_eh,
272 ecc_eh_to_a,
273
274 ecc_b,
389c787e
DU
275 ecc_unit,
276 ecc_table
277};