Coverage Report

Created: 2025-11-16 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/nettle/ecc-secp256r1.c
Line
Count
Source
1
/* ecc-secp256r1.c
2
3
   Compile time constant (but machine dependent) tables.
4
5
   Copyright (C) 2013, 2014 Niels Möller
6
7
   This file is part of GNU Nettle.
8
9
   GNU Nettle is free software: you can redistribute it and/or
10
   modify it under the terms of either:
11
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.
15
16
   or
17
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.
21
22
   or both in parallel, as here.
23
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.
28
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/.
32
*/
33
34
/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */
35
36
#if HAVE_CONFIG_H
37
# include "config.h"
38
#endif
39
40
#include <assert.h>
41
42
#include "ecc-internal.h"
43
44
#if HAVE_NATIVE_ecc_secp256r1_redc
45
# define USE_REDC 1
46
#else
47
# define USE_REDC (ECC_REDC_SIZE != 0)
48
#endif
49
50
#include "ecc-secp256r1.h"
51
52
#if HAVE_NATIVE_ecc_secp256r1_redc
53
# define ecc_secp256r1_redc _nettle_ecc_secp256r1_redc
54
void
55
ecc_secp256r1_redc (const struct ecc_modulo *p, mp_limb_t *rp, mp_limb_t *xp);
56
#else /* !HAVE_NATIVE_ecc_secp256r1_redc */
57
# if ECC_REDC_SIZE > 0
58
#   define ecc_secp256r1_redc ecc_pp1_redc
59
# elif ECC_REDC_SIZE == 0
60
#   define ecc_secp256r1_redc NULL
61
# else
62
#  error Configuration error
63
# endif
64
#endif /* !HAVE_NATIVE_ecc_secp256r1_redc */
65
66
#if ECC_BMODP_SIZE < ECC_LIMB_SIZE
67
#define ecc_secp256r1_modp ecc_mod
68
#define ecc_secp256r1_modq ecc_mod
69
#elif GMP_NUMB_BITS == 64
70
71
static void
72
ecc_secp256r1_modp (const struct ecc_modulo *p, mp_limb_t *rp, mp_limb_t *xp)
73
31.6k
{
74
31.6k
  mp_limb_t d1, u1, cy;
75
31.6k
  mp_size_t n;
76
77
  /* Reduce to < B^4 p up front, to avoid first quotient overflowing a limb. */
78
31.6k
  cy = mpn_sub_n (xp + 4, xp + 4, p->m, p->size);
79
31.6k
  mpn_cnd_add_n (cy, xp + 4, xp + 4, p->m, p->size);
80
81
31.6k
  d1 = UINT64_C(0xffffffff00000001);
82
95.0k
  for (n = 2*p->size, u1 = xp[--n] ;; n--)
83
126k
    {
84
126k
      mp_limb_t u0, q1, q0, qmax, r, t, mask;
85
126k
      u0 = xp[n-1];
86
87
      /* Since d0 == 0, 2/1 division gives a good enough quotient
88
   approximation.
89
90
   <q1, q0> = v * u1 + <u1,u0>, with v = 2^32 - 1:
91
92
     +---+---+
93
     | u1| u0|
94
     +---+---+
95
         |-u1|
96
       +-+-+-+
97
       | u1|
98
           +-+-+-+-+
99
           | q1| q0|
100
           +---+---+
101
      */
102
126k
      q1 = u1 - (u1 > u0);
103
126k
      q0 = u0 - u1;
104
126k
      t = u1 << 32;
105
126k
      q0 += t;
106
126k
      q1 += (u1 >> 32) + (q0 < t) + 1;
107
108
      /* Force q = B-1 when u1 == d1 */
109
126k
      qmax = - (mp_limb_t) (u1 >= d1);
110
111
      /* Candidate remainder r = u0 - q d1 (mod B), and 2/1 division
112
   adjustments. */
113
126k
      r = u0 + (q1 << 32) - q1;
114
126k
      mask = - (mp_limb_t) (r > q0);
115
126k
      q1 += mask;
116
126k
      r += (mask & d1);
117
126k
      mask = - (mp_limb_t) (r >= d1);
118
126k
      q1 -= mask;
119
126k
      r -= (mask & d1);
120
121
      /* In the case that u1 == d1, we get q1 == 0, r == 0 here (and
122
   correct 2/1 quotient would be B). Replace with q1 = B-1, r =
123
   d1. */
124
126k
      q1 |= qmax;
125
126k
      r += d1 & qmax;
126
127
126k
      cy = mpn_submul_1 (xp + n - 4, p->m, 3, q1);
128
126k
      mask = - (mp_limb_t) (r < cy);
129
126k
      if (n == p->size)
130
31.6k
  {
131
31.6k
    rp[3] = r - cy + (mask & d1) + mpn_cnd_add_n (mask, rp, xp, p->m, 3);
132
31.6k
    return;
133
31.6k
  }
134
95.0k
      u1 = r - cy + (mask & d1) + mpn_cnd_add_n (mask, xp + n - 4, xp + n- 4, p->m, 3);
135
95.0k
    }
136
31.6k
}
137
138
static void
139
ecc_secp256r1_modq (const struct ecc_modulo *q, mp_limb_t *rp, mp_limb_t *xp)
140
44.5k
{
141
44.5k
  mp_limb_t d1, cy;
142
44.5k
  mp_size_t n;
143
144
  /* Reduce to < B^4 p up front, to avoid first quotient overflowing a limb. */
145
44.5k
  cy = mpn_sub_n (xp + 4, xp + 4, q->m, q->size);
146
44.5k
  mpn_cnd_add_n (cy, xp + 4, xp + 4, q->m, q->size);
147
148
44.5k
  d1 = UINT64_C(0xffffffff00000000);
149
44.5k
  n = 2*q->size;
150
44.5k
  for (;;)
151
178k
    {
152
178k
      mp_limb_t u1, u0, q1, q0, r, t, qmax, mask;
153
178k
      u1 = xp[--n];
154
178k
      u0 = xp[n-1];
155
156
      /* divappr2, specialized for d1 = 2^64 - 2^32, d0 = 2^64-1.
157
158
   <q1, q0> = v * u1 + <u1,u0>, with v = 2^32 - 1:
159
160
     +---+---+
161
     | u1| u0|
162
     +---+---+
163
         |-u1|
164
       +-+-+-+
165
       | u1|
166
           +-+-+-+-+
167
           | q1| q0|
168
           +---+---+
169
      */
170
178k
      q1 = u1 - (u1 > u0);
171
178k
      q0 = u0 - u1;
172
178k
      t = u1 << 32;
173
178k
      q0 += t;
174
178k
      q1 += (q0 < t);
175
178k
      t = u1 >> 32;
176
      /* The divappr2 algorithm handles only q < B - 1. If we check
177
   for u1 >= d1 = 2^{64}-2^{32}, we cover all cases where q =
178
   2^64-1, and some when q = 2^64-2. The latter case is
179
   corrected by the final adjustment. */
180
178k
      qmax = - (mp_limb_t) (t == 0xffffffff);
181
178k
      q1 += t + 1;
182
183
      /* Candidate remainder r = u0 - q (d1 + 1) (mod B), and divappr2
184
   adjustments.
185
186
   For general divappr2, the expression is
187
188
     r = u_0 - q1 d1 - floor(q1 d0 / B) - 1
189
190
   but in our case floor(q1 d0 / B) simplifies to q1 - 1.
191
      */
192
178k
      r = u0 + (q1 << 32) - q1;
193
178k
      mask = - (mp_limb_t) (r >= q0);
194
178k
      q1 += mask;
195
178k
      r += (mask & (d1 + 1));
196
178k
      q1 += (r >= d1 - 1);
197
198
      /* Replace by qmax, when that is needed */
199
178k
      q1 |= qmax;
200
201
      /* Subtract, may underflow. */
202
178k
      cy = mpn_submul_1 (xp + n - 4, q->m, 4, q1);
203
178k
      if (n == q->size)
204
44.5k
  {
205
44.5k
    mpn_cnd_add_n (cy > u1, rp, xp, q->m, 4);
206
44.5k
    return;
207
44.5k
  }
208
133k
      mpn_cnd_add_n (cy > u1, xp + n - 4, xp + n- 4, q->m, 4);
209
133k
    }
210
44.5k
}
211
212
#else
213
#error Unsupported parameters
214
#endif
215
216
#define ECC_SECP256R1_INV_ITCH (4*ECC_LIMB_SIZE)
217
218
static void
219
ecc_secp256r1_inv (const struct ecc_modulo *p,
220
       mp_limb_t *rp, const mp_limb_t *ap,
221
       mp_limb_t *scratch)
