2 * Copyright 2002-2023 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
11 #include "internal/cryptlib.h"
13 #define BN_NIST_192_TOP (192+BN_BITS2-1)/BN_BITS2
14 #define BN_NIST_224_TOP (224+BN_BITS2-1)/BN_BITS2
15 #define BN_NIST_256_TOP (256+BN_BITS2-1)/BN_BITS2
16 #define BN_NIST_384_TOP (384+BN_BITS2-1)/BN_BITS2
17 #define BN_NIST_521_TOP (521+BN_BITS2-1)/BN_BITS2
19 /* pre-computed tables are "carry-less" values of modulus*(i+1) */
21 static const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = {
22 {0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFFULL},
23 {0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFFULL},
24 {0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFCULL, 0xFFFFFFFFFFFFFFFFULL}
27 static const BN_ULONG _nist_p_192_sqr[] = {
28 0x0000000000000001ULL, 0x0000000000000002ULL, 0x0000000000000001ULL,
29 0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFFULL
32 static const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = {
33 {0x0000000000000001ULL, 0xFFFFFFFF00000000ULL,
34 0xFFFFFFFFFFFFFFFFULL, 0x00000000FFFFFFFFULL},
35 {0x0000000000000002ULL, 0xFFFFFFFE00000000ULL,
36 0xFFFFFFFFFFFFFFFFULL, 0x00000001FFFFFFFFULL} /* this one is
40 static const BN_ULONG _nist_p_224_sqr[] = {
41 0x0000000000000001ULL, 0xFFFFFFFE00000000ULL,
42 0xFFFFFFFFFFFFFFFFULL, 0x0000000200000000ULL,
43 0x0000000000000000ULL, 0xFFFFFFFFFFFFFFFEULL,
47 static const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = {
48 {0xFFFFFFFFFFFFFFFFULL, 0x00000000FFFFFFFFULL,
49 0x0000000000000000ULL, 0xFFFFFFFF00000001ULL},
50 {0xFFFFFFFFFFFFFFFEULL, 0x00000001FFFFFFFFULL,
51 0x0000000000000000ULL, 0xFFFFFFFE00000002ULL},
52 {0xFFFFFFFFFFFFFFFDULL, 0x00000002FFFFFFFFULL,
53 0x0000000000000000ULL, 0xFFFFFFFD00000003ULL},
54 {0xFFFFFFFFFFFFFFFCULL, 0x00000003FFFFFFFFULL,
55 0x0000000000000000ULL, 0xFFFFFFFC00000004ULL},
56 {0xFFFFFFFFFFFFFFFBULL, 0x00000004FFFFFFFFULL,
57 0x0000000000000000ULL, 0xFFFFFFFB00000005ULL},
60 static const BN_ULONG _nist_p_256_sqr[] = {
61 0x0000000000000001ULL, 0xFFFFFFFE00000000ULL,
62 0xFFFFFFFFFFFFFFFFULL, 0x00000001FFFFFFFEULL,
63 0x00000001FFFFFFFEULL, 0x00000001FFFFFFFEULL,
64 0xFFFFFFFE00000001ULL, 0xFFFFFFFE00000002ULL
67 static const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = {
68 {0x00000000FFFFFFFFULL, 0xFFFFFFFF00000000ULL, 0xFFFFFFFFFFFFFFFEULL,
69 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
70 {0x00000001FFFFFFFEULL, 0xFFFFFFFE00000000ULL, 0xFFFFFFFFFFFFFFFDULL,
71 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
72 {0x00000002FFFFFFFDULL, 0xFFFFFFFD00000000ULL, 0xFFFFFFFFFFFFFFFCULL,
73 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
74 {0x00000003FFFFFFFCULL, 0xFFFFFFFC00000000ULL, 0xFFFFFFFFFFFFFFFBULL,
75 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
76 {0x00000004FFFFFFFBULL, 0xFFFFFFFB00000000ULL, 0xFFFFFFFFFFFFFFFAULL,
77 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
80 static const BN_ULONG _nist_p_384_sqr[] = {
81 0xFFFFFFFE00000001ULL, 0x0000000200000000ULL, 0xFFFFFFFE00000000ULL,
82 0x0000000200000000ULL, 0x0000000000000001ULL, 0x0000000000000000ULL,
83 0x00000001FFFFFFFEULL, 0xFFFFFFFE00000000ULL, 0xFFFFFFFFFFFFFFFDULL,
84 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL
87 static const BN_ULONG _nist_p_521[] =
88 { 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
89 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
90 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
91 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
95 static const BN_ULONG _nist_p_521_sqr[] = {
96 0x0000000000000001ULL, 0x0000000000000000ULL, 0x0000000000000000ULL,
97 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL,
98 0x0000000000000000ULL, 0x0000000000000000ULL, 0xFFFFFFFFFFFFFC00ULL,
99 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
100 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
101 0xFFFFFFFFFFFFFFFFULL, 0x000000000003FFFFULL
104 static const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = {
105 {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
106 {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
107 {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}
110 static const BN_ULONG _nist_p_192_sqr[] = {
111 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000001, 0x00000000,
112 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
115 static const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = {
116 {0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF,
117 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
118 {0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE,
119 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}
122 static const BN_ULONG _nist_p_224_sqr[] = {
123 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE,
124 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000002,
125 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF,
126 0xFFFFFFFF, 0xFFFFFFFF
129 static const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = {
130 {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
131 0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF},
132 {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001,
133 0x00000000, 0x00000000, 0x00000002, 0xFFFFFFFE},
134 {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000002,
135 0x00000000, 0x00000000, 0x00000003, 0xFFFFFFFD},
136 {0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000003,
137 0x00000000, 0x00000000, 0x00000004, 0xFFFFFFFC},
138 {0xFFFFFFFB, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000004,
139 0x00000000, 0x00000000, 0x00000005, 0xFFFFFFFB},
142 static const BN_ULONG _nist_p_256_sqr[] = {
143 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE,
144 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001,
145 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001,
146 0x00000001, 0xFFFFFFFE, 0x00000002, 0xFFFFFFFE
149 static const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = {
150 {0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF,
151 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
152 {0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF,
153 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
154 {0xFFFFFFFD, 0x00000002, 0x00000000, 0xFFFFFFFD, 0xFFFFFFFC, 0xFFFFFFFF,
155 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
156 {0xFFFFFFFC, 0x00000003, 0x00000000, 0xFFFFFFFC, 0xFFFFFFFB, 0xFFFFFFFF,
157 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
158 {0xFFFFFFFB, 0x00000004, 0x00000000, 0xFFFFFFFB, 0xFFFFFFFA, 0xFFFFFFFF,
159 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
162 static const BN_ULONG _nist_p_384_sqr[] = {
163 0x00000001, 0xFFFFFFFE, 0x00000000, 0x00000002, 0x00000000, 0xFFFFFFFE,
164 0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
165 0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF,
166 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
169 static const BN_ULONG _nist_p_521[] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
170 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
171 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
172 0xFFFFFFFF, 0x000001FF
175 static const BN_ULONG _nist_p_521_sqr[] = {
176 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
177 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
178 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFC00, 0xFFFFFFFF,
179 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
180 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
181 0xFFFFFFFF, 0xFFFFFFFF, 0x0003FFFF
184 # error "unsupported BN_BITS2"
187 static const BIGNUM ossl_bignum_nist_p_192 = {
188 (BN_ULONG *)_nist_p_192[0],
195 static const BIGNUM ossl_bignum_nist_p_224 = {
196 (BN_ULONG *)_nist_p_224[0],
203 static const BIGNUM ossl_bignum_nist_p_256 = {
204 (BN_ULONG *)_nist_p_256[0],
211 static const BIGNUM ossl_bignum_nist_p_384 = {
212 (BN_ULONG *)_nist_p_384[0],
219 static const BIGNUM ossl_bignum_nist_p_521 = {
220 (BN_ULONG *)_nist_p_521,
227 const BIGNUM *BN_get0_nist_prime_192(void)
229 return &ossl_bignum_nist_p_192;
232 const BIGNUM *BN_get0_nist_prime_224(void)
234 return &ossl_bignum_nist_p_224;
237 const BIGNUM *BN_get0_nist_prime_256(void)
239 return &ossl_bignum_nist_p_256;
242 const BIGNUM *BN_get0_nist_prime_384(void)
244 return &ossl_bignum_nist_p_384;
247 const BIGNUM *BN_get0_nist_prime_521(void)
249 return &ossl_bignum_nist_p_521;
253 * To avoid more recent compilers (specifically clang-14) from treating this
254 * code as a violation of the strict aliasing conditions and omitting it, this
255 * cannot be declared as a function. Moreover, the dst parameter cannot be
256 * cached in a local since this no longer references the union and again falls
257 * foul of the strict aliasing criteria. Refer to #18225 for the initial
258 * diagnostics and llvm/llvm-project#55255 for the later discussions with the
259 * LLVM developers. The problem boils down to if an array in the union is
260 * converted to a pointer or if it is used directly.
262 * This function was inlined regardless, so there is no space cost to be
263 * paid for making it a macro.
265 #define nist_cp_bn_0(dst, src_in, top, max) \
268 const BN_ULONG *src = src_in; \
270 for (ii = 0; ii < top; ii++) \
271 (dst)[ii] = src[ii]; \
272 for (; ii < max; ii++) \
276 static void nist_cp_bn(BN_ULONG *dst, const BN_ULONG *src, int top)
280 for (i = 0; i < top; i++)
285 # define bn_cp_64(to, n, from, m) (to)[n] = (m>=0)?((from)[m]):0;
286 # define bn_64_set_0(to, n) (to)[n] = (BN_ULONG)0;
288 * two following macros are implemented under assumption that they
289 * are called in a sequence with *ascending* n, i.e. as they are...
291 # define bn_cp_32_naked(to, n, from, m) (((n)&1)?(to[(n)/2]|=((m)&1)?(from[(m)/2]&BN_MASK2h):(from[(m)/2]<<32))\
292 :(to[(n)/2] =((m)&1)?(from[(m)/2]>>32):(from[(m)/2]&BN_MASK2l)))
293 # define bn_32_set_0(to, n) (((n)&1)?(to[(n)/2]&=BN_MASK2l):(to[(n)/2]=0));
294 # define bn_cp_32(to,n,from,m) ((m)>=0)?bn_cp_32_naked(to,n,from,m):bn_32_set_0(to,n)
295 # if defined(L_ENDIAN)
296 # if defined(__arch64__)
297 # define NIST_INT64 long
299 # define NIST_INT64 long long
303 # define bn_cp_64(to, n, from, m) \
305 bn_cp_32(to, (n)*2, from, (m)*2); \
306 bn_cp_32(to, (n)*2+1, from, (m)*2+1); \
308 # define bn_64_set_0(to, n) \
310 bn_32_set_0(to, (n)*2); \
311 bn_32_set_0(to, (n)*2+1); \
313 # define bn_cp_32(to, n, from, m) (to)[n] = (m>=0)?((from)[m]):0;
314 # define bn_32_set_0(to, n) (to)[n] = (BN_ULONG)0;
315 # if defined(_WIN32) && !defined(__GNUC__)
316 # define NIST_INT64 __int64
317 # elif defined(BN_LLONG)
318 # define NIST_INT64 long long
320 #endif /* BN_BITS2 != 64 */
323 /* Helpers to load/store a 32-bit word (uint32_t) from/into a memory
324 * location and avoid potential aliasing issue. */
325 static ossl_inline uint32_t load_u32(const void *ptr)
329 memcpy(&tmp, ptr, sizeof(tmp));
333 static ossl_inline void store_lo32(void *ptr, NIST_INT64 val)
335 /* A cast is needed for big-endian system: on a 32-bit BE system
336 * NIST_INT64 may be defined as well if the compiler supports 64-bit
338 uint32_t tmp = (uint32_t)val;
340 memcpy(ptr, &tmp, sizeof(tmp));
342 #endif /* NIST_INT64 */
344 #define nist_set_192(to, from, a1, a2, a3) \
346 bn_cp_64(to, 0, from, (a3) - 3) \
347 bn_cp_64(to, 1, from, (a2) - 3) \
348 bn_cp_64(to, 2, from, (a1) - 3) \
351 int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
356 register BN_ULONG *r_d, *a_d = a->d;
358 BN_ULONG bn[BN_NIST_192_TOP];
359 unsigned int ui[BN_NIST_192_TOP * sizeof(BN_ULONG) /
360 sizeof(unsigned int)];
362 BN_ULONG c_d[BN_NIST_192_TOP], *res;
363 static const BIGNUM ossl_bignum_nist_p_192_sqr = {
364 (BN_ULONG *)_nist_p_192_sqr,
365 OSSL_NELEM(_nist_p_192_sqr),
366 OSSL_NELEM(_nist_p_192_sqr),
367 0, BN_FLG_STATIC_DATA
370 field = &ossl_bignum_nist_p_192; /* just to make sure */
372 if (BN_is_negative(a) || BN_ucmp(a, &ossl_bignum_nist_p_192_sqr) >= 0)
373 return BN_nnmod(r, a, field, ctx);
375 i = BN_ucmp(field, a);
380 return (r == a) ? 1 : (BN_copy(r, a) != NULL);
383 if (!bn_wexpand(r, BN_NIST_192_TOP))
386 nist_cp_bn(r_d, a_d, BN_NIST_192_TOP);
390 nist_cp_bn_0(buf.bn, a_d + BN_NIST_192_TOP, top - BN_NIST_192_TOP,
393 #if defined(NIST_INT64)
395 NIST_INT64 acc; /* accumulator */
396 unsigned int *rp = (unsigned int *)r_d;
397 const unsigned int *bp = (const unsigned int *)buf.ui;
399 acc = load_u32(&rp[0]);
400 acc += bp[3 * 2 - 6];
401 acc += bp[5 * 2 - 6];
402 store_lo32(&rp[0], acc);
405 acc += load_u32(&rp[1]);
406 acc += bp[3 * 2 - 5];
407 acc += bp[5 * 2 - 5];
408 store_lo32(&rp[1], acc);
411 acc += load_u32(&rp[2]);
412 acc += bp[3 * 2 - 6];
413 acc += bp[4 * 2 - 6];
414 acc += bp[5 * 2 - 6];
415 store_lo32(&rp[2], acc);
418 acc += load_u32(&rp[3]);
419 acc += bp[3 * 2 - 5];
420 acc += bp[4 * 2 - 5];
421 acc += bp[5 * 2 - 5];
422 store_lo32(&rp[3], acc);
425 acc += load_u32(&rp[4]);
426 acc += bp[4 * 2 - 6];
427 acc += bp[5 * 2 - 6];
428 store_lo32(&rp[4], acc);
431 acc += load_u32(&rp[5]);
432 acc += bp[4 * 2 - 5];
433 acc += bp[5 * 2 - 5];
434 store_lo32(&rp[5], acc);
436 carry = (int)(acc >> 32);
440 BN_ULONG t_d[BN_NIST_192_TOP];
442 nist_set_192(t_d, buf.bn, 0, 3, 3);
443 carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
444 nist_set_192(t_d, buf.bn, 4, 4, 0);
445 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
446 nist_set_192(t_d, buf.bn, 5, 5, 5)
447 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
452 (int)bn_sub_words(r_d, r_d, _nist_p_192[carry - 1],
458 * we need 'if (carry==0 || result>=modulus) result-=modulus;'
459 * as comparison implies subtraction, we can write
460 * 'tmp=result-modulus; if (!carry || !borrow) result=tmp;'
461 * this is what happens below, but without explicit if:-) a.
463 res = (bn_sub_words(c_d, r_d, _nist_p_192[0], BN_NIST_192_TOP) && carry)
466 nist_cp_bn(r_d, res, BN_NIST_192_TOP);
467 r->top = BN_NIST_192_TOP;
473 typedef BN_ULONG (*bn_addsub_f) (BN_ULONG *, const BN_ULONG *,
474 const BN_ULONG *, int);
476 #define nist_set_224(to, from, a1, a2, a3, a4, a5, a6, a7) \
478 bn_cp_32(to, 0, from, (a7) - 7) \
479 bn_cp_32(to, 1, from, (a6) - 7) \
480 bn_cp_32(to, 2, from, (a5) - 7) \
481 bn_cp_32(to, 3, from, (a4) - 7) \
482 bn_cp_32(to, 4, from, (a3) - 7) \
483 bn_cp_32(to, 5, from, (a2) - 7) \
484 bn_cp_32(to, 6, from, (a1) - 7) \
487 int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
492 BN_ULONG *r_d, *a_d = a->d;
494 BN_ULONG bn[BN_NIST_224_TOP];
495 unsigned int ui[BN_NIST_224_TOP * sizeof(BN_ULONG) /
496 sizeof(unsigned int)];
498 BN_ULONG c_d[BN_NIST_224_TOP], *res;
500 static const BIGNUM ossl_bignum_nist_p_224_sqr = {
501 (BN_ULONG *)_nist_p_224_sqr,
502 OSSL_NELEM(_nist_p_224_sqr),
503 OSSL_NELEM(_nist_p_224_sqr),
504 0, BN_FLG_STATIC_DATA
507 field = &ossl_bignum_nist_p_224; /* just to make sure */
509 if (BN_is_negative(a) || BN_ucmp(a, &ossl_bignum_nist_p_224_sqr) >= 0)
510 return BN_nnmod(r, a, field, ctx);
512 i = BN_ucmp(field, a);
517 return (r == a) ? 1 : (BN_copy(r, a) != NULL);
520 if (!bn_wexpand(r, BN_NIST_224_TOP))
523 nist_cp_bn(r_d, a_d, BN_NIST_224_TOP);
528 /* copy upper 256 bits of 448 bit number ... */
529 nist_cp_bn_0(c_d, a_d + (BN_NIST_224_TOP - 1),
530 top - (BN_NIST_224_TOP - 1), BN_NIST_224_TOP);
531 /* ... and right shift by 32 to obtain upper 224 bits */
532 nist_set_224(buf.bn, c_d, 14, 13, 12, 11, 10, 9, 8);
533 /* truncate lower part to 224 bits too */
534 r_d[BN_NIST_224_TOP - 1] &= BN_MASK2l;
536 nist_cp_bn_0(buf.bn, a_d + BN_NIST_224_TOP, top - BN_NIST_224_TOP,
540 #if defined(NIST_INT64) && BN_BITS2!=64
542 NIST_INT64 acc; /* accumulator */
543 unsigned int *rp = (unsigned int *)r_d;
544 const unsigned int *bp = (const unsigned int *)buf.ui;
549 rp[0] = (unsigned int)acc;
555 rp[1] = (unsigned int)acc;
561 rp[2] = (unsigned int)acc;
568 rp[3] = (unsigned int)acc;
575 rp[4] = (unsigned int)acc;
582 rp[5] = (unsigned int)acc;
588 rp[6] = (unsigned int)acc;
590 carry = (int)(acc >> 32);
597 BN_ULONG t_d[BN_NIST_224_TOP];
599 nist_set_224(t_d, buf.bn, 10, 9, 8, 7, 0, 0, 0);
600 carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP);
601 nist_set_224(t_d, buf.bn, 0, 13, 12, 11, 0, 0, 0);
602 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP);
603 nist_set_224(t_d, buf.bn, 13, 12, 11, 10, 9, 8, 7);
604 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP);
605 nist_set_224(t_d, buf.bn, 0, 0, 0, 0, 13, 12, 11);
606 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP);
609 carry = (int)(r_d[BN_NIST_224_TOP - 1] >> 32);
613 adjust = bn_sub_words;
616 (int)bn_sub_words(r_d, r_d, _nist_p_224[carry - 1],
619 carry = (int)(~(r_d[BN_NIST_224_TOP - 1] >> 32)) & 1;
621 } else if (carry < 0) {
623 * it's a bit more complicated logic in this case. if bn_add_words
624 * yields no carry, then result has to be adjusted by unconditionally
625 * *adding* the modulus. but if it does, then result has to be
626 * compared to the modulus and conditionally adjusted by
627 * *subtracting* the latter.
630 (int)bn_add_words(r_d, r_d, _nist_p_224[-carry - 1],
632 adjust = carry ? bn_sub_words : bn_add_words;
636 /* otherwise it's effectively same as in BN_nist_mod_192... */
637 res = ((*adjust) (c_d, r_d, _nist_p_224[0], BN_NIST_224_TOP) && carry)
640 nist_cp_bn(r_d, res, BN_NIST_224_TOP);
641 r->top = BN_NIST_224_TOP;
647 #define nist_set_256(to, from, a1, a2, a3, a4, a5, a6, a7, a8) \
649 bn_cp_32(to, 0, from, (a8) - 8) \
650 bn_cp_32(to, 1, from, (a7) - 8) \
651 bn_cp_32(to, 2, from, (a6) - 8) \
652 bn_cp_32(to, 3, from, (a5) - 8) \
653 bn_cp_32(to, 4, from, (a4) - 8) \
654 bn_cp_32(to, 5, from, (a3) - 8) \
655 bn_cp_32(to, 6, from, (a2) - 8) \
656 bn_cp_32(to, 7, from, (a1) - 8) \
659 int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
664 register BN_ULONG *a_d = a->d, *r_d;
666 BN_ULONG bn[BN_NIST_256_TOP];
667 unsigned int ui[BN_NIST_256_TOP * sizeof(BN_ULONG) /
668 sizeof(unsigned int)];
670 BN_ULONG c_d[BN_NIST_256_TOP], *res;
672 static const BIGNUM ossl_bignum_nist_p_256_sqr = {
673 (BN_ULONG *)_nist_p_256_sqr,
674 OSSL_NELEM(_nist_p_256_sqr),
675 OSSL_NELEM(_nist_p_256_sqr),
676 0, BN_FLG_STATIC_DATA
679 field = &ossl_bignum_nist_p_256; /* just to make sure */
681 if (BN_is_negative(a) || BN_ucmp(a, &ossl_bignum_nist_p_256_sqr) >= 0)
682 return BN_nnmod(r, a, field, ctx);
684 i = BN_ucmp(field, a);
689 return (r == a) ? 1 : (BN_copy(r, a) != NULL);
692 if (!bn_wexpand(r, BN_NIST_256_TOP))
695 nist_cp_bn(r_d, a_d, BN_NIST_256_TOP);
699 nist_cp_bn_0(buf.bn, a_d + BN_NIST_256_TOP, top - BN_NIST_256_TOP,
702 #if defined(NIST_INT64)
704 NIST_INT64 acc; /* accumulator */
705 unsigned int *rp = (unsigned int *)r_d;
706 const unsigned int *bp = (const unsigned int *)buf.ui;
708 acc = load_u32(&rp[0]);
715 store_lo32(&rp[0], acc);
718 acc += load_u32(&rp[1]);
725 store_lo32(&rp[1], acc);
728 acc += load_u32(&rp[2]);
734 store_lo32(&rp[2], acc);
737 acc += load_u32(&rp[3]);
746 store_lo32(&rp[3], acc);
749 acc += load_u32(&rp[4]);
757 store_lo32(&rp[4], acc);
760 acc += load_u32(&rp[5]);
768 store_lo32(&rp[5], acc);
771 acc += load_u32(&rp[6]);
780 store_lo32(&rp[6], acc);
783 acc += load_u32(&rp[7]);
792 store_lo32(&rp[7], acc);
794 carry = (int)(acc >> 32);
798 BN_ULONG t_d[BN_NIST_256_TOP];
803 nist_set_256(t_d, buf.bn, 15, 14, 13, 12, 11, 0, 0, 0);
807 nist_set_256(c_d, buf.bn, 0, 15, 14, 13, 12, 0, 0, 0);
808 carry = (int)bn_add_words(t_d, t_d, c_d, BN_NIST_256_TOP);
811 register BN_ULONG *ap, t, c;
814 for (i = BN_NIST_256_TOP; i != 0; --i) {
816 *(ap++) = ((t << 1) | c) & BN_MASK2;
817 c = (t & BN_TBIT) ? 1 : 0;
822 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
826 nist_set_256(t_d, buf.bn, 15, 14, 0, 0, 0, 10, 9, 8);
827 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
831 nist_set_256(t_d, buf.bn, 8, 13, 15, 14, 13, 11, 10, 9);
832 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
836 nist_set_256(t_d, buf.bn, 10, 8, 0, 0, 0, 13, 12, 11);
837 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
841 nist_set_256(t_d, buf.bn, 11, 9, 0, 0, 15, 14, 13, 12);
842 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
846 nist_set_256(t_d, buf.bn, 12, 0, 10, 9, 8, 15, 14, 13);
847 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
851 nist_set_256(t_d, buf.bn, 13, 0, 11, 10, 9, 0, 15, 14);
852 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
856 /* see BN_nist_mod_224 for explanation */
857 adjust = bn_sub_words;
860 (int)bn_sub_words(r_d, r_d, _nist_p_256[carry - 1],
862 else if (carry < 0) {
864 (int)bn_add_words(r_d, r_d, _nist_p_256[-carry - 1],
866 adjust = carry ? bn_sub_words : bn_add_words;
870 res = ((*adjust) (c_d, r_d, _nist_p_256[0], BN_NIST_256_TOP) && carry)
873 nist_cp_bn(r_d, res, BN_NIST_256_TOP);
874 r->top = BN_NIST_256_TOP;
880 #define nist_set_384(to,from,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) \
882 bn_cp_32(to, 0, from, (a12) - 12) \
883 bn_cp_32(to, 1, from, (a11) - 12) \
884 bn_cp_32(to, 2, from, (a10) - 12) \
885 bn_cp_32(to, 3, from, (a9) - 12) \
886 bn_cp_32(to, 4, from, (a8) - 12) \
887 bn_cp_32(to, 5, from, (a7) - 12) \
888 bn_cp_32(to, 6, from, (a6) - 12) \
889 bn_cp_32(to, 7, from, (a5) - 12) \
890 bn_cp_32(to, 8, from, (a4) - 12) \
891 bn_cp_32(to, 9, from, (a3) - 12) \
892 bn_cp_32(to, 10, from, (a2) - 12) \
893 bn_cp_32(to, 11, from, (a1) - 12) \
896 int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
901 register BN_ULONG *r_d, *a_d = a->d;
903 BN_ULONG bn[BN_NIST_384_TOP];
904 unsigned int ui[BN_NIST_384_TOP * sizeof(BN_ULONG) /
905 sizeof(unsigned int)];
907 BN_ULONG c_d[BN_NIST_384_TOP], *res;
909 static const BIGNUM ossl_bignum_nist_p_384_sqr = {
910 (BN_ULONG *)_nist_p_384_sqr,
911 OSSL_NELEM(_nist_p_384_sqr),
912 OSSL_NELEM(_nist_p_384_sqr),
913 0, BN_FLG_STATIC_DATA
916 field = &ossl_bignum_nist_p_384; /* just to make sure */
918 if (BN_is_negative(a) || BN_ucmp(a, &ossl_bignum_nist_p_384_sqr) >= 0)
919 return BN_nnmod(r, a, field, ctx);
921 i = BN_ucmp(field, a);
926 return (r == a) ? 1 : (BN_copy(r, a) != NULL);
929 if (!bn_wexpand(r, BN_NIST_384_TOP))
932 nist_cp_bn(r_d, a_d, BN_NIST_384_TOP);
936 nist_cp_bn_0(buf.bn, a_d + BN_NIST_384_TOP, top - BN_NIST_384_TOP,
939 #if defined(NIST_INT64)
941 NIST_INT64 acc; /* accumulator */
942 unsigned int *rp = (unsigned int *)r_d;
943 const unsigned int *bp = (const unsigned int *)buf.ui;
945 acc = load_u32(&rp[0]);
950 store_lo32(&rp[0], acc);
953 acc += load_u32(&rp[1]);
959 store_lo32(&rp[1], acc);
962 acc += load_u32(&rp[2]);
967 store_lo32(&rp[2], acc);
970 acc += load_u32(&rp[3]);
978 store_lo32(&rp[3], acc);
981 acc += load_u32(&rp[4]);
992 store_lo32(&rp[4], acc);
995 acc += load_u32(&rp[5]);
1004 store_lo32(&rp[5], acc);
1007 acc += load_u32(&rp[6]);
1015 store_lo32(&rp[6], acc);
1018 acc += load_u32(&rp[7]);
1024 store_lo32(&rp[7], acc);
1027 acc += load_u32(&rp[8]);
1032 store_lo32(&rp[8], acc);
1035 acc += load_u32(&rp[9]);
1040 store_lo32(&rp[9], acc);
1043 acc += load_u32(&rp[10]);
1048 store_lo32(&rp[10], acc);
1051 acc += load_u32(&rp[11]);
1056 store_lo32(&rp[11], acc);
1058 carry = (int)(acc >> 32);
1062 BN_ULONG t_d[BN_NIST_384_TOP];
1067 nist_set_256(t_d, buf.bn, 0, 0, 0, 0, 0, 23 - 4, 22 - 4, 21 - 4);
1070 register BN_ULONG *ap, t, c;
1073 for (i = 3; i != 0; --i) {
1075 *(ap++) = ((t << 1) | c) & BN_MASK2;
1076 c = (t & BN_TBIT) ? 1 : 0;
1081 (int)bn_add_words(r_d + (128 / BN_BITS2), r_d + (128 / BN_BITS2),
1082 t_d, BN_NIST_256_TOP);
1086 carry += (int)bn_add_words(r_d, r_d, buf.bn, BN_NIST_384_TOP);
1090 nist_set_384(t_d, buf.bn, 20, 19, 18, 17, 16, 15, 14, 13, 12, 23, 22,
1092 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
1096 nist_set_384(t_d, buf.bn, 19, 18, 17, 16, 15, 14, 13, 12, 20, 0, 23,
1098 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
1102 nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 23, 22, 21, 20, 0, 0, 0, 0);
1103 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
1107 nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 23, 22, 21, 0, 0, 20);
1108 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
1112 nist_set_384(t_d, buf.bn, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12,
1114 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
1118 nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 0, 23, 22, 21, 20, 0);
1119 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
1123 nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 0, 23, 23, 0, 0, 0);
1124 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
1128 /* see BN_nist_mod_224 for explanation */
1129 adjust = bn_sub_words;
1132 (int)bn_sub_words(r_d, r_d, _nist_p_384[carry - 1],
1134 else if (carry < 0) {
1136 (int)bn_add_words(r_d, r_d, _nist_p_384[-carry - 1],
1138 adjust = carry ? bn_sub_words : bn_add_words;
1142 res = ((*adjust) (c_d, r_d, _nist_p_384[0], BN_NIST_384_TOP) && carry)
1145 nist_cp_bn(r_d, res, BN_NIST_384_TOP);
1146 r->top = BN_NIST_384_TOP;
1152 #define BN_NIST_521_RSHIFT (521%BN_BITS2)
1153 #define BN_NIST_521_LSHIFT (BN_BITS2-BN_NIST_521_RSHIFT)
1154 #define BN_NIST_521_TOP_MASK ((BN_ULONG)BN_MASK2>>BN_NIST_521_LSHIFT)
1156 int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
1159 int top = a->top, i;
1160 BN_ULONG *r_d, *a_d = a->d, t_d[BN_NIST_521_TOP], val, tmp, *res;
1161 static const BIGNUM ossl_bignum_nist_p_521_sqr = {
1162 (BN_ULONG *)_nist_p_521_sqr,
1163 OSSL_NELEM(_nist_p_521_sqr),
1164 OSSL_NELEM(_nist_p_521_sqr),
1165 0, BN_FLG_STATIC_DATA
1168 field = &ossl_bignum_nist_p_521; /* just to make sure */
1170 if (BN_is_negative(a) || BN_ucmp(a, &ossl_bignum_nist_p_521_sqr) >= 0)
1171 return BN_nnmod(r, a, field, ctx);
1173 i = BN_ucmp(field, a);
1178 return (r == a) ? 1 : (BN_copy(r, a) != NULL);
1181 if (!bn_wexpand(r, BN_NIST_521_TOP))
1184 nist_cp_bn(r_d, a_d, BN_NIST_521_TOP);
1188 /* upper 521 bits, copy ... */
1189 nist_cp_bn_0(t_d, a_d + (BN_NIST_521_TOP - 1),
1190 top - (BN_NIST_521_TOP - 1), BN_NIST_521_TOP);
1191 /* ... and right shift */
1192 for (val = t_d[0], i = 0; i < BN_NIST_521_TOP - 1; i++) {
1195 * MSC ARM compiler [version 2013, presumably even earlier,
1196 * much earlier] miscompiles this code, but not one in
1197 * #else section. See RT#3541.
1199 tmp = val >> BN_NIST_521_RSHIFT;
1201 t_d[i] = (tmp | val << BN_NIST_521_LSHIFT) & BN_MASK2;
1203 t_d[i] = (val >> BN_NIST_521_RSHIFT |
1204 (tmp = t_d[i + 1]) << BN_NIST_521_LSHIFT) & BN_MASK2;
1208 t_d[i] = val >> BN_NIST_521_RSHIFT;
1209 /* lower 521 bits */
1210 r_d[i] &= BN_NIST_521_TOP_MASK;
1212 bn_add_words(r_d, r_d, t_d, BN_NIST_521_TOP);
1213 res = bn_sub_words(t_d, r_d, _nist_p_521,
1217 nist_cp_bn(r_d, res, BN_NIST_521_TOP);
1218 r->top = BN_NIST_521_TOP;
1224 int (*BN_nist_mod_func(const BIGNUM *p)) (BIGNUM *r, const BIGNUM *a,
1225 const BIGNUM *field, BN_CTX *ctx) {
1226 if (BN_ucmp(&ossl_bignum_nist_p_192, p) == 0)
1227 return BN_nist_mod_192;
1228 if (BN_ucmp(&ossl_bignum_nist_p_224, p) == 0)
1229 return BN_nist_mod_224;
1230 if (BN_ucmp(&ossl_bignum_nist_p_256, p) == 0)
1231 return BN_nist_mod_256;
1232 if (BN_ucmp(&ossl_bignum_nist_p_384, p) == 0)
1233 return BN_nist_mod_384;
1234 if (BN_ucmp(&ossl_bignum_nist_p_521, p) == 0)
1235 return BN_nist_mod_521;