1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 2002-2023 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci#include "bn_local.h"
11e1051a39Sopenharmony_ci#include "internal/cryptlib.h"
12e1051a39Sopenharmony_ci
13e1051a39Sopenharmony_ci#define BN_NIST_192_TOP (192+BN_BITS2-1)/BN_BITS2
14e1051a39Sopenharmony_ci#define BN_NIST_224_TOP (224+BN_BITS2-1)/BN_BITS2
15e1051a39Sopenharmony_ci#define BN_NIST_256_TOP (256+BN_BITS2-1)/BN_BITS2
16e1051a39Sopenharmony_ci#define BN_NIST_384_TOP (384+BN_BITS2-1)/BN_BITS2
17e1051a39Sopenharmony_ci#define BN_NIST_521_TOP (521+BN_BITS2-1)/BN_BITS2
18e1051a39Sopenharmony_ci
19e1051a39Sopenharmony_ci/* pre-computed tables are "carry-less" values of modulus*(i+1) */
20e1051a39Sopenharmony_ci#if BN_BITS2 == 64
21e1051a39Sopenharmony_cistatic const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = {
22e1051a39Sopenharmony_ci    {0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFFULL},
23e1051a39Sopenharmony_ci    {0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFFULL},
24e1051a39Sopenharmony_ci    {0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFCULL, 0xFFFFFFFFFFFFFFFFULL}
25e1051a39Sopenharmony_ci};
26e1051a39Sopenharmony_ci
27e1051a39Sopenharmony_cistatic const BN_ULONG _nist_p_192_sqr[] = {
28e1051a39Sopenharmony_ci    0x0000000000000001ULL, 0x0000000000000002ULL, 0x0000000000000001ULL,
29e1051a39Sopenharmony_ci    0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFFULL
30e1051a39Sopenharmony_ci};
31e1051a39Sopenharmony_ci
32e1051a39Sopenharmony_cistatic const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = {
33e1051a39Sopenharmony_ci    {0x0000000000000001ULL, 0xFFFFFFFF00000000ULL,
34e1051a39Sopenharmony_ci     0xFFFFFFFFFFFFFFFFULL, 0x00000000FFFFFFFFULL},
35e1051a39Sopenharmony_ci    {0x0000000000000002ULL, 0xFFFFFFFE00000000ULL,
36e1051a39Sopenharmony_ci     0xFFFFFFFFFFFFFFFFULL, 0x00000001FFFFFFFFULL} /* this one is
37e1051a39Sopenharmony_ci                                                    * "carry-full" */
38e1051a39Sopenharmony_ci};
39e1051a39Sopenharmony_ci
40e1051a39Sopenharmony_cistatic const BN_ULONG _nist_p_224_sqr[] = {
41e1051a39Sopenharmony_ci    0x0000000000000001ULL, 0xFFFFFFFE00000000ULL,
42e1051a39Sopenharmony_ci    0xFFFFFFFFFFFFFFFFULL, 0x0000000200000000ULL,
43e1051a39Sopenharmony_ci    0x0000000000000000ULL, 0xFFFFFFFFFFFFFFFEULL,
44e1051a39Sopenharmony_ci    0xFFFFFFFFFFFFFFFFULL
45e1051a39Sopenharmony_ci};
46e1051a39Sopenharmony_ci
47e1051a39Sopenharmony_cistatic const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = {
48e1051a39Sopenharmony_ci    {0xFFFFFFFFFFFFFFFFULL, 0x00000000FFFFFFFFULL,
49e1051a39Sopenharmony_ci     0x0000000000000000ULL, 0xFFFFFFFF00000001ULL},
50e1051a39Sopenharmony_ci    {0xFFFFFFFFFFFFFFFEULL, 0x00000001FFFFFFFFULL,
51e1051a39Sopenharmony_ci     0x0000000000000000ULL, 0xFFFFFFFE00000002ULL},
52e1051a39Sopenharmony_ci    {0xFFFFFFFFFFFFFFFDULL, 0x00000002FFFFFFFFULL,
53e1051a39Sopenharmony_ci     0x0000000000000000ULL, 0xFFFFFFFD00000003ULL},
54e1051a39Sopenharmony_ci    {0xFFFFFFFFFFFFFFFCULL, 0x00000003FFFFFFFFULL,
55e1051a39Sopenharmony_ci     0x0000000000000000ULL, 0xFFFFFFFC00000004ULL},
56e1051a39Sopenharmony_ci    {0xFFFFFFFFFFFFFFFBULL, 0x00000004FFFFFFFFULL,
57e1051a39Sopenharmony_ci     0x0000000000000000ULL, 0xFFFFFFFB00000005ULL},
58e1051a39Sopenharmony_ci};
59e1051a39Sopenharmony_ci
60e1051a39Sopenharmony_cistatic const BN_ULONG _nist_p_256_sqr[] = {
61e1051a39Sopenharmony_ci    0x0000000000000001ULL, 0xFFFFFFFE00000000ULL,
62e1051a39Sopenharmony_ci    0xFFFFFFFFFFFFFFFFULL, 0x00000001FFFFFFFEULL,
63e1051a39Sopenharmony_ci    0x00000001FFFFFFFEULL, 0x00000001FFFFFFFEULL,
64e1051a39Sopenharmony_ci    0xFFFFFFFE00000001ULL, 0xFFFFFFFE00000002ULL
65e1051a39Sopenharmony_ci};
66e1051a39Sopenharmony_ci
67e1051a39Sopenharmony_cistatic const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = {
68e1051a39Sopenharmony_ci    {0x00000000FFFFFFFFULL, 0xFFFFFFFF00000000ULL, 0xFFFFFFFFFFFFFFFEULL,
69e1051a39Sopenharmony_ci     0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
70e1051a39Sopenharmony_ci    {0x00000001FFFFFFFEULL, 0xFFFFFFFE00000000ULL, 0xFFFFFFFFFFFFFFFDULL,
71e1051a39Sopenharmony_ci     0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
72e1051a39Sopenharmony_ci    {0x00000002FFFFFFFDULL, 0xFFFFFFFD00000000ULL, 0xFFFFFFFFFFFFFFFCULL,
73e1051a39Sopenharmony_ci     0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
74e1051a39Sopenharmony_ci    {0x00000003FFFFFFFCULL, 0xFFFFFFFC00000000ULL, 0xFFFFFFFFFFFFFFFBULL,
75e1051a39Sopenharmony_ci     0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
76e1051a39Sopenharmony_ci    {0x00000004FFFFFFFBULL, 0xFFFFFFFB00000000ULL, 0xFFFFFFFFFFFFFFFAULL,
77e1051a39Sopenharmony_ci     0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
78e1051a39Sopenharmony_ci};
79e1051a39Sopenharmony_ci
80e1051a39Sopenharmony_cistatic const BN_ULONG _nist_p_384_sqr[] = {
81e1051a39Sopenharmony_ci    0xFFFFFFFE00000001ULL, 0x0000000200000000ULL, 0xFFFFFFFE00000000ULL,
82e1051a39Sopenharmony_ci    0x0000000200000000ULL, 0x0000000000000001ULL, 0x0000000000000000ULL,
83e1051a39Sopenharmony_ci    0x00000001FFFFFFFEULL, 0xFFFFFFFE00000000ULL, 0xFFFFFFFFFFFFFFFDULL,
84e1051a39Sopenharmony_ci    0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL
85e1051a39Sopenharmony_ci};
86e1051a39Sopenharmony_ci
87e1051a39Sopenharmony_cistatic const BN_ULONG _nist_p_521[] =
88e1051a39Sopenharmony_ci    { 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
89e1051a39Sopenharmony_ci    0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
90e1051a39Sopenharmony_ci    0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
91e1051a39Sopenharmony_ci    0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
92e1051a39Sopenharmony_ci    0x00000000000001FFULL
93e1051a39Sopenharmony_ci};
94e1051a39Sopenharmony_ci
95e1051a39Sopenharmony_cistatic const BN_ULONG _nist_p_521_sqr[] = {
96e1051a39Sopenharmony_ci    0x0000000000000001ULL, 0x0000000000000000ULL, 0x0000000000000000ULL,
97e1051a39Sopenharmony_ci    0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL,
98e1051a39Sopenharmony_ci    0x0000000000000000ULL, 0x0000000000000000ULL, 0xFFFFFFFFFFFFFC00ULL,
99e1051a39Sopenharmony_ci    0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
100e1051a39Sopenharmony_ci    0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
101e1051a39Sopenharmony_ci    0xFFFFFFFFFFFFFFFFULL, 0x000000000003FFFFULL
102e1051a39Sopenharmony_ci};
103e1051a39Sopenharmony_ci#elif BN_BITS2 == 32
104e1051a39Sopenharmony_cistatic const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = {
105e1051a39Sopenharmony_ci    {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
106e1051a39Sopenharmony_ci    {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
107e1051a39Sopenharmony_ci    {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}
108e1051a39Sopenharmony_ci};
109e1051a39Sopenharmony_ci
110e1051a39Sopenharmony_cistatic const BN_ULONG _nist_p_192_sqr[] = {
111e1051a39Sopenharmony_ci    0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000001, 0x00000000,
112e1051a39Sopenharmony_ci    0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
113e1051a39Sopenharmony_ci};
114e1051a39Sopenharmony_ci
115e1051a39Sopenharmony_cistatic const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = {
116e1051a39Sopenharmony_ci    {0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF,
117e1051a39Sopenharmony_ci     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
118e1051a39Sopenharmony_ci    {0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE,
119e1051a39Sopenharmony_ci     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}
120e1051a39Sopenharmony_ci};
121e1051a39Sopenharmony_ci
122e1051a39Sopenharmony_cistatic const BN_ULONG _nist_p_224_sqr[] = {
123e1051a39Sopenharmony_ci    0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE,
124e1051a39Sopenharmony_ci    0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000002,
125e1051a39Sopenharmony_ci    0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF,
126e1051a39Sopenharmony_ci    0xFFFFFFFF, 0xFFFFFFFF
127e1051a39Sopenharmony_ci};
128e1051a39Sopenharmony_ci
129e1051a39Sopenharmony_cistatic const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = {
130e1051a39Sopenharmony_ci    {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
131e1051a39Sopenharmony_ci     0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF},
132e1051a39Sopenharmony_ci    {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001,
133e1051a39Sopenharmony_ci     0x00000000, 0x00000000, 0x00000002, 0xFFFFFFFE},
134e1051a39Sopenharmony_ci    {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000002,
135e1051a39Sopenharmony_ci     0x00000000, 0x00000000, 0x00000003, 0xFFFFFFFD},
136e1051a39Sopenharmony_ci    {0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000003,
137e1051a39Sopenharmony_ci     0x00000000, 0x00000000, 0x00000004, 0xFFFFFFFC},
138e1051a39Sopenharmony_ci    {0xFFFFFFFB, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000004,
139e1051a39Sopenharmony_ci     0x00000000, 0x00000000, 0x00000005, 0xFFFFFFFB},
140e1051a39Sopenharmony_ci};
141e1051a39Sopenharmony_ci
142e1051a39Sopenharmony_cistatic const BN_ULONG _nist_p_256_sqr[] = {
143e1051a39Sopenharmony_ci    0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE,
144e1051a39Sopenharmony_ci    0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001,
145e1051a39Sopenharmony_ci    0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001,
146e1051a39Sopenharmony_ci    0x00000001, 0xFFFFFFFE, 0x00000002, 0xFFFFFFFE
147e1051a39Sopenharmony_ci};
148e1051a39Sopenharmony_ci
149e1051a39Sopenharmony_cistatic const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = {
150e1051a39Sopenharmony_ci    {0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF,
151e1051a39Sopenharmony_ci     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
152e1051a39Sopenharmony_ci    {0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF,
153e1051a39Sopenharmony_ci     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
154e1051a39Sopenharmony_ci    {0xFFFFFFFD, 0x00000002, 0x00000000, 0xFFFFFFFD, 0xFFFFFFFC, 0xFFFFFFFF,
155e1051a39Sopenharmony_ci     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
156e1051a39Sopenharmony_ci    {0xFFFFFFFC, 0x00000003, 0x00000000, 0xFFFFFFFC, 0xFFFFFFFB, 0xFFFFFFFF,
157e1051a39Sopenharmony_ci     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
158e1051a39Sopenharmony_ci    {0xFFFFFFFB, 0x00000004, 0x00000000, 0xFFFFFFFB, 0xFFFFFFFA, 0xFFFFFFFF,
159e1051a39Sopenharmony_ci     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
160e1051a39Sopenharmony_ci};
161e1051a39Sopenharmony_ci
162e1051a39Sopenharmony_cistatic const BN_ULONG _nist_p_384_sqr[] = {
163e1051a39Sopenharmony_ci    0x00000001, 0xFFFFFFFE, 0x00000000, 0x00000002, 0x00000000, 0xFFFFFFFE,
164e1051a39Sopenharmony_ci    0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
165e1051a39Sopenharmony_ci    0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF,
166e1051a39Sopenharmony_ci    0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
167e1051a39Sopenharmony_ci};
168e1051a39Sopenharmony_ci
169e1051a39Sopenharmony_cistatic const BN_ULONG _nist_p_521[] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
170e1051a39Sopenharmony_ci    0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
171e1051a39Sopenharmony_ci    0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
172e1051a39Sopenharmony_ci    0xFFFFFFFF, 0x000001FF
173e1051a39Sopenharmony_ci};
174e1051a39Sopenharmony_ci
175e1051a39Sopenharmony_cistatic const BN_ULONG _nist_p_521_sqr[] = {
176e1051a39Sopenharmony_ci    0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
177e1051a39Sopenharmony_ci    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
178e1051a39Sopenharmony_ci    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFC00, 0xFFFFFFFF,
179e1051a39Sopenharmony_ci    0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
180e1051a39Sopenharmony_ci    0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
181e1051a39Sopenharmony_ci    0xFFFFFFFF, 0xFFFFFFFF, 0x0003FFFF
182e1051a39Sopenharmony_ci};
183e1051a39Sopenharmony_ci#else
184e1051a39Sopenharmony_ci# error "unsupported BN_BITS2"
185e1051a39Sopenharmony_ci#endif
186e1051a39Sopenharmony_ci
187e1051a39Sopenharmony_cistatic const BIGNUM ossl_bignum_nist_p_192 = {
188e1051a39Sopenharmony_ci    (BN_ULONG *)_nist_p_192[0],
189e1051a39Sopenharmony_ci    BN_NIST_192_TOP,
190e1051a39Sopenharmony_ci    BN_NIST_192_TOP,
191e1051a39Sopenharmony_ci    0,
192e1051a39Sopenharmony_ci    BN_FLG_STATIC_DATA
193e1051a39Sopenharmony_ci};
194e1051a39Sopenharmony_ci
195e1051a39Sopenharmony_cistatic const BIGNUM ossl_bignum_nist_p_224 = {
196e1051a39Sopenharmony_ci    (BN_ULONG *)_nist_p_224[0],
197e1051a39Sopenharmony_ci    BN_NIST_224_TOP,
198e1051a39Sopenharmony_ci    BN_NIST_224_TOP,
199e1051a39Sopenharmony_ci    0,
200e1051a39Sopenharmony_ci    BN_FLG_STATIC_DATA
201e1051a39Sopenharmony_ci};
202e1051a39Sopenharmony_ci
203e1051a39Sopenharmony_cistatic const BIGNUM ossl_bignum_nist_p_256 = {
204e1051a39Sopenharmony_ci    (BN_ULONG *)_nist_p_256[0],
205e1051a39Sopenharmony_ci    BN_NIST_256_TOP,
206e1051a39Sopenharmony_ci    BN_NIST_256_TOP,
207e1051a39Sopenharmony_ci    0,
208e1051a39Sopenharmony_ci    BN_FLG_STATIC_DATA
209e1051a39Sopenharmony_ci};
210e1051a39Sopenharmony_ci
211e1051a39Sopenharmony_cistatic const BIGNUM ossl_bignum_nist_p_384 = {
212e1051a39Sopenharmony_ci    (BN_ULONG *)_nist_p_384[0],
213e1051a39Sopenharmony_ci    BN_NIST_384_TOP,
214e1051a39Sopenharmony_ci    BN_NIST_384_TOP,
215e1051a39Sopenharmony_ci    0,
216e1051a39Sopenharmony_ci    BN_FLG_STATIC_DATA
217e1051a39Sopenharmony_ci};
218e1051a39Sopenharmony_ci
219e1051a39Sopenharmony_cistatic const BIGNUM ossl_bignum_nist_p_521 = {
220e1051a39Sopenharmony_ci    (BN_ULONG *)_nist_p_521,
221e1051a39Sopenharmony_ci    BN_NIST_521_TOP,
222e1051a39Sopenharmony_ci    BN_NIST_521_TOP,
223e1051a39Sopenharmony_ci    0,
224e1051a39Sopenharmony_ci    BN_FLG_STATIC_DATA
225e1051a39Sopenharmony_ci};
226e1051a39Sopenharmony_ci
227e1051a39Sopenharmony_ciconst BIGNUM *BN_get0_nist_prime_192(void)
228e1051a39Sopenharmony_ci{
229e1051a39Sopenharmony_ci    return &ossl_bignum_nist_p_192;
230e1051a39Sopenharmony_ci}
231e1051a39Sopenharmony_ci
232e1051a39Sopenharmony_ciconst BIGNUM *BN_get0_nist_prime_224(void)
233e1051a39Sopenharmony_ci{
234e1051a39Sopenharmony_ci    return &ossl_bignum_nist_p_224;
235e1051a39Sopenharmony_ci}
236e1051a39Sopenharmony_ci
237e1051a39Sopenharmony_ciconst BIGNUM *BN_get0_nist_prime_256(void)
238e1051a39Sopenharmony_ci{
239e1051a39Sopenharmony_ci    return &ossl_bignum_nist_p_256;
240e1051a39Sopenharmony_ci}
241e1051a39Sopenharmony_ci
242e1051a39Sopenharmony_ciconst BIGNUM *BN_get0_nist_prime_384(void)
243e1051a39Sopenharmony_ci{
244e1051a39Sopenharmony_ci    return &ossl_bignum_nist_p_384;
245e1051a39Sopenharmony_ci}
246e1051a39Sopenharmony_ci
247e1051a39Sopenharmony_ciconst BIGNUM *BN_get0_nist_prime_521(void)
248e1051a39Sopenharmony_ci{
249e1051a39Sopenharmony_ci    return &ossl_bignum_nist_p_521;
250e1051a39Sopenharmony_ci}
251e1051a39Sopenharmony_ci
252e1051a39Sopenharmony_ci/*
253e1051a39Sopenharmony_ci * To avoid more recent compilers (specifically clang-14) from treating this
254e1051a39Sopenharmony_ci * code as a violation of the strict aliasing conditions and omiting it, this
255e1051a39Sopenharmony_ci * cannot be declared as a function.  Moreover, the dst parameter cannot be
256e1051a39Sopenharmony_ci * cached in a local since this no longer references the union and again falls
257e1051a39Sopenharmony_ci * foul of the strict aliasing criteria.  Refer to #18225 for the initial
258e1051a39Sopenharmony_ci * diagnostics and llvm/llvm-project#55255 for the later discussions with the
259e1051a39Sopenharmony_ci * LLVM developers.  The problem boils down to if an array in the union is
260e1051a39Sopenharmony_ci * converted to a pointer or if it is used directly.
261e1051a39Sopenharmony_ci *
262e1051a39Sopenharmony_ci * This function was inlined regardless, so there is no space cost to be
263e1051a39Sopenharmony_ci * paid for making it a macro.
264e1051a39Sopenharmony_ci */
265e1051a39Sopenharmony_ci#define nist_cp_bn_0(dst, src_in, top, max) \
266e1051a39Sopenharmony_ci{                                           \
267e1051a39Sopenharmony_ci    int ii;                                 \
268e1051a39Sopenharmony_ci    const BN_ULONG *src = src_in;           \
269e1051a39Sopenharmony_ci                                            \
270e1051a39Sopenharmony_ci    for (ii = 0; ii < top; ii++)            \
271e1051a39Sopenharmony_ci        (dst)[ii] = src[ii];                \
272e1051a39Sopenharmony_ci    for (; ii < max; ii++)                  \
273e1051a39Sopenharmony_ci        (dst)[ii] = 0;                      \
274e1051a39Sopenharmony_ci}
275e1051a39Sopenharmony_ci
276e1051a39Sopenharmony_cistatic void nist_cp_bn(BN_ULONG *dst, const BN_ULONG *src, int top)
277e1051a39Sopenharmony_ci{
278e1051a39Sopenharmony_ci    int i;
279e1051a39Sopenharmony_ci
280e1051a39Sopenharmony_ci    for (i = 0; i < top; i++)
281e1051a39Sopenharmony_ci        dst[i] = src[i];
282e1051a39Sopenharmony_ci}
283e1051a39Sopenharmony_ci
284e1051a39Sopenharmony_ci#if BN_BITS2 == 64
285e1051a39Sopenharmony_ci# define bn_cp_64(to, n, from, m)        (to)[n] = (m>=0)?((from)[m]):0;
286e1051a39Sopenharmony_ci# define bn_64_set_0(to, n)              (to)[n] = (BN_ULONG)0;
287e1051a39Sopenharmony_ci/*
288e1051a39Sopenharmony_ci * two following macros are implemented under assumption that they
289e1051a39Sopenharmony_ci * are called in a sequence with *ascending* n, i.e. as they are...
290e1051a39Sopenharmony_ci */
291e1051a39Sopenharmony_ci# 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))\
292e1051a39Sopenharmony_ci                                                :(to[(n)/2] =((m)&1)?(from[(m)/2]>>32):(from[(m)/2]&BN_MASK2l)))
293e1051a39Sopenharmony_ci# define bn_32_set_0(to, n)              (((n)&1)?(to[(n)/2]&=BN_MASK2l):(to[(n)/2]=0));
294e1051a39Sopenharmony_ci# define bn_cp_32(to,n,from,m)           ((m)>=0)?bn_cp_32_naked(to,n,from,m):bn_32_set_0(to,n)
295e1051a39Sopenharmony_ci# if defined(L_ENDIAN)
296e1051a39Sopenharmony_ci#  if defined(__arch64__)
297e1051a39Sopenharmony_ci#   define NIST_INT64 long
298e1051a39Sopenharmony_ci#  else
299e1051a39Sopenharmony_ci#   define NIST_INT64 long long
300e1051a39Sopenharmony_ci#  endif
301e1051a39Sopenharmony_ci# endif
302e1051a39Sopenharmony_ci#else
303e1051a39Sopenharmony_ci# define bn_cp_64(to, n, from, m) \
304e1051a39Sopenharmony_ci        { \
305e1051a39Sopenharmony_ci        bn_cp_32(to, (n)*2, from, (m)*2); \
306e1051a39Sopenharmony_ci        bn_cp_32(to, (n)*2+1, from, (m)*2+1); \
307e1051a39Sopenharmony_ci        }
308e1051a39Sopenharmony_ci# define bn_64_set_0(to, n) \
309e1051a39Sopenharmony_ci        { \
310e1051a39Sopenharmony_ci        bn_32_set_0(to, (n)*2); \
311e1051a39Sopenharmony_ci        bn_32_set_0(to, (n)*2+1); \
312e1051a39Sopenharmony_ci        }
313e1051a39Sopenharmony_ci# define bn_cp_32(to, n, from, m)        (to)[n] = (m>=0)?((from)[m]):0;
314e1051a39Sopenharmony_ci# define bn_32_set_0(to, n)              (to)[n] = (BN_ULONG)0;
315e1051a39Sopenharmony_ci# if defined(_WIN32) && !defined(__GNUC__)
316e1051a39Sopenharmony_ci#  define NIST_INT64 __int64
317e1051a39Sopenharmony_ci# elif defined(BN_LLONG)
318e1051a39Sopenharmony_ci#  define NIST_INT64 long long
319e1051a39Sopenharmony_ci# endif
320e1051a39Sopenharmony_ci#endif                          /* BN_BITS2 != 64 */
321e1051a39Sopenharmony_ci
322e1051a39Sopenharmony_ci#define nist_set_192(to, from, a1, a2, a3) \
323e1051a39Sopenharmony_ci        { \
324e1051a39Sopenharmony_ci        bn_cp_64(to, 0, from, (a3) - 3) \
325e1051a39Sopenharmony_ci        bn_cp_64(to, 1, from, (a2) - 3) \
326e1051a39Sopenharmony_ci        bn_cp_64(to, 2, from, (a1) - 3) \
327e1051a39Sopenharmony_ci        }
328e1051a39Sopenharmony_ci
329e1051a39Sopenharmony_ciint BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
330e1051a39Sopenharmony_ci                    BN_CTX *ctx)
331e1051a39Sopenharmony_ci{
332e1051a39Sopenharmony_ci    int top = a->top, i;
333e1051a39Sopenharmony_ci    int carry;
334e1051a39Sopenharmony_ci    register BN_ULONG *r_d, *a_d = a->d;
335e1051a39Sopenharmony_ci    union {
336e1051a39Sopenharmony_ci        BN_ULONG bn[BN_NIST_192_TOP];
337e1051a39Sopenharmony_ci        unsigned int ui[BN_NIST_192_TOP * sizeof(BN_ULONG) /
338e1051a39Sopenharmony_ci                        sizeof(unsigned int)];
339e1051a39Sopenharmony_ci    } buf;
340e1051a39Sopenharmony_ci    BN_ULONG c_d[BN_NIST_192_TOP], *res;
341e1051a39Sopenharmony_ci    static const BIGNUM ossl_bignum_nist_p_192_sqr = {
342e1051a39Sopenharmony_ci        (BN_ULONG *)_nist_p_192_sqr,
343e1051a39Sopenharmony_ci        OSSL_NELEM(_nist_p_192_sqr),
344e1051a39Sopenharmony_ci        OSSL_NELEM(_nist_p_192_sqr),
345e1051a39Sopenharmony_ci        0, BN_FLG_STATIC_DATA
346e1051a39Sopenharmony_ci    };
347e1051a39Sopenharmony_ci
348e1051a39Sopenharmony_ci    field = &ossl_bignum_nist_p_192; /* just to make sure */
349e1051a39Sopenharmony_ci
350e1051a39Sopenharmony_ci    if (BN_is_negative(a) || BN_ucmp(a, &ossl_bignum_nist_p_192_sqr) >= 0)
351e1051a39Sopenharmony_ci        return BN_nnmod(r, a, field, ctx);
352e1051a39Sopenharmony_ci
353e1051a39Sopenharmony_ci    i = BN_ucmp(field, a);
354e1051a39Sopenharmony_ci    if (i == 0) {
355e1051a39Sopenharmony_ci        BN_zero(r);
356e1051a39Sopenharmony_ci        return 1;
357e1051a39Sopenharmony_ci    } else if (i > 0)
358e1051a39Sopenharmony_ci        return (r == a) ? 1 : (BN_copy(r, a) != NULL);
359e1051a39Sopenharmony_ci
360e1051a39Sopenharmony_ci    if (r != a) {
361e1051a39Sopenharmony_ci        if (!bn_wexpand(r, BN_NIST_192_TOP))
362e1051a39Sopenharmony_ci            return 0;
363e1051a39Sopenharmony_ci        r_d = r->d;
364e1051a39Sopenharmony_ci        nist_cp_bn(r_d, a_d, BN_NIST_192_TOP);
365e1051a39Sopenharmony_ci    } else
366e1051a39Sopenharmony_ci        r_d = a_d;
367e1051a39Sopenharmony_ci
368e1051a39Sopenharmony_ci    nist_cp_bn_0(buf.bn, a_d + BN_NIST_192_TOP, top - BN_NIST_192_TOP,
369e1051a39Sopenharmony_ci                 BN_NIST_192_TOP);
370e1051a39Sopenharmony_ci
371e1051a39Sopenharmony_ci#if defined(NIST_INT64)
372e1051a39Sopenharmony_ci    {
373e1051a39Sopenharmony_ci        NIST_INT64 acc;         /* accumulator */
374e1051a39Sopenharmony_ci        unsigned int *rp = (unsigned int *)r_d;
375e1051a39Sopenharmony_ci        const unsigned int *bp = (const unsigned int *)buf.ui;
376e1051a39Sopenharmony_ci
377e1051a39Sopenharmony_ci        acc = rp[0];
378e1051a39Sopenharmony_ci        acc += bp[3 * 2 - 6];
379e1051a39Sopenharmony_ci        acc += bp[5 * 2 - 6];
380e1051a39Sopenharmony_ci        rp[0] = (unsigned int)acc;
381e1051a39Sopenharmony_ci        acc >>= 32;
382e1051a39Sopenharmony_ci
383e1051a39Sopenharmony_ci        acc += rp[1];
384e1051a39Sopenharmony_ci        acc += bp[3 * 2 - 5];
385e1051a39Sopenharmony_ci        acc += bp[5 * 2 - 5];
386e1051a39Sopenharmony_ci        rp[1] = (unsigned int)acc;
387e1051a39Sopenharmony_ci        acc >>= 32;
388e1051a39Sopenharmony_ci
389e1051a39Sopenharmony_ci        acc += rp[2];
390e1051a39Sopenharmony_ci        acc += bp[3 * 2 - 6];
391e1051a39Sopenharmony_ci        acc += bp[4 * 2 - 6];
392e1051a39Sopenharmony_ci        acc += bp[5 * 2 - 6];
393e1051a39Sopenharmony_ci        rp[2] = (unsigned int)acc;
394e1051a39Sopenharmony_ci        acc >>= 32;
395e1051a39Sopenharmony_ci
396e1051a39Sopenharmony_ci        acc += rp[3];
397e1051a39Sopenharmony_ci        acc += bp[3 * 2 - 5];
398e1051a39Sopenharmony_ci        acc += bp[4 * 2 - 5];
399e1051a39Sopenharmony_ci        acc += bp[5 * 2 - 5];
400e1051a39Sopenharmony_ci        rp[3] = (unsigned int)acc;
401e1051a39Sopenharmony_ci        acc >>= 32;
402e1051a39Sopenharmony_ci
403e1051a39Sopenharmony_ci        acc += rp[4];
404e1051a39Sopenharmony_ci        acc += bp[4 * 2 - 6];
405e1051a39Sopenharmony_ci        acc += bp[5 * 2 - 6];
406e1051a39Sopenharmony_ci        rp[4] = (unsigned int)acc;
407e1051a39Sopenharmony_ci        acc >>= 32;
408e1051a39Sopenharmony_ci
409e1051a39Sopenharmony_ci        acc += rp[5];
410e1051a39Sopenharmony_ci        acc += bp[4 * 2 - 5];
411e1051a39Sopenharmony_ci        acc += bp[5 * 2 - 5];
412e1051a39Sopenharmony_ci        rp[5] = (unsigned int)acc;
413e1051a39Sopenharmony_ci
414e1051a39Sopenharmony_ci        carry = (int)(acc >> 32);
415e1051a39Sopenharmony_ci    }
416e1051a39Sopenharmony_ci#else
417e1051a39Sopenharmony_ci    {
418e1051a39Sopenharmony_ci        BN_ULONG t_d[BN_NIST_192_TOP];
419e1051a39Sopenharmony_ci
420e1051a39Sopenharmony_ci        nist_set_192(t_d, buf.bn, 0, 3, 3);
421e1051a39Sopenharmony_ci        carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
422e1051a39Sopenharmony_ci        nist_set_192(t_d, buf.bn, 4, 4, 0);
423e1051a39Sopenharmony_ci        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
424e1051a39Sopenharmony_ci        nist_set_192(t_d, buf.bn, 5, 5, 5)
425e1051a39Sopenharmony_ci            carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
426e1051a39Sopenharmony_ci    }
427e1051a39Sopenharmony_ci#endif
428e1051a39Sopenharmony_ci    if (carry > 0)
429e1051a39Sopenharmony_ci        carry =
430e1051a39Sopenharmony_ci            (int)bn_sub_words(r_d, r_d, _nist_p_192[carry - 1],
431e1051a39Sopenharmony_ci                              BN_NIST_192_TOP);
432e1051a39Sopenharmony_ci    else
433e1051a39Sopenharmony_ci        carry = 1;
434e1051a39Sopenharmony_ci
435e1051a39Sopenharmony_ci    /*
436e1051a39Sopenharmony_ci     * we need 'if (carry==0 || result>=modulus) result-=modulus;'
437e1051a39Sopenharmony_ci     * as comparison implies subtraction, we can write
438e1051a39Sopenharmony_ci     * 'tmp=result-modulus; if (!carry || !borrow) result=tmp;'
439e1051a39Sopenharmony_ci     * this is what happens below, but without explicit if:-) a.
440e1051a39Sopenharmony_ci     */
441e1051a39Sopenharmony_ci    res = (bn_sub_words(c_d, r_d, _nist_p_192[0], BN_NIST_192_TOP) && carry)
442e1051a39Sopenharmony_ci        ? r_d
443e1051a39Sopenharmony_ci        : c_d;
444e1051a39Sopenharmony_ci    nist_cp_bn(r_d, res, BN_NIST_192_TOP);
445e1051a39Sopenharmony_ci    r->top = BN_NIST_192_TOP;
446e1051a39Sopenharmony_ci    bn_correct_top(r);
447e1051a39Sopenharmony_ci
448e1051a39Sopenharmony_ci    return 1;
449e1051a39Sopenharmony_ci}
450e1051a39Sopenharmony_ci
451e1051a39Sopenharmony_citypedef BN_ULONG (*bn_addsub_f) (BN_ULONG *, const BN_ULONG *,
452e1051a39Sopenharmony_ci                                 const BN_ULONG *, int);
453e1051a39Sopenharmony_ci
454e1051a39Sopenharmony_ci#define nist_set_224(to, from, a1, a2, a3, a4, a5, a6, a7) \
455e1051a39Sopenharmony_ci        { \
456e1051a39Sopenharmony_ci        bn_cp_32(to, 0, from, (a7) - 7) \
457e1051a39Sopenharmony_ci        bn_cp_32(to, 1, from, (a6) - 7) \
458e1051a39Sopenharmony_ci        bn_cp_32(to, 2, from, (a5) - 7) \
459e1051a39Sopenharmony_ci        bn_cp_32(to, 3, from, (a4) - 7) \
460e1051a39Sopenharmony_ci        bn_cp_32(to, 4, from, (a3) - 7) \
461e1051a39Sopenharmony_ci        bn_cp_32(to, 5, from, (a2) - 7) \
462e1051a39Sopenharmony_ci        bn_cp_32(to, 6, from, (a1) - 7) \
463e1051a39Sopenharmony_ci        }
464e1051a39Sopenharmony_ci
465e1051a39Sopenharmony_ciint BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
466e1051a39Sopenharmony_ci                    BN_CTX *ctx)
467e1051a39Sopenharmony_ci{
468e1051a39Sopenharmony_ci    int top = a->top, i;
469e1051a39Sopenharmony_ci    int carry;
470e1051a39Sopenharmony_ci    BN_ULONG *r_d, *a_d = a->d;
471e1051a39Sopenharmony_ci    union {
472e1051a39Sopenharmony_ci        BN_ULONG bn[BN_NIST_224_TOP];
473e1051a39Sopenharmony_ci        unsigned int ui[BN_NIST_224_TOP * sizeof(BN_ULONG) /
474e1051a39Sopenharmony_ci                        sizeof(unsigned int)];
475e1051a39Sopenharmony_ci    } buf;
476e1051a39Sopenharmony_ci    BN_ULONG c_d[BN_NIST_224_TOP], *res;
477e1051a39Sopenharmony_ci    bn_addsub_f adjust;
478e1051a39Sopenharmony_ci    static const BIGNUM ossl_bignum_nist_p_224_sqr = {
479e1051a39Sopenharmony_ci        (BN_ULONG *)_nist_p_224_sqr,
480e1051a39Sopenharmony_ci        OSSL_NELEM(_nist_p_224_sqr),
481e1051a39Sopenharmony_ci        OSSL_NELEM(_nist_p_224_sqr),
482e1051a39Sopenharmony_ci        0, BN_FLG_STATIC_DATA
483e1051a39Sopenharmony_ci    };
484e1051a39Sopenharmony_ci
485e1051a39Sopenharmony_ci    field = &ossl_bignum_nist_p_224; /* just to make sure */
486e1051a39Sopenharmony_ci
487e1051a39Sopenharmony_ci    if (BN_is_negative(a) || BN_ucmp(a, &ossl_bignum_nist_p_224_sqr) >= 0)
488e1051a39Sopenharmony_ci        return BN_nnmod(r, a, field, ctx);
489e1051a39Sopenharmony_ci
490e1051a39Sopenharmony_ci    i = BN_ucmp(field, a);
491e1051a39Sopenharmony_ci    if (i == 0) {
492e1051a39Sopenharmony_ci        BN_zero(r);
493e1051a39Sopenharmony_ci        return 1;
494e1051a39Sopenharmony_ci    } else if (i > 0)
495e1051a39Sopenharmony_ci        return (r == a) ? 1 : (BN_copy(r, a) != NULL);
496e1051a39Sopenharmony_ci
497e1051a39Sopenharmony_ci    if (r != a) {
498e1051a39Sopenharmony_ci        if (!bn_wexpand(r, BN_NIST_224_TOP))
499e1051a39Sopenharmony_ci            return 0;
500e1051a39Sopenharmony_ci        r_d = r->d;
501e1051a39Sopenharmony_ci        nist_cp_bn(r_d, a_d, BN_NIST_224_TOP);
502e1051a39Sopenharmony_ci    } else
503e1051a39Sopenharmony_ci        r_d = a_d;
504e1051a39Sopenharmony_ci
505e1051a39Sopenharmony_ci#if BN_BITS2==64
506e1051a39Sopenharmony_ci    /* copy upper 256 bits of 448 bit number ... */
507e1051a39Sopenharmony_ci    nist_cp_bn_0(c_d, a_d + (BN_NIST_224_TOP - 1),
508e1051a39Sopenharmony_ci                 top - (BN_NIST_224_TOP - 1), BN_NIST_224_TOP);
509e1051a39Sopenharmony_ci    /* ... and right shift by 32 to obtain upper 224 bits */
510e1051a39Sopenharmony_ci    nist_set_224(buf.bn, c_d, 14, 13, 12, 11, 10, 9, 8);
511e1051a39Sopenharmony_ci    /* truncate lower part to 224 bits too */
512e1051a39Sopenharmony_ci    r_d[BN_NIST_224_TOP - 1] &= BN_MASK2l;
513e1051a39Sopenharmony_ci#else
514e1051a39Sopenharmony_ci    nist_cp_bn_0(buf.bn, a_d + BN_NIST_224_TOP, top - BN_NIST_224_TOP,
515e1051a39Sopenharmony_ci                 BN_NIST_224_TOP);
516e1051a39Sopenharmony_ci#endif
517e1051a39Sopenharmony_ci
518e1051a39Sopenharmony_ci#if defined(NIST_INT64) && BN_BITS2!=64
519e1051a39Sopenharmony_ci    {
520e1051a39Sopenharmony_ci        NIST_INT64 acc;         /* accumulator */
521e1051a39Sopenharmony_ci        unsigned int *rp = (unsigned int *)r_d;
522e1051a39Sopenharmony_ci        const unsigned int *bp = (const unsigned int *)buf.ui;
523e1051a39Sopenharmony_ci
524e1051a39Sopenharmony_ci        acc = rp[0];
525e1051a39Sopenharmony_ci        acc -= bp[7 - 7];
526e1051a39Sopenharmony_ci        acc -= bp[11 - 7];
527e1051a39Sopenharmony_ci        rp[0] = (unsigned int)acc;
528e1051a39Sopenharmony_ci        acc >>= 32;
529e1051a39Sopenharmony_ci
530e1051a39Sopenharmony_ci        acc += rp[1];
531e1051a39Sopenharmony_ci        acc -= bp[8 - 7];
532e1051a39Sopenharmony_ci        acc -= bp[12 - 7];
533e1051a39Sopenharmony_ci        rp[1] = (unsigned int)acc;
534e1051a39Sopenharmony_ci        acc >>= 32;
535e1051a39Sopenharmony_ci
536e1051a39Sopenharmony_ci        acc += rp[2];
537e1051a39Sopenharmony_ci        acc -= bp[9 - 7];
538e1051a39Sopenharmony_ci        acc -= bp[13 - 7];
539e1051a39Sopenharmony_ci        rp[2] = (unsigned int)acc;
540e1051a39Sopenharmony_ci        acc >>= 32;
541e1051a39Sopenharmony_ci
542e1051a39Sopenharmony_ci        acc += rp[3];
543e1051a39Sopenharmony_ci        acc += bp[7 - 7];
544e1051a39Sopenharmony_ci        acc += bp[11 - 7];
545e1051a39Sopenharmony_ci        acc -= bp[10 - 7];
546e1051a39Sopenharmony_ci        rp[3] = (unsigned int)acc;
547e1051a39Sopenharmony_ci        acc >>= 32;
548e1051a39Sopenharmony_ci
549e1051a39Sopenharmony_ci        acc += rp[4];
550e1051a39Sopenharmony_ci        acc += bp[8 - 7];
551e1051a39Sopenharmony_ci        acc += bp[12 - 7];
552e1051a39Sopenharmony_ci        acc -= bp[11 - 7];
553e1051a39Sopenharmony_ci        rp[4] = (unsigned int)acc;
554e1051a39Sopenharmony_ci        acc >>= 32;
555e1051a39Sopenharmony_ci
556e1051a39Sopenharmony_ci        acc += rp[5];
557e1051a39Sopenharmony_ci        acc += bp[9 - 7];
558e1051a39Sopenharmony_ci        acc += bp[13 - 7];
559e1051a39Sopenharmony_ci        acc -= bp[12 - 7];
560e1051a39Sopenharmony_ci        rp[5] = (unsigned int)acc;
561e1051a39Sopenharmony_ci        acc >>= 32;
562e1051a39Sopenharmony_ci
563e1051a39Sopenharmony_ci        acc += rp[6];
564e1051a39Sopenharmony_ci        acc += bp[10 - 7];
565e1051a39Sopenharmony_ci        acc -= bp[13 - 7];
566e1051a39Sopenharmony_ci        rp[6] = (unsigned int)acc;
567e1051a39Sopenharmony_ci
568e1051a39Sopenharmony_ci        carry = (int)(acc >> 32);
569e1051a39Sopenharmony_ci# if BN_BITS2==64
570e1051a39Sopenharmony_ci        rp[7] = carry;
571e1051a39Sopenharmony_ci# endif
572e1051a39Sopenharmony_ci    }
573e1051a39Sopenharmony_ci#else
574e1051a39Sopenharmony_ci    {
575e1051a39Sopenharmony_ci        BN_ULONG t_d[BN_NIST_224_TOP];
576e1051a39Sopenharmony_ci
577e1051a39Sopenharmony_ci        nist_set_224(t_d, buf.bn, 10, 9, 8, 7, 0, 0, 0);
578e1051a39Sopenharmony_ci        carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP);
579e1051a39Sopenharmony_ci        nist_set_224(t_d, buf.bn, 0, 13, 12, 11, 0, 0, 0);
580e1051a39Sopenharmony_ci        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP);
581e1051a39Sopenharmony_ci        nist_set_224(t_d, buf.bn, 13, 12, 11, 10, 9, 8, 7);
582e1051a39Sopenharmony_ci        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP);
583e1051a39Sopenharmony_ci        nist_set_224(t_d, buf.bn, 0, 0, 0, 0, 13, 12, 11);
584e1051a39Sopenharmony_ci        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP);
585e1051a39Sopenharmony_ci
586e1051a39Sopenharmony_ci# if BN_BITS2==64
587e1051a39Sopenharmony_ci        carry = (int)(r_d[BN_NIST_224_TOP - 1] >> 32);
588e1051a39Sopenharmony_ci# endif
589e1051a39Sopenharmony_ci    }
590e1051a39Sopenharmony_ci#endif
591e1051a39Sopenharmony_ci    adjust = bn_sub_words;
592e1051a39Sopenharmony_ci    if (carry > 0) {
593e1051a39Sopenharmony_ci        carry =
594e1051a39Sopenharmony_ci            (int)bn_sub_words(r_d, r_d, _nist_p_224[carry - 1],
595e1051a39Sopenharmony_ci                              BN_NIST_224_TOP);
596e1051a39Sopenharmony_ci#if BN_BITS2==64
597e1051a39Sopenharmony_ci        carry = (int)(~(r_d[BN_NIST_224_TOP - 1] >> 32)) & 1;
598e1051a39Sopenharmony_ci#endif
599e1051a39Sopenharmony_ci    } else if (carry < 0) {
600e1051a39Sopenharmony_ci        /*
601e1051a39Sopenharmony_ci         * it's a bit more complicated logic in this case. if bn_add_words
602e1051a39Sopenharmony_ci         * yields no carry, then result has to be adjusted by unconditionally
603e1051a39Sopenharmony_ci         * *adding* the modulus. but if it does, then result has to be
604e1051a39Sopenharmony_ci         * compared to the modulus and conditionally adjusted by
605e1051a39Sopenharmony_ci         * *subtracting* the latter.
606e1051a39Sopenharmony_ci         */
607e1051a39Sopenharmony_ci        carry =
608e1051a39Sopenharmony_ci            (int)bn_add_words(r_d, r_d, _nist_p_224[-carry - 1],
609e1051a39Sopenharmony_ci                              BN_NIST_224_TOP);
610e1051a39Sopenharmony_ci        adjust = carry ? bn_sub_words : bn_add_words;
611e1051a39Sopenharmony_ci    } else
612e1051a39Sopenharmony_ci        carry = 1;
613e1051a39Sopenharmony_ci
614e1051a39Sopenharmony_ci    /* otherwise it's effectively same as in BN_nist_mod_192... */
615e1051a39Sopenharmony_ci    res = ((*adjust) (c_d, r_d, _nist_p_224[0], BN_NIST_224_TOP) && carry)
616e1051a39Sopenharmony_ci        ? r_d
617e1051a39Sopenharmony_ci        : c_d;
618e1051a39Sopenharmony_ci    nist_cp_bn(r_d, res, BN_NIST_224_TOP);
619e1051a39Sopenharmony_ci    r->top = BN_NIST_224_TOP;
620e1051a39Sopenharmony_ci    bn_correct_top(r);
621e1051a39Sopenharmony_ci
622e1051a39Sopenharmony_ci    return 1;
623e1051a39Sopenharmony_ci}
624e1051a39Sopenharmony_ci
625e1051a39Sopenharmony_ci#define nist_set_256(to, from, a1, a2, a3, a4, a5, a6, a7, a8) \
626e1051a39Sopenharmony_ci        { \
627e1051a39Sopenharmony_ci        bn_cp_32(to, 0, from, (a8) - 8) \
628e1051a39Sopenharmony_ci        bn_cp_32(to, 1, from, (a7) - 8) \
629e1051a39Sopenharmony_ci        bn_cp_32(to, 2, from, (a6) - 8) \
630e1051a39Sopenharmony_ci        bn_cp_32(to, 3, from, (a5) - 8) \
631e1051a39Sopenharmony_ci        bn_cp_32(to, 4, from, (a4) - 8) \
632e1051a39Sopenharmony_ci        bn_cp_32(to, 5, from, (a3) - 8) \
633e1051a39Sopenharmony_ci        bn_cp_32(to, 6, from, (a2) - 8) \
634e1051a39Sopenharmony_ci        bn_cp_32(to, 7, from, (a1) - 8) \
635e1051a39Sopenharmony_ci        }
636e1051a39Sopenharmony_ci
637e1051a39Sopenharmony_ciint BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
638e1051a39Sopenharmony_ci                    BN_CTX *ctx)
639e1051a39Sopenharmony_ci{
640e1051a39Sopenharmony_ci    int i, top = a->top;
641e1051a39Sopenharmony_ci    int carry = 0;
642e1051a39Sopenharmony_ci    register BN_ULONG *a_d = a->d, *r_d;
643e1051a39Sopenharmony_ci    union {
644e1051a39Sopenharmony_ci        BN_ULONG bn[BN_NIST_256_TOP];
645e1051a39Sopenharmony_ci        unsigned int ui[BN_NIST_256_TOP * sizeof(BN_ULONG) /
646e1051a39Sopenharmony_ci                        sizeof(unsigned int)];
647e1051a39Sopenharmony_ci    } buf;
648e1051a39Sopenharmony_ci    BN_ULONG c_d[BN_NIST_256_TOP], *res;
649e1051a39Sopenharmony_ci    bn_addsub_f adjust;
650e1051a39Sopenharmony_ci    static const BIGNUM ossl_bignum_nist_p_256_sqr = {
651e1051a39Sopenharmony_ci        (BN_ULONG *)_nist_p_256_sqr,
652e1051a39Sopenharmony_ci        OSSL_NELEM(_nist_p_256_sqr),
653e1051a39Sopenharmony_ci        OSSL_NELEM(_nist_p_256_sqr),
654e1051a39Sopenharmony_ci        0, BN_FLG_STATIC_DATA
655e1051a39Sopenharmony_ci    };
656e1051a39Sopenharmony_ci
657e1051a39Sopenharmony_ci    field = &ossl_bignum_nist_p_256; /* just to make sure */
658e1051a39Sopenharmony_ci
659e1051a39Sopenharmony_ci    if (BN_is_negative(a) || BN_ucmp(a, &ossl_bignum_nist_p_256_sqr) >= 0)
660e1051a39Sopenharmony_ci        return BN_nnmod(r, a, field, ctx);
661e1051a39Sopenharmony_ci
662e1051a39Sopenharmony_ci    i = BN_ucmp(field, a);
663e1051a39Sopenharmony_ci    if (i == 0) {
664e1051a39Sopenharmony_ci        BN_zero(r);
665e1051a39Sopenharmony_ci        return 1;
666e1051a39Sopenharmony_ci    } else if (i > 0)
667e1051a39Sopenharmony_ci        return (r == a) ? 1 : (BN_copy(r, a) != NULL);
668e1051a39Sopenharmony_ci
669e1051a39Sopenharmony_ci    if (r != a) {
670e1051a39Sopenharmony_ci        if (!bn_wexpand(r, BN_NIST_256_TOP))
671e1051a39Sopenharmony_ci            return 0;
672e1051a39Sopenharmony_ci        r_d = r->d;
673e1051a39Sopenharmony_ci        nist_cp_bn(r_d, a_d, BN_NIST_256_TOP);
674e1051a39Sopenharmony_ci    } else
675e1051a39Sopenharmony_ci        r_d = a_d;
676e1051a39Sopenharmony_ci
677e1051a39Sopenharmony_ci    nist_cp_bn_0(buf.bn, a_d + BN_NIST_256_TOP, top - BN_NIST_256_TOP,
678e1051a39Sopenharmony_ci                 BN_NIST_256_TOP);
679e1051a39Sopenharmony_ci
680e1051a39Sopenharmony_ci#if defined(NIST_INT64)
681e1051a39Sopenharmony_ci    {
682e1051a39Sopenharmony_ci        NIST_INT64 acc;         /* accumulator */
683e1051a39Sopenharmony_ci        unsigned int *rp = (unsigned int *)r_d;
684e1051a39Sopenharmony_ci        const unsigned int *bp = (const unsigned int *)buf.ui;
685e1051a39Sopenharmony_ci
686e1051a39Sopenharmony_ci        acc = rp[0];
687e1051a39Sopenharmony_ci        acc += bp[8 - 8];
688e1051a39Sopenharmony_ci        acc += bp[9 - 8];
689e1051a39Sopenharmony_ci        acc -= bp[11 - 8];
690e1051a39Sopenharmony_ci        acc -= bp[12 - 8];
691e1051a39Sopenharmony_ci        acc -= bp[13 - 8];
692e1051a39Sopenharmony_ci        acc -= bp[14 - 8];
693e1051a39Sopenharmony_ci        rp[0] = (unsigned int)acc;
694e1051a39Sopenharmony_ci        acc >>= 32;
695e1051a39Sopenharmony_ci
696e1051a39Sopenharmony_ci        acc += rp[1];
697e1051a39Sopenharmony_ci        acc += bp[9 - 8];
698e1051a39Sopenharmony_ci        acc += bp[10 - 8];
699e1051a39Sopenharmony_ci        acc -= bp[12 - 8];
700e1051a39Sopenharmony_ci        acc -= bp[13 - 8];
701e1051a39Sopenharmony_ci        acc -= bp[14 - 8];
702e1051a39Sopenharmony_ci        acc -= bp[15 - 8];
703e1051a39Sopenharmony_ci        rp[1] = (unsigned int)acc;
704e1051a39Sopenharmony_ci        acc >>= 32;
705e1051a39Sopenharmony_ci
706e1051a39Sopenharmony_ci        acc += rp[2];
707e1051a39Sopenharmony_ci        acc += bp[10 - 8];
708e1051a39Sopenharmony_ci        acc += bp[11 - 8];
709e1051a39Sopenharmony_ci        acc -= bp[13 - 8];
710e1051a39Sopenharmony_ci        acc -= bp[14 - 8];
711e1051a39Sopenharmony_ci        acc -= bp[15 - 8];
712e1051a39Sopenharmony_ci        rp[2] = (unsigned int)acc;
713e1051a39Sopenharmony_ci        acc >>= 32;
714e1051a39Sopenharmony_ci
715e1051a39Sopenharmony_ci        acc += rp[3];
716e1051a39Sopenharmony_ci        acc += bp[11 - 8];
717e1051a39Sopenharmony_ci        acc += bp[11 - 8];
718e1051a39Sopenharmony_ci        acc += bp[12 - 8];
719e1051a39Sopenharmony_ci        acc += bp[12 - 8];
720e1051a39Sopenharmony_ci        acc += bp[13 - 8];
721e1051a39Sopenharmony_ci        acc -= bp[15 - 8];
722e1051a39Sopenharmony_ci        acc -= bp[8 - 8];
723e1051a39Sopenharmony_ci        acc -= bp[9 - 8];
724e1051a39Sopenharmony_ci        rp[3] = (unsigned int)acc;
725e1051a39Sopenharmony_ci        acc >>= 32;
726e1051a39Sopenharmony_ci
727e1051a39Sopenharmony_ci        acc += rp[4];
728e1051a39Sopenharmony_ci        acc += bp[12 - 8];
729e1051a39Sopenharmony_ci        acc += bp[12 - 8];
730e1051a39Sopenharmony_ci        acc += bp[13 - 8];
731e1051a39Sopenharmony_ci        acc += bp[13 - 8];
732e1051a39Sopenharmony_ci        acc += bp[14 - 8];
733e1051a39Sopenharmony_ci        acc -= bp[9 - 8];
734e1051a39Sopenharmony_ci        acc -= bp[10 - 8];
735e1051a39Sopenharmony_ci        rp[4] = (unsigned int)acc;
736e1051a39Sopenharmony_ci        acc >>= 32;
737e1051a39Sopenharmony_ci
738e1051a39Sopenharmony_ci        acc += rp[5];
739e1051a39Sopenharmony_ci        acc += bp[13 - 8];
740e1051a39Sopenharmony_ci        acc += bp[13 - 8];
741e1051a39Sopenharmony_ci        acc += bp[14 - 8];
742e1051a39Sopenharmony_ci        acc += bp[14 - 8];
743e1051a39Sopenharmony_ci        acc += bp[15 - 8];
744e1051a39Sopenharmony_ci        acc -= bp[10 - 8];
745e1051a39Sopenharmony_ci        acc -= bp[11 - 8];
746e1051a39Sopenharmony_ci        rp[5] = (unsigned int)acc;
747e1051a39Sopenharmony_ci        acc >>= 32;
748e1051a39Sopenharmony_ci
749e1051a39Sopenharmony_ci        acc += rp[6];
750e1051a39Sopenharmony_ci        acc += bp[14 - 8];
751e1051a39Sopenharmony_ci        acc += bp[14 - 8];
752e1051a39Sopenharmony_ci        acc += bp[15 - 8];
753e1051a39Sopenharmony_ci        acc += bp[15 - 8];
754e1051a39Sopenharmony_ci        acc += bp[14 - 8];
755e1051a39Sopenharmony_ci        acc += bp[13 - 8];
756e1051a39Sopenharmony_ci        acc -= bp[8 - 8];
757e1051a39Sopenharmony_ci        acc -= bp[9 - 8];
758e1051a39Sopenharmony_ci        rp[6] = (unsigned int)acc;
759e1051a39Sopenharmony_ci        acc >>= 32;
760e1051a39Sopenharmony_ci
761e1051a39Sopenharmony_ci        acc += rp[7];
762e1051a39Sopenharmony_ci        acc += bp[15 - 8];
763e1051a39Sopenharmony_ci        acc += bp[15 - 8];
764e1051a39Sopenharmony_ci        acc += bp[15 - 8];
765e1051a39Sopenharmony_ci        acc += bp[8 - 8];
766e1051a39Sopenharmony_ci        acc -= bp[10 - 8];
767e1051a39Sopenharmony_ci        acc -= bp[11 - 8];
768e1051a39Sopenharmony_ci        acc -= bp[12 - 8];
769e1051a39Sopenharmony_ci        acc -= bp[13 - 8];
770e1051a39Sopenharmony_ci        rp[7] = (unsigned int)acc;
771e1051a39Sopenharmony_ci
772e1051a39Sopenharmony_ci        carry = (int)(acc >> 32);
773e1051a39Sopenharmony_ci    }
774e1051a39Sopenharmony_ci#else
775e1051a39Sopenharmony_ci    {
776e1051a39Sopenharmony_ci        BN_ULONG t_d[BN_NIST_256_TOP];
777e1051a39Sopenharmony_ci
778e1051a39Sopenharmony_ci        /*
779e1051a39Sopenharmony_ci         * S1
780e1051a39Sopenharmony_ci         */
781e1051a39Sopenharmony_ci        nist_set_256(t_d, buf.bn, 15, 14, 13, 12, 11, 0, 0, 0);
782e1051a39Sopenharmony_ci        /*
783e1051a39Sopenharmony_ci         * S2
784e1051a39Sopenharmony_ci         */
785e1051a39Sopenharmony_ci        nist_set_256(c_d, buf.bn, 0, 15, 14, 13, 12, 0, 0, 0);
786e1051a39Sopenharmony_ci        carry = (int)bn_add_words(t_d, t_d, c_d, BN_NIST_256_TOP);
787e1051a39Sopenharmony_ci        /* left shift */
788e1051a39Sopenharmony_ci        {
789e1051a39Sopenharmony_ci            register BN_ULONG *ap, t, c;
790e1051a39Sopenharmony_ci            ap = t_d;
791e1051a39Sopenharmony_ci            c = 0;
792e1051a39Sopenharmony_ci            for (i = BN_NIST_256_TOP; i != 0; --i) {
793e1051a39Sopenharmony_ci                t = *ap;
794e1051a39Sopenharmony_ci                *(ap++) = ((t << 1) | c) & BN_MASK2;
795e1051a39Sopenharmony_ci                c = (t & BN_TBIT) ? 1 : 0;
796e1051a39Sopenharmony_ci            }
797e1051a39Sopenharmony_ci            carry <<= 1;
798e1051a39Sopenharmony_ci            carry |= c;
799e1051a39Sopenharmony_ci        }
800e1051a39Sopenharmony_ci        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
801e1051a39Sopenharmony_ci        /*
802e1051a39Sopenharmony_ci         * S3
803e1051a39Sopenharmony_ci         */
804e1051a39Sopenharmony_ci        nist_set_256(t_d, buf.bn, 15, 14, 0, 0, 0, 10, 9, 8);
805e1051a39Sopenharmony_ci        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
806e1051a39Sopenharmony_ci        /*
807e1051a39Sopenharmony_ci         * S4
808e1051a39Sopenharmony_ci         */
809e1051a39Sopenharmony_ci        nist_set_256(t_d, buf.bn, 8, 13, 15, 14, 13, 11, 10, 9);
810e1051a39Sopenharmony_ci        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
811e1051a39Sopenharmony_ci        /*
812e1051a39Sopenharmony_ci         * D1
813e1051a39Sopenharmony_ci         */
814e1051a39Sopenharmony_ci        nist_set_256(t_d, buf.bn, 10, 8, 0, 0, 0, 13, 12, 11);
815e1051a39Sopenharmony_ci        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
816e1051a39Sopenharmony_ci        /*
817e1051a39Sopenharmony_ci         * D2
818e1051a39Sopenharmony_ci         */
819e1051a39Sopenharmony_ci        nist_set_256(t_d, buf.bn, 11, 9, 0, 0, 15, 14, 13, 12);
820e1051a39Sopenharmony_ci        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
821e1051a39Sopenharmony_ci        /*
822e1051a39Sopenharmony_ci         * D3
823e1051a39Sopenharmony_ci         */
824e1051a39Sopenharmony_ci        nist_set_256(t_d, buf.bn, 12, 0, 10, 9, 8, 15, 14, 13);
825e1051a39Sopenharmony_ci        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
826e1051a39Sopenharmony_ci        /*
827e1051a39Sopenharmony_ci         * D4
828e1051a39Sopenharmony_ci         */
829e1051a39Sopenharmony_ci        nist_set_256(t_d, buf.bn, 13, 0, 11, 10, 9, 0, 15, 14);
830e1051a39Sopenharmony_ci        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
831e1051a39Sopenharmony_ci
832e1051a39Sopenharmony_ci    }
833e1051a39Sopenharmony_ci#endif
834e1051a39Sopenharmony_ci    /* see BN_nist_mod_224 for explanation */
835e1051a39Sopenharmony_ci    adjust = bn_sub_words;
836e1051a39Sopenharmony_ci    if (carry > 0)
837e1051a39Sopenharmony_ci        carry =
838e1051a39Sopenharmony_ci            (int)bn_sub_words(r_d, r_d, _nist_p_256[carry - 1],
839e1051a39Sopenharmony_ci                              BN_NIST_256_TOP);
840e1051a39Sopenharmony_ci    else if (carry < 0) {
841e1051a39Sopenharmony_ci        carry =
842e1051a39Sopenharmony_ci            (int)bn_add_words(r_d, r_d, _nist_p_256[-carry - 1],
843e1051a39Sopenharmony_ci                              BN_NIST_256_TOP);
844e1051a39Sopenharmony_ci        adjust = carry ? bn_sub_words : bn_add_words;
845e1051a39Sopenharmony_ci    } else
846e1051a39Sopenharmony_ci        carry = 1;
847e1051a39Sopenharmony_ci
848e1051a39Sopenharmony_ci    res = ((*adjust) (c_d, r_d, _nist_p_256[0], BN_NIST_256_TOP) && carry)
849e1051a39Sopenharmony_ci        ? r_d
850e1051a39Sopenharmony_ci        : c_d;
851e1051a39Sopenharmony_ci    nist_cp_bn(r_d, res, BN_NIST_256_TOP);
852e1051a39Sopenharmony_ci    r->top = BN_NIST_256_TOP;
853e1051a39Sopenharmony_ci    bn_correct_top(r);
854e1051a39Sopenharmony_ci
855e1051a39Sopenharmony_ci    return 1;
856e1051a39Sopenharmony_ci}
857e1051a39Sopenharmony_ci
858e1051a39Sopenharmony_ci#define nist_set_384(to,from,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) \
859e1051a39Sopenharmony_ci        { \
860e1051a39Sopenharmony_ci        bn_cp_32(to, 0, from,  (a12) - 12) \
861e1051a39Sopenharmony_ci        bn_cp_32(to, 1, from,  (a11) - 12) \
862e1051a39Sopenharmony_ci        bn_cp_32(to, 2, from,  (a10) - 12) \
863e1051a39Sopenharmony_ci        bn_cp_32(to, 3, from,  (a9) - 12)  \
864e1051a39Sopenharmony_ci        bn_cp_32(to, 4, from,  (a8) - 12)  \
865e1051a39Sopenharmony_ci        bn_cp_32(to, 5, from,  (a7) - 12)  \
866e1051a39Sopenharmony_ci        bn_cp_32(to, 6, from,  (a6) - 12)  \
867e1051a39Sopenharmony_ci        bn_cp_32(to, 7, from,  (a5) - 12)  \
868e1051a39Sopenharmony_ci        bn_cp_32(to, 8, from,  (a4) - 12)  \
869e1051a39Sopenharmony_ci        bn_cp_32(to, 9, from,  (a3) - 12)  \
870e1051a39Sopenharmony_ci        bn_cp_32(to, 10, from, (a2) - 12)  \
871e1051a39Sopenharmony_ci        bn_cp_32(to, 11, from, (a1) - 12)  \
872e1051a39Sopenharmony_ci        }
873e1051a39Sopenharmony_ci
874e1051a39Sopenharmony_ciint BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
875e1051a39Sopenharmony_ci                    BN_CTX *ctx)
876e1051a39Sopenharmony_ci{
877e1051a39Sopenharmony_ci    int i, top = a->top;
878e1051a39Sopenharmony_ci    int carry = 0;
879e1051a39Sopenharmony_ci    register BN_ULONG *r_d, *a_d = a->d;
880e1051a39Sopenharmony_ci    union {
881e1051a39Sopenharmony_ci        BN_ULONG bn[BN_NIST_384_TOP];
882e1051a39Sopenharmony_ci        unsigned int ui[BN_NIST_384_TOP * sizeof(BN_ULONG) /
883e1051a39Sopenharmony_ci                        sizeof(unsigned int)];
884e1051a39Sopenharmony_ci    } buf;
885e1051a39Sopenharmony_ci    BN_ULONG c_d[BN_NIST_384_TOP], *res;
886e1051a39Sopenharmony_ci    bn_addsub_f adjust;
887e1051a39Sopenharmony_ci    static const BIGNUM ossl_bignum_nist_p_384_sqr = {
888e1051a39Sopenharmony_ci        (BN_ULONG *)_nist_p_384_sqr,
889e1051a39Sopenharmony_ci        OSSL_NELEM(_nist_p_384_sqr),
890e1051a39Sopenharmony_ci        OSSL_NELEM(_nist_p_384_sqr),
891e1051a39Sopenharmony_ci        0, BN_FLG_STATIC_DATA
892e1051a39Sopenharmony_ci    };
893e1051a39Sopenharmony_ci
894e1051a39Sopenharmony_ci    field = &ossl_bignum_nist_p_384; /* just to make sure */
895e1051a39Sopenharmony_ci
896e1051a39Sopenharmony_ci    if (BN_is_negative(a) || BN_ucmp(a, &ossl_bignum_nist_p_384_sqr) >= 0)
897e1051a39Sopenharmony_ci        return BN_nnmod(r, a, field, ctx);
898e1051a39Sopenharmony_ci
899e1051a39Sopenharmony_ci    i = BN_ucmp(field, a);
900e1051a39Sopenharmony_ci    if (i == 0) {
901e1051a39Sopenharmony_ci        BN_zero(r);
902e1051a39Sopenharmony_ci        return 1;
903e1051a39Sopenharmony_ci    } else if (i > 0)
904e1051a39Sopenharmony_ci        return (r == a) ? 1 : (BN_copy(r, a) != NULL);
905e1051a39Sopenharmony_ci
906e1051a39Sopenharmony_ci    if (r != a) {
907e1051a39Sopenharmony_ci        if (!bn_wexpand(r, BN_NIST_384_TOP))
908e1051a39Sopenharmony_ci            return 0;
909e1051a39Sopenharmony_ci        r_d = r->d;
910e1051a39Sopenharmony_ci        nist_cp_bn(r_d, a_d, BN_NIST_384_TOP);
911e1051a39Sopenharmony_ci    } else
912e1051a39Sopenharmony_ci        r_d = a_d;
913e1051a39Sopenharmony_ci
914e1051a39Sopenharmony_ci    nist_cp_bn_0(buf.bn, a_d + BN_NIST_384_TOP, top - BN_NIST_384_TOP,
915e1051a39Sopenharmony_ci                 BN_NIST_384_TOP);
916e1051a39Sopenharmony_ci
917e1051a39Sopenharmony_ci#if defined(NIST_INT64)
918e1051a39Sopenharmony_ci    {
919e1051a39Sopenharmony_ci        NIST_INT64 acc;         /* accumulator */
920e1051a39Sopenharmony_ci        unsigned int *rp = (unsigned int *)r_d;
921e1051a39Sopenharmony_ci        const unsigned int *bp = (const unsigned int *)buf.ui;
922e1051a39Sopenharmony_ci
923e1051a39Sopenharmony_ci        acc = rp[0];
924e1051a39Sopenharmony_ci        acc += bp[12 - 12];
925e1051a39Sopenharmony_ci        acc += bp[21 - 12];
926e1051a39Sopenharmony_ci        acc += bp[20 - 12];
927e1051a39Sopenharmony_ci        acc -= bp[23 - 12];
928e1051a39Sopenharmony_ci        rp[0] = (unsigned int)acc;
929e1051a39Sopenharmony_ci        acc >>= 32;
930e1051a39Sopenharmony_ci
931e1051a39Sopenharmony_ci        acc += rp[1];
932e1051a39Sopenharmony_ci        acc += bp[13 - 12];
933e1051a39Sopenharmony_ci        acc += bp[22 - 12];
934e1051a39Sopenharmony_ci        acc += bp[23 - 12];
935e1051a39Sopenharmony_ci        acc -= bp[12 - 12];
936e1051a39Sopenharmony_ci        acc -= bp[20 - 12];
937e1051a39Sopenharmony_ci        rp[1] = (unsigned int)acc;
938e1051a39Sopenharmony_ci        acc >>= 32;
939e1051a39Sopenharmony_ci
940e1051a39Sopenharmony_ci        acc += rp[2];
941e1051a39Sopenharmony_ci        acc += bp[14 - 12];
942e1051a39Sopenharmony_ci        acc += bp[23 - 12];
943e1051a39Sopenharmony_ci        acc -= bp[13 - 12];
944e1051a39Sopenharmony_ci        acc -= bp[21 - 12];
945e1051a39Sopenharmony_ci        rp[2] = (unsigned int)acc;
946e1051a39Sopenharmony_ci        acc >>= 32;
947e1051a39Sopenharmony_ci
948e1051a39Sopenharmony_ci        acc += rp[3];
949e1051a39Sopenharmony_ci        acc += bp[15 - 12];
950e1051a39Sopenharmony_ci        acc += bp[12 - 12];
951e1051a39Sopenharmony_ci        acc += bp[20 - 12];
952e1051a39Sopenharmony_ci        acc += bp[21 - 12];
953e1051a39Sopenharmony_ci        acc -= bp[14 - 12];
954e1051a39Sopenharmony_ci        acc -= bp[22 - 12];
955e1051a39Sopenharmony_ci        acc -= bp[23 - 12];
956e1051a39Sopenharmony_ci        rp[3] = (unsigned int)acc;
957e1051a39Sopenharmony_ci        acc >>= 32;
958e1051a39Sopenharmony_ci
959e1051a39Sopenharmony_ci        acc += rp[4];
960e1051a39Sopenharmony_ci        acc += bp[21 - 12];
961e1051a39Sopenharmony_ci        acc += bp[21 - 12];
962e1051a39Sopenharmony_ci        acc += bp[16 - 12];
963e1051a39Sopenharmony_ci        acc += bp[13 - 12];
964e1051a39Sopenharmony_ci        acc += bp[12 - 12];
965e1051a39Sopenharmony_ci        acc += bp[20 - 12];
966e1051a39Sopenharmony_ci        acc += bp[22 - 12];
967e1051a39Sopenharmony_ci        acc -= bp[15 - 12];
968e1051a39Sopenharmony_ci        acc -= bp[23 - 12];
969e1051a39Sopenharmony_ci        acc -= bp[23 - 12];
970e1051a39Sopenharmony_ci        rp[4] = (unsigned int)acc;
971e1051a39Sopenharmony_ci        acc >>= 32;
972e1051a39Sopenharmony_ci
973e1051a39Sopenharmony_ci        acc += rp[5];
974e1051a39Sopenharmony_ci        acc += bp[22 - 12];
975e1051a39Sopenharmony_ci        acc += bp[22 - 12];
976e1051a39Sopenharmony_ci        acc += bp[17 - 12];
977e1051a39Sopenharmony_ci        acc += bp[14 - 12];
978e1051a39Sopenharmony_ci        acc += bp[13 - 12];
979e1051a39Sopenharmony_ci        acc += bp[21 - 12];
980e1051a39Sopenharmony_ci        acc += bp[23 - 12];
981e1051a39Sopenharmony_ci        acc -= bp[16 - 12];
982e1051a39Sopenharmony_ci        rp[5] = (unsigned int)acc;
983e1051a39Sopenharmony_ci        acc >>= 32;
984e1051a39Sopenharmony_ci
985e1051a39Sopenharmony_ci        acc += rp[6];
986e1051a39Sopenharmony_ci        acc += bp[23 - 12];
987e1051a39Sopenharmony_ci        acc += bp[23 - 12];
988e1051a39Sopenharmony_ci        acc += bp[18 - 12];
989e1051a39Sopenharmony_ci        acc += bp[15 - 12];
990e1051a39Sopenharmony_ci        acc += bp[14 - 12];
991e1051a39Sopenharmony_ci        acc += bp[22 - 12];
992e1051a39Sopenharmony_ci        acc -= bp[17 - 12];
993e1051a39Sopenharmony_ci        rp[6] = (unsigned int)acc;
994e1051a39Sopenharmony_ci        acc >>= 32;
995e1051a39Sopenharmony_ci
996e1051a39Sopenharmony_ci        acc += rp[7];
997e1051a39Sopenharmony_ci        acc += bp[19 - 12];
998e1051a39Sopenharmony_ci        acc += bp[16 - 12];
999e1051a39Sopenharmony_ci        acc += bp[15 - 12];
1000e1051a39Sopenharmony_ci        acc += bp[23 - 12];
1001e1051a39Sopenharmony_ci        acc -= bp[18 - 12];
1002e1051a39Sopenharmony_ci        rp[7] = (unsigned int)acc;
1003e1051a39Sopenharmony_ci        acc >>= 32;
1004e1051a39Sopenharmony_ci
1005e1051a39Sopenharmony_ci        acc += rp[8];
1006e1051a39Sopenharmony_ci        acc += bp[20 - 12];
1007e1051a39Sopenharmony_ci        acc += bp[17 - 12];
1008e1051a39Sopenharmony_ci        acc += bp[16 - 12];
1009e1051a39Sopenharmony_ci        acc -= bp[19 - 12];
1010e1051a39Sopenharmony_ci        rp[8] = (unsigned int)acc;
1011e1051a39Sopenharmony_ci        acc >>= 32;
1012e1051a39Sopenharmony_ci
1013e1051a39Sopenharmony_ci        acc += rp[9];
1014e1051a39Sopenharmony_ci        acc += bp[21 - 12];
1015e1051a39Sopenharmony_ci        acc += bp[18 - 12];
1016e1051a39Sopenharmony_ci        acc += bp[17 - 12];
1017e1051a39Sopenharmony_ci        acc -= bp[20 - 12];
1018e1051a39Sopenharmony_ci        rp[9] = (unsigned int)acc;
1019e1051a39Sopenharmony_ci        acc >>= 32;
1020e1051a39Sopenharmony_ci
1021e1051a39Sopenharmony_ci        acc += rp[10];
1022e1051a39Sopenharmony_ci        acc += bp[22 - 12];
1023e1051a39Sopenharmony_ci        acc += bp[19 - 12];
1024e1051a39Sopenharmony_ci        acc += bp[18 - 12];
1025e1051a39Sopenharmony_ci        acc -= bp[21 - 12];
1026e1051a39Sopenharmony_ci        rp[10] = (unsigned int)acc;
1027e1051a39Sopenharmony_ci        acc >>= 32;
1028e1051a39Sopenharmony_ci
1029e1051a39Sopenharmony_ci        acc += rp[11];
1030e1051a39Sopenharmony_ci        acc += bp[23 - 12];
1031e1051a39Sopenharmony_ci        acc += bp[20 - 12];
1032e1051a39Sopenharmony_ci        acc += bp[19 - 12];
1033e1051a39Sopenharmony_ci        acc -= bp[22 - 12];
1034e1051a39Sopenharmony_ci        rp[11] = (unsigned int)acc;
1035e1051a39Sopenharmony_ci
1036e1051a39Sopenharmony_ci        carry = (int)(acc >> 32);
1037e1051a39Sopenharmony_ci    }
1038e1051a39Sopenharmony_ci#else
1039e1051a39Sopenharmony_ci    {
1040e1051a39Sopenharmony_ci        BN_ULONG t_d[BN_NIST_384_TOP];
1041e1051a39Sopenharmony_ci
1042e1051a39Sopenharmony_ci        /*
1043e1051a39Sopenharmony_ci         * S1
1044e1051a39Sopenharmony_ci         */
1045e1051a39Sopenharmony_ci        nist_set_256(t_d, buf.bn, 0, 0, 0, 0, 0, 23 - 4, 22 - 4, 21 - 4);
1046e1051a39Sopenharmony_ci        /* left shift */
1047e1051a39Sopenharmony_ci        {
1048e1051a39Sopenharmony_ci            register BN_ULONG *ap, t, c;
1049e1051a39Sopenharmony_ci            ap = t_d;
1050e1051a39Sopenharmony_ci            c = 0;
1051e1051a39Sopenharmony_ci            for (i = 3; i != 0; --i) {
1052e1051a39Sopenharmony_ci                t = *ap;
1053e1051a39Sopenharmony_ci                *(ap++) = ((t << 1) | c) & BN_MASK2;
1054e1051a39Sopenharmony_ci                c = (t & BN_TBIT) ? 1 : 0;
1055e1051a39Sopenharmony_ci            }
1056e1051a39Sopenharmony_ci            *ap = c;
1057e1051a39Sopenharmony_ci        }
1058e1051a39Sopenharmony_ci        carry =
1059e1051a39Sopenharmony_ci            (int)bn_add_words(r_d + (128 / BN_BITS2), r_d + (128 / BN_BITS2),
1060e1051a39Sopenharmony_ci                              t_d, BN_NIST_256_TOP);
1061e1051a39Sopenharmony_ci        /*
1062e1051a39Sopenharmony_ci         * S2
1063e1051a39Sopenharmony_ci         */
1064e1051a39Sopenharmony_ci        carry += (int)bn_add_words(r_d, r_d, buf.bn, BN_NIST_384_TOP);
1065e1051a39Sopenharmony_ci        /*
1066e1051a39Sopenharmony_ci         * S3
1067e1051a39Sopenharmony_ci         */
1068e1051a39Sopenharmony_ci        nist_set_384(t_d, buf.bn, 20, 19, 18, 17, 16, 15, 14, 13, 12, 23, 22,
1069e1051a39Sopenharmony_ci                     21);
1070e1051a39Sopenharmony_ci        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
1071e1051a39Sopenharmony_ci        /*
1072e1051a39Sopenharmony_ci         * S4
1073e1051a39Sopenharmony_ci         */
1074e1051a39Sopenharmony_ci        nist_set_384(t_d, buf.bn, 19, 18, 17, 16, 15, 14, 13, 12, 20, 0, 23,
1075e1051a39Sopenharmony_ci                     0);
1076e1051a39Sopenharmony_ci        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
1077e1051a39Sopenharmony_ci        /*
1078e1051a39Sopenharmony_ci         * S5
1079e1051a39Sopenharmony_ci         */
1080e1051a39Sopenharmony_ci        nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 23, 22, 21, 20, 0, 0, 0, 0);
1081e1051a39Sopenharmony_ci        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
1082e1051a39Sopenharmony_ci        /*
1083e1051a39Sopenharmony_ci         * S6
1084e1051a39Sopenharmony_ci         */
1085e1051a39Sopenharmony_ci        nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 23, 22, 21, 0, 0, 20);
1086e1051a39Sopenharmony_ci        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
1087e1051a39Sopenharmony_ci        /*
1088e1051a39Sopenharmony_ci         * D1
1089e1051a39Sopenharmony_ci         */
1090e1051a39Sopenharmony_ci        nist_set_384(t_d, buf.bn, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12,
1091e1051a39Sopenharmony_ci                     23);
1092e1051a39Sopenharmony_ci        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
1093e1051a39Sopenharmony_ci        /*
1094e1051a39Sopenharmony_ci         * D2
1095e1051a39Sopenharmony_ci         */
1096e1051a39Sopenharmony_ci        nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 0, 23, 22, 21, 20, 0);
1097e1051a39Sopenharmony_ci        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
1098e1051a39Sopenharmony_ci        /*
1099e1051a39Sopenharmony_ci         * D3
1100e1051a39Sopenharmony_ci         */
1101e1051a39Sopenharmony_ci        nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 0, 23, 23, 0, 0, 0);
1102e1051a39Sopenharmony_ci        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
1103e1051a39Sopenharmony_ci
1104e1051a39Sopenharmony_ci    }
1105e1051a39Sopenharmony_ci#endif
1106e1051a39Sopenharmony_ci    /* see BN_nist_mod_224 for explanation */
1107e1051a39Sopenharmony_ci    adjust = bn_sub_words;
1108e1051a39Sopenharmony_ci    if (carry > 0)
1109e1051a39Sopenharmony_ci        carry =
1110e1051a39Sopenharmony_ci            (int)bn_sub_words(r_d, r_d, _nist_p_384[carry - 1],
1111e1051a39Sopenharmony_ci                              BN_NIST_384_TOP);
1112e1051a39Sopenharmony_ci    else if (carry < 0) {
1113e1051a39Sopenharmony_ci        carry =
1114e1051a39Sopenharmony_ci            (int)bn_add_words(r_d, r_d, _nist_p_384[-carry - 1],
1115e1051a39Sopenharmony_ci                              BN_NIST_384_TOP);
1116e1051a39Sopenharmony_ci        adjust = carry ? bn_sub_words : bn_add_words;
1117e1051a39Sopenharmony_ci    } else
1118e1051a39Sopenharmony_ci        carry = 1;
1119e1051a39Sopenharmony_ci
1120e1051a39Sopenharmony_ci    res = ((*adjust) (c_d, r_d, _nist_p_384[0], BN_NIST_384_TOP) && carry)
1121e1051a39Sopenharmony_ci        ? r_d
1122e1051a39Sopenharmony_ci        : c_d;
1123e1051a39Sopenharmony_ci    nist_cp_bn(r_d, res, BN_NIST_384_TOP);
1124e1051a39Sopenharmony_ci    r->top = BN_NIST_384_TOP;
1125e1051a39Sopenharmony_ci    bn_correct_top(r);
1126e1051a39Sopenharmony_ci
1127e1051a39Sopenharmony_ci    return 1;
1128e1051a39Sopenharmony_ci}
1129e1051a39Sopenharmony_ci
1130e1051a39Sopenharmony_ci#define BN_NIST_521_RSHIFT      (521%BN_BITS2)
1131e1051a39Sopenharmony_ci#define BN_NIST_521_LSHIFT      (BN_BITS2-BN_NIST_521_RSHIFT)
1132e1051a39Sopenharmony_ci#define BN_NIST_521_TOP_MASK    ((BN_ULONG)BN_MASK2>>BN_NIST_521_LSHIFT)
1133e1051a39Sopenharmony_ci
1134e1051a39Sopenharmony_ciint BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
1135e1051a39Sopenharmony_ci                    BN_CTX *ctx)
1136e1051a39Sopenharmony_ci{
1137e1051a39Sopenharmony_ci    int top = a->top, i;
1138e1051a39Sopenharmony_ci    BN_ULONG *r_d, *a_d = a->d, t_d[BN_NIST_521_TOP], val, tmp, *res;
1139e1051a39Sopenharmony_ci    static const BIGNUM ossl_bignum_nist_p_521_sqr = {
1140e1051a39Sopenharmony_ci        (BN_ULONG *)_nist_p_521_sqr,
1141e1051a39Sopenharmony_ci        OSSL_NELEM(_nist_p_521_sqr),
1142e1051a39Sopenharmony_ci        OSSL_NELEM(_nist_p_521_sqr),
1143e1051a39Sopenharmony_ci        0, BN_FLG_STATIC_DATA
1144e1051a39Sopenharmony_ci    };
1145e1051a39Sopenharmony_ci
1146e1051a39Sopenharmony_ci    field = &ossl_bignum_nist_p_521; /* just to make sure */
1147e1051a39Sopenharmony_ci
1148e1051a39Sopenharmony_ci    if (BN_is_negative(a) || BN_ucmp(a, &ossl_bignum_nist_p_521_sqr) >= 0)
1149e1051a39Sopenharmony_ci        return BN_nnmod(r, a, field, ctx);
1150e1051a39Sopenharmony_ci
1151e1051a39Sopenharmony_ci    i = BN_ucmp(field, a);
1152e1051a39Sopenharmony_ci    if (i == 0) {
1153e1051a39Sopenharmony_ci        BN_zero(r);
1154e1051a39Sopenharmony_ci        return 1;
1155e1051a39Sopenharmony_ci    } else if (i > 0)
1156e1051a39Sopenharmony_ci        return (r == a) ? 1 : (BN_copy(r, a) != NULL);
1157e1051a39Sopenharmony_ci
1158e1051a39Sopenharmony_ci    if (r != a) {
1159e1051a39Sopenharmony_ci        if (!bn_wexpand(r, BN_NIST_521_TOP))
1160e1051a39Sopenharmony_ci            return 0;
1161e1051a39Sopenharmony_ci        r_d = r->d;
1162e1051a39Sopenharmony_ci        nist_cp_bn(r_d, a_d, BN_NIST_521_TOP);
1163e1051a39Sopenharmony_ci    } else
1164e1051a39Sopenharmony_ci        r_d = a_d;
1165e1051a39Sopenharmony_ci
1166e1051a39Sopenharmony_ci    /* upper 521 bits, copy ... */
1167e1051a39Sopenharmony_ci    nist_cp_bn_0(t_d, a_d + (BN_NIST_521_TOP - 1),
1168e1051a39Sopenharmony_ci                 top - (BN_NIST_521_TOP - 1), BN_NIST_521_TOP);
1169e1051a39Sopenharmony_ci    /* ... and right shift */
1170e1051a39Sopenharmony_ci    for (val = t_d[0], i = 0; i < BN_NIST_521_TOP - 1; i++) {
1171e1051a39Sopenharmony_ci#if 0
1172e1051a39Sopenharmony_ci        /*
1173e1051a39Sopenharmony_ci         * MSC ARM compiler [version 2013, presumably even earlier,
1174e1051a39Sopenharmony_ci         * much earlier] miscompiles this code, but not one in
1175e1051a39Sopenharmony_ci         * #else section. See RT#3541.
1176e1051a39Sopenharmony_ci         */
1177e1051a39Sopenharmony_ci        tmp = val >> BN_NIST_521_RSHIFT;
1178e1051a39Sopenharmony_ci        val = t_d[i + 1];
1179e1051a39Sopenharmony_ci        t_d[i] = (tmp | val << BN_NIST_521_LSHIFT) & BN_MASK2;
1180e1051a39Sopenharmony_ci#else
1181e1051a39Sopenharmony_ci        t_d[i] = (val >> BN_NIST_521_RSHIFT |
1182e1051a39Sopenharmony_ci                  (tmp = t_d[i + 1]) << BN_NIST_521_LSHIFT) & BN_MASK2;
1183e1051a39Sopenharmony_ci        val = tmp;
1184e1051a39Sopenharmony_ci#endif
1185e1051a39Sopenharmony_ci    }
1186e1051a39Sopenharmony_ci    t_d[i] = val >> BN_NIST_521_RSHIFT;
1187e1051a39Sopenharmony_ci    /* lower 521 bits */
1188e1051a39Sopenharmony_ci    r_d[i] &= BN_NIST_521_TOP_MASK;
1189e1051a39Sopenharmony_ci
1190e1051a39Sopenharmony_ci    bn_add_words(r_d, r_d, t_d, BN_NIST_521_TOP);
1191e1051a39Sopenharmony_ci    res = bn_sub_words(t_d, r_d, _nist_p_521,
1192e1051a39Sopenharmony_ci                       BN_NIST_521_TOP)
1193e1051a39Sopenharmony_ci        ? r_d
1194e1051a39Sopenharmony_ci        : t_d;
1195e1051a39Sopenharmony_ci    nist_cp_bn(r_d, res, BN_NIST_521_TOP);
1196e1051a39Sopenharmony_ci    r->top = BN_NIST_521_TOP;
1197e1051a39Sopenharmony_ci    bn_correct_top(r);
1198e1051a39Sopenharmony_ci
1199e1051a39Sopenharmony_ci    return 1;
1200e1051a39Sopenharmony_ci}
1201e1051a39Sopenharmony_ci
1202e1051a39Sopenharmony_ciint (*BN_nist_mod_func(const BIGNUM *p)) (BIGNUM *r, const BIGNUM *a,
1203e1051a39Sopenharmony_ci                                          const BIGNUM *field, BN_CTX *ctx) {
1204e1051a39Sopenharmony_ci    if (BN_ucmp(&ossl_bignum_nist_p_192, p) == 0)
1205e1051a39Sopenharmony_ci        return BN_nist_mod_192;
1206e1051a39Sopenharmony_ci    if (BN_ucmp(&ossl_bignum_nist_p_224, p) == 0)
1207e1051a39Sopenharmony_ci        return BN_nist_mod_224;
1208e1051a39Sopenharmony_ci    if (BN_ucmp(&ossl_bignum_nist_p_256, p) == 0)
1209e1051a39Sopenharmony_ci        return BN_nist_mod_256;
1210e1051a39Sopenharmony_ci    if (BN_ucmp(&ossl_bignum_nist_p_384, p) == 0)
1211e1051a39Sopenharmony_ci        return BN_nist_mod_384;
1212e1051a39Sopenharmony_ci    if (BN_ucmp(&ossl_bignum_nist_p_521, p) == 0)
1213e1051a39Sopenharmony_ci        return BN_nist_mod_521;
1214e1051a39Sopenharmony_ci    return 0;
1215e1051a39Sopenharmony_ci}
1216