222
62.6k
{
223
313k
#define a5m1 scratch
224
313k
#define t0 (scratch + ECC_LIMB_SIZE)
225
250k
#define a15m1 t0
226
187k
#define a32m1 a5m1
227
814k
#define tp (scratch + 2*ECC_LIMB_SIZE)
228
/*
229
   Addition chain for p - 2 = 2^{256} - 2^{224} + 2^{192} + 2^{96} - 3
230
231
    2^5 - 1 = 1 + 2 (2^4 - 1) = 1 + 2 (2^2+1)(2 + 1)    4 S + 3 M
232
    2^{15} - 1 = (2^5 - 1) (1 + 2^5 (1 + 2^5)          10 S + 2 M
233
    2^{16} - 1 = 1 + 2 (2^{15} - 1)                       S +   M
234
    2^{32} - 1 = (2^{16} + 1) (2^{16} - 1)             16 S +   M
235
    2^{64} - 2^{32} + 1 = 2^{32} (2^{32} - 1) + 1      32 S +   M
236
    2^{192} - 2^{160} + 2^{128} + 2^{32} - 1
237
        = 2^{128} (2^{64} - 2^{32} + 1) + 2^{32} - 1  128 S +   M
238
    2^{224} - 2^{192} + 2^{160} + 2^{64} - 1
239
        = 2^{32} (...) + 2^{32} - 1                    32 S +   M
240
    2^{239} - 2^{207} + 2^{175} + 2^{79} - 1
241
        = 2^{15} (...) + 2^{15} - 1                    15 S +   M
242
    2^{254} - 2^{222} + 2^{190} + 2^{94} - 1
243
        = 2^{15} (...) + 2^{15} - 1                    15 S +   M
244
    p - 2 = 2^2 (...) + 1                               2 S     M
245
                                                   ---------------
246
                  255 S + 13 M
247
 */
248
62.6k
  ecc_mod_sqr (p, rp, ap, tp);      /* a^2 */
249
62.6k
  ecc_mod_mul (p, rp, rp, ap, tp);    /* a^3 */
250
62.6k
  ecc_mod_pow_2kp1 (p, t0, rp, 2, tp);    /* a^{2^4 - 1} */
251
62.6k
  ecc_mod_sqr (p, rp, t0, tp);      /* a^{2^5 - 2} */
252
62.6k
  ecc_mod_mul (p, a5m1, rp, ap, tp);    /* a^{2^5 - 1}, a5m1 */
253
254
62.6k
  ecc_mod_pow_2kp1 (p, rp, a5m1, 5, tp);  /* a^{2^{10} - 1, a5m1*/
255
62.6k
  ecc_mod_pow_2k_mul (p, a15m1, rp, 5, a5m1, tp); /* a^{2^{15} - 1}, a5m1 a15m1 */
256
62.6k
  ecc_mod_sqr (p, rp, a15m1, tp);    /* a^{2^{16} - 2}, a15m1 */
257
62.6k
  ecc_mod_mul (p, rp, rp, ap, tp);    /* a^{2^{16} - 1}, a15m1 */
258
62.6k
  ecc_mod_pow_2kp1 (p, a32m1, rp, 16, tp);  /* a^{2^{32} - 1}, a15m1, a32m1 */
259
260
62.6k
  ecc_mod_pow_2k_mul (p, rp, a32m1, 32, ap, tp);/* a^{2^{64} - 2^{32} + 1 */
261
62.6k
  ecc_mod_pow_2k_mul (p, rp, rp, 128, a32m1, tp); /* a^{2^{192} - 2^{160} + 2^{128} + 2^{32} - 1} */
262
62.6k
  ecc_mod_pow_2k_mul (p, rp, rp, 32, a32m1, tp);/* a^{2^{224} - 2^{192} + 2^{160} + 2^{64} - 1} */
263
62.6k
  ecc_mod_pow_2k_mul (p, rp, rp, 15, a15m1, tp);/* a^{2^{239} - 2^{207} + 2^{175} + 2^{79} - 1} */
264
62.6k
  ecc_mod_pow_2k_mul (p, rp, rp, 15, a15m1, tp);/* a^{2^{254} - 2^{222} + 2^{190} + 2^{94} - 1} */
265
62.6k
  ecc_mod_pow_2k_mul (p, rp, rp, 2, ap, tp);  /* a^{2^{256} - 2^{224} + 2^{192} + 2^{96} - 3} */
266
267
62.6k
#undef a5m1
268
62.6k
#undef t0
269
62.6k
#undef a15m1
270
62.6k
#undef a32m1
271
62.6k
#undef tp
272
62.6k
}
273
274
/* To guarantee that inputs to ecc_mod_zero_p are in the required range. */
275
#if ECC_LIMB_SIZE * GMP_NUMB_BITS != 256
276
#error Unsupported limb size
277
#endif
278
279
#define ECC_SECP256R1_SQRT_ITCH (3*ECC_LIMB_SIZE)
280
281
static int
282
ecc_secp256r1_sqrt (const struct ecc_modulo *m,
283
        mp_limb_t *rp,
284
        const mp_limb_t *cp,
285
        mp_limb_t *scratch)
286
0
{
287
  /* This computes the square root modulo p256 using the identity:
288
289
     sqrt(c) = c^(2^254 − 2^222 + 2^190 + 2^94)  (mod P-256)
290
291
     which can be seen as a special case of Tonelli-Shanks with e=1.
292
293
     It would be nice to share part of the addition chain between inverse and sqrt.
294
295
     We need
296
297
       p-2 = 2^{256} - 2^{224} + 2^{192} + 2^{96} - 3 (inverse)
298
299
     and
300
301
       (p+1)/4 = 2^{254} − 2^{222} + 2^{190} + 2^{94} (sqrt)
302
303
     which we can both get conveniently from
304
305
       (p-3)/4 = 2^{254} − 2^{222} + 2^{190} + 2^{94} - 1
306
307
     But addition chain for 2^{94} - 1 appears to cost a few more mul
308
     operations than the current, separate, chains. */
309
310
0
#define t0 scratch
311
0
#define tp (scratch + ECC_LIMB_SIZE)
312
313
0
  ecc_mod_sqr        (m, rp, cp, tp);    /* c^2 */
314
0
  ecc_mod_mul        (m, t0, rp, cp, tp);  /* c^3 */
315
0
  ecc_mod_pow_2kp1   (m, rp, t0, 2, tp);  /* c^(2^4 - 1) */
316
0
  ecc_mod_pow_2kp1   (m, t0, rp, 4, tp);  /* c^(2^8 - 1) */
317
0
  ecc_mod_pow_2kp1   (m, rp, t0, 8, tp);  /* c^(2^16 - 1) */
318
0
  ecc_mod_pow_2kp1   (m, t0, rp, 16, tp); /* c^(2^32 - 1) */
319
0
  ecc_mod_pow_2k_mul (m, rp, t0, 32, cp, tp);  /* c^(2^64 - 2^32 + 1) */
320
0
  ecc_mod_pow_2k_mul (m, t0, rp, 96, cp, tp);  /* c^(2^160 - 2^128 + 2^96 + 1) */
321
0
  ecc_mod_pow_2k     (m, rp, t0, 94,     tp);  /* c^(2^254 - 2^222 + 2^190 + 2^94) */
322
323
0
  ecc_mod_sqr (m, t0, rp, tp);
324
0
  ecc_mod_sub (m, t0, t0, cp);
325
326
0
  return ecc_mod_zero_p (m, t0);
327
0
#undef t0
328
0
#undef tp
329
330
0
}
331
332
const struct ecc_curve _nettle_secp_256r1 =
333
{
334
  {
335
    256,
336
    ECC_LIMB_SIZE,
337
    ECC_BMODP_SIZE,
338
    ECC_REDC_SIZE,
339
    ECC_SECP256R1_INV_ITCH,
340
    ECC_SECP256R1_SQRT_ITCH,
341
    0,
342
343
    ecc_p,
344
    ecc_Bmodp,
345
    ecc_Bmodp_shifted,
346
    ecc_Bm2p,
347
    ecc_redc_ppm1,
348
    ecc_pp1h,
349
350
    ecc_secp256r1_modp,
351
    USE_REDC ? ecc_secp256r1_redc : ecc_secp256r1_modp,
352
    ecc_secp256r1_inv,
353
    ecc_secp256r1_sqrt,
354
    NULL,
355
  },
356
  {
357
    256,
358
    ECC_LIMB_SIZE,
359
    ECC_BMODQ_SIZE,
360
    0,
361
    ECC_MOD_INV_ITCH (ECC_LIMB_SIZE),
362
    0,
363
    0,
364
365
    ecc_q,
366
    ecc_Bmodq,
367
    ecc_Bmodq_shifted,
368
    ecc_Bm2q,
369
    NULL,
370
    ecc_qp1h,
371
372
    ecc_secp256r1_modq,
373
    ecc_secp256r1_modq,
374
    ecc_mod_inv,
375
    NULL,
376
    NULL,
377
  },
378
379
  USE_REDC,
380
  ECC_PIPPENGER_K,
381
  ECC_PIPPENGER_C,
382
383
  ECC_ADD_JJA_ITCH (ECC_LIMB_SIZE),
384
  ECC_ADD_JJJ_ITCH (ECC_LIMB_SIZE),
385
  ECC_DUP_JJ_ITCH (ECC_LIMB_SIZE),
386
  ECC_MUL_A_ITCH (ECC_LIMB_SIZE),
387
  ECC_MUL_G_ITCH (ECC_LIMB_SIZE),
388
  ECC_J_TO_A_ITCH(ECC_LIMB_SIZE, ECC_SECP256R1_INV_ITCH),
389
390
  ecc_add_jja,
391
  ecc_add_jjj,
392
  ecc_dup_jj,
393
  ecc_mul_a,
394
  ecc_mul_g,
395
  ecc_j_to_a,
396
397
  ecc_b,
398
  ecc_unit,
399
  ecc_table
400
};
401
402
const struct ecc_curve *nettle_get_secp_256r1(void)
403
238k
{
404
238k
  return &_nettle_secp_256r1;
405
238k
}