1*2139Sjp161948 /* crypto/bn/bn_nist.c */
2*2139Sjp161948 /*
3*2139Sjp161948 * Written by Nils Larsch for the OpenSSL project
4*2139Sjp161948 */
5*2139Sjp161948 /* ====================================================================
6*2139Sjp161948 * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
7*2139Sjp161948 *
8*2139Sjp161948 * Redistribution and use in source and binary forms, with or without
9*2139Sjp161948 * modification, are permitted provided that the following conditions
10*2139Sjp161948 * are met:
11*2139Sjp161948 *
12*2139Sjp161948 * 1. Redistributions of source code must retain the above copyright
13*2139Sjp161948 * notice, this list of conditions and the following disclaimer.
14*2139Sjp161948 *
15*2139Sjp161948 * 2. Redistributions in binary form must reproduce the above copyright
16*2139Sjp161948 * notice, this list of conditions and the following disclaimer in
17*2139Sjp161948 * the documentation and/or other materials provided with the
18*2139Sjp161948 * distribution.
19*2139Sjp161948 *
20*2139Sjp161948 * 3. All advertising materials mentioning features or use of this
21*2139Sjp161948 * software must display the following acknowledgment:
22*2139Sjp161948 * "This product includes software developed by the OpenSSL Project
23*2139Sjp161948 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
24*2139Sjp161948 *
25*2139Sjp161948 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26*2139Sjp161948 * endorse or promote products derived from this software without
27*2139Sjp161948 * prior written permission. For written permission, please contact
28*2139Sjp161948 * openssl-core@openssl.org.
29*2139Sjp161948 *
30*2139Sjp161948 * 5. Products derived from this software may not be called "OpenSSL"
31*2139Sjp161948 * nor may "OpenSSL" appear in their names without prior written
32*2139Sjp161948 * permission of the OpenSSL Project.
33*2139Sjp161948 *
34*2139Sjp161948 * 6. Redistributions of any form whatsoever must retain the following
35*2139Sjp161948 * acknowledgment:
36*2139Sjp161948 * "This product includes software developed by the OpenSSL Project
37*2139Sjp161948 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
38*2139Sjp161948 *
39*2139Sjp161948 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40*2139Sjp161948 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41*2139Sjp161948 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42*2139Sjp161948 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43*2139Sjp161948 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44*2139Sjp161948 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45*2139Sjp161948 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46*2139Sjp161948 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47*2139Sjp161948 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48*2139Sjp161948 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49*2139Sjp161948 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50*2139Sjp161948 * OF THE POSSIBILITY OF SUCH DAMAGE.
51*2139Sjp161948 * ====================================================================
52*2139Sjp161948 *
53*2139Sjp161948 * This product includes cryptographic software written by Eric Young
54*2139Sjp161948 * (eay@cryptsoft.com). This product includes software written by Tim
55*2139Sjp161948 * Hudson (tjh@cryptsoft.com).
56*2139Sjp161948 *
57*2139Sjp161948 */
58*2139Sjp161948
59*2139Sjp161948 #include "bn_lcl.h"
60*2139Sjp161948 #include "cryptlib.h"
61*2139Sjp161948
62*2139Sjp161948 #define BN_NIST_192_TOP (192+BN_BITS2-1)/BN_BITS2
63*2139Sjp161948 #define BN_NIST_224_TOP (224+BN_BITS2-1)/BN_BITS2
64*2139Sjp161948 #define BN_NIST_256_TOP (256+BN_BITS2-1)/BN_BITS2
65*2139Sjp161948 #define BN_NIST_384_TOP (384+BN_BITS2-1)/BN_BITS2
66*2139Sjp161948 #define BN_NIST_521_TOP (521+BN_BITS2-1)/BN_BITS2
67*2139Sjp161948
68*2139Sjp161948 #if BN_BITS2 == 64
69*2139Sjp161948 static const BN_ULONG _nist_p_192[] =
70*2139Sjp161948 {0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFEULL,
71*2139Sjp161948 0xFFFFFFFFFFFFFFFFULL};
72*2139Sjp161948 static const BN_ULONG _nist_p_224[] =
73*2139Sjp161948 {0x0000000000000001ULL,0xFFFFFFFF00000000ULL,
74*2139Sjp161948 0xFFFFFFFFFFFFFFFFULL,0x00000000FFFFFFFFULL};
75*2139Sjp161948 static const BN_ULONG _nist_p_256[] =
76*2139Sjp161948 {0xFFFFFFFFFFFFFFFFULL,0x00000000FFFFFFFFULL,
77*2139Sjp161948 0x0000000000000000ULL,0xFFFFFFFF00000001ULL};
78*2139Sjp161948 static const BN_ULONG _nist_p_384[] =
79*2139Sjp161948 {0x00000000FFFFFFFFULL,0xFFFFFFFF00000000ULL,
80*2139Sjp161948 0xFFFFFFFFFFFFFFFEULL,0xFFFFFFFFFFFFFFFFULL,
81*2139Sjp161948 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL};
82*2139Sjp161948 static const BN_ULONG _nist_p_521[] =
83*2139Sjp161948 {0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
84*2139Sjp161948 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
85*2139Sjp161948 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
86*2139Sjp161948 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
87*2139Sjp161948 0x00000000000001FFULL};
88*2139Sjp161948 #elif BN_BITS2 == 32
89*2139Sjp161948 static const BN_ULONG _nist_p_192[] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFE,
90*2139Sjp161948 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
91*2139Sjp161948 static const BN_ULONG _nist_p_224[] = {0x00000001,0x00000000,0x00000000,
92*2139Sjp161948 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
93*2139Sjp161948 static const BN_ULONG _nist_p_256[] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
94*2139Sjp161948 0x00000000,0x00000000,0x00000000,0x00000001,0xFFFFFFFF};
95*2139Sjp161948 static const BN_ULONG _nist_p_384[] = {0xFFFFFFFF,0x00000000,0x00000000,
96*2139Sjp161948 0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
97*2139Sjp161948 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
98*2139Sjp161948 static const BN_ULONG _nist_p_521[] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
99*2139Sjp161948 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
100*2139Sjp161948 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
101*2139Sjp161948 0xFFFFFFFF,0x000001FF};
102*2139Sjp161948 #elif BN_BITS2 == 16
103*2139Sjp161948 static const BN_ULONG _nist_p_192[] = {0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFE,
104*2139Sjp161948 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF};
105*2139Sjp161948 static const BN_ULONG _nist_p_224[] = {0x0001,0x0000,0x0000,0x0000,0x0000,
106*2139Sjp161948 0x0000,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF};
107*2139Sjp161948 static const BN_ULONG _nist_p_256[] = {0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
108*2139Sjp161948 0xFFFF,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0001,0x0000,0xFFFF,
109*2139Sjp161948 0xFFFF};
110*2139Sjp161948 static const BN_ULONG _nist_p_384[] = {0xFFFF,0xFFFF,0x0000,0x0000,0x0000,
111*2139Sjp161948 0x0000,0xFFFF,0xFFFF,0xFFFE,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
112*2139Sjp161948 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF};
113*2139Sjp161948 static const BN_ULONG _nist_p_521[] = {0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
114*2139Sjp161948 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
115*2139Sjp161948 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
116*2139Sjp161948 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0x01FF};
117*2139Sjp161948 #elif BN_BITS2 == 8
118*2139Sjp161948 static const BN_ULONG _nist_p_192[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
119*2139Sjp161948 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
120*2139Sjp161948 0xFF,0xFF};
121*2139Sjp161948 static const BN_ULONG _nist_p_224[] = {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
122*2139Sjp161948 0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
123*2139Sjp161948 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
124*2139Sjp161948 static const BN_ULONG _nist_p_256[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
125*2139Sjp161948 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
126*2139Sjp161948 0x00,0x00,0x01,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF};
127*2139Sjp161948 static const BN_ULONG _nist_p_384[] = {0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
128*2139Sjp161948 0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,
129*2139Sjp161948 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
130*2139Sjp161948 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
131*2139Sjp161948 static const BN_ULONG _nist_p_521[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
132*2139Sjp161948 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
133*2139Sjp161948 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
134*2139Sjp161948 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
135*2139Sjp161948 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
136*2139Sjp161948 0xFF,0x01};
137*2139Sjp161948 #endif
138*2139Sjp161948
BN_get0_nist_prime_192(void)139*2139Sjp161948 const BIGNUM *BN_get0_nist_prime_192(void)
140*2139Sjp161948 {
141*2139Sjp161948 static BIGNUM const_nist_192 = { (BN_ULONG *)_nist_p_192,
142*2139Sjp161948 BN_NIST_192_TOP, BN_NIST_192_TOP, 0, BN_FLG_STATIC_DATA };
143*2139Sjp161948 return &const_nist_192;
144*2139Sjp161948 }
145*2139Sjp161948
BN_get0_nist_prime_224(void)146*2139Sjp161948 const BIGNUM *BN_get0_nist_prime_224(void)
147*2139Sjp161948 {
148*2139Sjp161948 static BIGNUM const_nist_224 = { (BN_ULONG *)_nist_p_224,
149*2139Sjp161948 BN_NIST_224_TOP, BN_NIST_224_TOP, 0, BN_FLG_STATIC_DATA };
150*2139Sjp161948 return &const_nist_224;
151*2139Sjp161948 }
152*2139Sjp161948
BN_get0_nist_prime_256(void)153*2139Sjp161948 const BIGNUM *BN_get0_nist_prime_256(void)
154*2139Sjp161948 {
155*2139Sjp161948 static BIGNUM const_nist_256 = { (BN_ULONG *)_nist_p_256,
156*2139Sjp161948 BN_NIST_256_TOP, BN_NIST_256_TOP, 0, BN_FLG_STATIC_DATA };
157*2139Sjp161948 return &const_nist_256;
158*2139Sjp161948 }
159*2139Sjp161948
BN_get0_nist_prime_384(void)160*2139Sjp161948 const BIGNUM *BN_get0_nist_prime_384(void)
161*2139Sjp161948 {
162*2139Sjp161948 static BIGNUM const_nist_384 = { (BN_ULONG *)_nist_p_384,
163*2139Sjp161948 BN_NIST_384_TOP, BN_NIST_384_TOP, 0, BN_FLG_STATIC_DATA };
164*2139Sjp161948 return &const_nist_384;
165*2139Sjp161948 }
166*2139Sjp161948
BN_get0_nist_prime_521(void)167*2139Sjp161948 const BIGNUM *BN_get0_nist_prime_521(void)
168*2139Sjp161948 {
169*2139Sjp161948 static BIGNUM const_nist_521 = { (BN_ULONG *)_nist_p_521,
170*2139Sjp161948 BN_NIST_521_TOP, BN_NIST_521_TOP, 0, BN_FLG_STATIC_DATA };
171*2139Sjp161948 return &const_nist_521;
172*2139Sjp161948 }
173*2139Sjp161948
174*2139Sjp161948 /* some misc internal functions */
175*2139Sjp161948 #if BN_BITS2 != 64
176*2139Sjp161948 static BN_ULONG _256_data[BN_NIST_256_TOP*6];
177*2139Sjp161948 static int _is_set_256_data = 0;
178*2139Sjp161948 static void _init_256_data(void);
179*2139Sjp161948
180*2139Sjp161948 static BN_ULONG _384_data[BN_NIST_384_TOP*8];
181*2139Sjp161948 static int _is_set_384_data = 0;
182*2139Sjp161948 static void _init_384_data(void);
183*2139Sjp161948 #endif
184*2139Sjp161948
185*2139Sjp161948 #define BN_NIST_ADD_ONE(a) while (!(++(*(a)))) ++(a);
186*2139Sjp161948
nist_cp_bn_0(BN_ULONG * buf,BN_ULONG * a,int top,int max)187*2139Sjp161948 static void nist_cp_bn_0(BN_ULONG *buf, BN_ULONG *a, int top, int max)
188*2139Sjp161948 {
189*2139Sjp161948 int i;
190*2139Sjp161948 BN_ULONG *_tmp1 = (buf), *_tmp2 = (a);
191*2139Sjp161948 for (i = (top); i != 0; i--)
192*2139Sjp161948 *_tmp1++ = *_tmp2++;
193*2139Sjp161948 for (i = (max) - (top); i != 0; i--)
194*2139Sjp161948 *_tmp1++ = (BN_ULONG) 0;
195*2139Sjp161948 }
196*2139Sjp161948
nist_cp_bn(BN_ULONG * buf,BN_ULONG * a,int top)197*2139Sjp161948 static void nist_cp_bn(BN_ULONG *buf, BN_ULONG *a, int top)
198*2139Sjp161948 {
199*2139Sjp161948 int i;
200*2139Sjp161948 BN_ULONG *_tmp1 = (buf), *_tmp2 = (a);
201*2139Sjp161948 for (i = (top); i != 0; i--)
202*2139Sjp161948 *_tmp1++ = *_tmp2++;
203*2139Sjp161948 }
204*2139Sjp161948
205*2139Sjp161948 #if BN_BITS2 == 64
206*2139Sjp161948 #define bn_cp_64(to, n, from, m) (to)[n] = (from)[m];
207*2139Sjp161948 #define bn_64_set_0(to, n) (to)[n] = (BN_ULONG)0;
208*2139Sjp161948 /* TBD */
209*2139Sjp161948 #define bn_cp_32(to, n, from, m) (to)[n] = (from)[m];
210*2139Sjp161948 #define bn_32_set_0(to, n) (to)[n] = (BN_ULONG)0;
211*2139Sjp161948 #else
212*2139Sjp161948 #define bn_cp_64(to, n, from, m) \
213*2139Sjp161948 { \
214*2139Sjp161948 bn_cp_32(to, (n)*2, from, (m)*2); \
215*2139Sjp161948 bn_cp_32(to, (n)*2+1, from, (m)*2+1); \
216*2139Sjp161948 }
217*2139Sjp161948 #define bn_64_set_0(to, n) \
218*2139Sjp161948 { \
219*2139Sjp161948 bn_32_set_0(to, (n)*2); \
220*2139Sjp161948 bn_32_set_0(to, (n)*2+1); \
221*2139Sjp161948 }
222*2139Sjp161948 #if BN_BITS2 == 32
223*2139Sjp161948 #define bn_cp_32(to, n, from, m) (to)[n] = (from)[m];
224*2139Sjp161948 #define bn_32_set_0(to, n) (to)[n] = (BN_ULONG)0;
225*2139Sjp161948 #elif BN_BITS2 == 16
226*2139Sjp161948 #define bn_cp_32(to, n, from, m) \
227*2139Sjp161948 { \
228*2139Sjp161948 (to)[(n)*2] = (from)[(m)*2]; \
229*2139Sjp161948 (to)[(n)*2+1] = (from)[(m)*2+1];\
230*2139Sjp161948 }
231*2139Sjp161948 #define bn_32_set_0(to, n) { (to)[(n)*2] = 0; (to)[(n)*2+1] = 0; }
232*2139Sjp161948 #elif BN_BITS2 == 8
233*2139Sjp161948 #define bn_cp_32(to, n, from, m) \
234*2139Sjp161948 { \
235*2139Sjp161948 (to)[(n)*4] = (from)[(m)*4]; \
236*2139Sjp161948 (to)[(n)*4+1] = (from)[(m)*4+1];\
237*2139Sjp161948 (to)[(n)*4+2] = (from)[(m)*4+2];\
238*2139Sjp161948 (to)[(n)*4+3] = (from)[(m)*4+3];\
239*2139Sjp161948 }
240*2139Sjp161948 #define bn_32_set_0(to, n) \
241*2139Sjp161948 { (to)[(n)*4] = (BN_ULONG)0; (to)[(n)*4+1] = (BN_ULONG)0; \
242*2139Sjp161948 (to)[(n)*4+2] = (BN_ULONG)0; (to)[(n)*4+3] = (BN_ULONG)0; }
243*2139Sjp161948 #endif
244*2139Sjp161948 #endif /* BN_BITS2 != 64 */
245*2139Sjp161948
246*2139Sjp161948
247*2139Sjp161948 #define nist_set_192(to, from, a1, a2, a3) \
248*2139Sjp161948 { \
249*2139Sjp161948 if (a3 != 0) bn_cp_64(to, 0, from, (a3) - 3) else bn_64_set_0(to, 0)\
250*2139Sjp161948 bn_cp_64(to, 1, from, (a2) - 3) \
251*2139Sjp161948 if (a1 != 0) bn_cp_64(to, 2, from, (a1) - 3) else bn_64_set_0(to, 2)\
252*2139Sjp161948 }
253*2139Sjp161948
BN_nist_mod_192(BIGNUM * r,const BIGNUM * a,const BIGNUM * field,BN_CTX * ctx)254*2139Sjp161948 int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
255*2139Sjp161948 BN_CTX *ctx)
256*2139Sjp161948 {
257*2139Sjp161948 int top = a->top, i;
258*2139Sjp161948 BN_ULONG carry = 0;
259*2139Sjp161948 register BN_ULONG *r_d, *a_d = a->d;
260*2139Sjp161948 BN_ULONG t_d[BN_NIST_192_TOP],
261*2139Sjp161948 buf[BN_NIST_192_TOP];
262*2139Sjp161948
263*2139Sjp161948 i = BN_ucmp(field, a);
264*2139Sjp161948 if (i == 0)
265*2139Sjp161948 {
266*2139Sjp161948 BN_zero(r);
267*2139Sjp161948 return 1;
268*2139Sjp161948 }
269*2139Sjp161948 else if (i > 0)
270*2139Sjp161948 return (r == a) ? 1 : (BN_copy(r ,a) != NULL);
271*2139Sjp161948
272*2139Sjp161948 if (top == BN_NIST_192_TOP)
273*2139Sjp161948 return BN_usub(r, a, field);
274*2139Sjp161948
275*2139Sjp161948 if (r != a)
276*2139Sjp161948 {
277*2139Sjp161948 if (!bn_wexpand(r, BN_NIST_192_TOP))
278*2139Sjp161948 return 0;
279*2139Sjp161948 r_d = r->d;
280*2139Sjp161948 nist_cp_bn(r_d, a_d, BN_NIST_192_TOP);
281*2139Sjp161948 }
282*2139Sjp161948 else
283*2139Sjp161948 r_d = a_d;
284*2139Sjp161948
285*2139Sjp161948 nist_cp_bn_0(buf, a_d + BN_NIST_192_TOP, top - BN_NIST_192_TOP, BN_NIST_192_TOP);
286*2139Sjp161948
287*2139Sjp161948 #if defined(OPENSSL_SYS_VMS) && defined(__DECC)
288*2139Sjp161948 # pragma message save
289*2139Sjp161948 # pragma message disable BADSUBSCRIPT
290*2139Sjp161948 #endif
291*2139Sjp161948
292*2139Sjp161948 nist_set_192(t_d, buf, 0, 3, 3);
293*2139Sjp161948 if (bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP))
294*2139Sjp161948 ++carry;
295*2139Sjp161948
296*2139Sjp161948 nist_set_192(t_d, buf, 4, 4, 0);
297*2139Sjp161948 if (bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP))
298*2139Sjp161948 ++carry;
299*2139Sjp161948
300*2139Sjp161948 #if defined(OPENSSL_SYS_VMS) && defined(__DECC)
301*2139Sjp161948 # pragma message restore
302*2139Sjp161948 #endif
303*2139Sjp161948
304*2139Sjp161948 nist_set_192(t_d, buf, 5, 5, 5)
305*2139Sjp161948 if (bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP))
306*2139Sjp161948 ++carry;
307*2139Sjp161948
308*2139Sjp161948 while (carry)
309*2139Sjp161948 {
310*2139Sjp161948 if (bn_sub_words(r_d, r_d, _nist_p_192, BN_NIST_192_TOP))
311*2139Sjp161948 --carry;
312*2139Sjp161948 }
313*2139Sjp161948 r->top = BN_NIST_192_TOP;
314*2139Sjp161948 bn_correct_top(r);
315*2139Sjp161948 if (BN_ucmp(r, field) >= 0)
316*2139Sjp161948 {
317*2139Sjp161948 bn_sub_words(r_d, r_d, _nist_p_192, BN_NIST_192_TOP);
318*2139Sjp161948 bn_correct_top(r);
319*2139Sjp161948 }
320*2139Sjp161948
321*2139Sjp161948 bn_check_top(r);
322*2139Sjp161948 return 1;
323*2139Sjp161948 }
324*2139Sjp161948
325*2139Sjp161948 #define nist_set_224(to, from, a1, a2, a3, a4, a5, a6, a7) \
326*2139Sjp161948 { \
327*2139Sjp161948 if (a7 != 0) bn_cp_32(to, 0, from, (a7) - 7) else bn_32_set_0(to, 0)\
328*2139Sjp161948 if (a6 != 0) bn_cp_32(to, 1, from, (a6) - 7) else bn_32_set_0(to, 1)\
329*2139Sjp161948 if (a5 != 0) bn_cp_32(to, 2, from, (a5) - 7) else bn_32_set_0(to, 2)\
330*2139Sjp161948 if (a4 != 0) bn_cp_32(to, 3, from, (a4) - 7) else bn_32_set_0(to, 3)\
331*2139Sjp161948 if (a3 != 0) bn_cp_32(to, 4, from, (a3) - 7) else bn_32_set_0(to, 4)\
332*2139Sjp161948 if (a2 != 0) bn_cp_32(to, 5, from, (a2) - 7) else bn_32_set_0(to, 5)\
333*2139Sjp161948 if (a1 != 0) bn_cp_32(to, 6, from, (a1) - 7) else bn_32_set_0(to, 6)\
334*2139Sjp161948 }
335*2139Sjp161948
BN_nist_mod_224(BIGNUM * r,const BIGNUM * a,const BIGNUM * field,BN_CTX * ctx)336*2139Sjp161948 int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
337*2139Sjp161948 BN_CTX *ctx)
338*2139Sjp161948 {
339*2139Sjp161948 #if BN_BITS2 != 64
340*2139Sjp161948 int top = a->top, i;
341*2139Sjp161948 int carry = 0;
342*2139Sjp161948 BN_ULONG *r_d, *a_d = a->d;
343*2139Sjp161948 BN_ULONG t_d[BN_NIST_224_TOP],
344*2139Sjp161948 buf[BN_NIST_224_TOP];
345*2139Sjp161948
346*2139Sjp161948 i = BN_ucmp(field, a);
347*2139Sjp161948 if (i == 0)
348*2139Sjp161948 {
349*2139Sjp161948 BN_zero(r);
350*2139Sjp161948 return 1;
351*2139Sjp161948 }
352*2139Sjp161948 else if (i > 0)
353*2139Sjp161948 return (r == a)? 1 : (BN_copy(r ,a) != NULL);
354*2139Sjp161948
355*2139Sjp161948 if (top == BN_NIST_224_TOP)
356*2139Sjp161948 return BN_usub(r, a, field);
357*2139Sjp161948
358*2139Sjp161948 if (r != a)
359*2139Sjp161948 {
360*2139Sjp161948 if (!bn_wexpand(r, BN_NIST_224_TOP))
361*2139Sjp161948 return 0;
362*2139Sjp161948 r_d = r->d;
363*2139Sjp161948 nist_cp_bn(r_d, a_d, BN_NIST_224_TOP);
364*2139Sjp161948 }
365*2139Sjp161948 else
366*2139Sjp161948 r_d = a_d;
367*2139Sjp161948
368*2139Sjp161948 nist_cp_bn_0(buf, a_d + BN_NIST_224_TOP, top - BN_NIST_224_TOP, BN_NIST_224_TOP);
369*2139Sjp161948
370*2139Sjp161948 nist_set_224(t_d, buf, 10, 9, 8, 7, 0, 0, 0);
371*2139Sjp161948 if (bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP))
372*2139Sjp161948 ++carry;
373*2139Sjp161948 nist_set_224(t_d, buf, 0, 13, 12, 11, 0, 0, 0);
374*2139Sjp161948 if (bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP))
375*2139Sjp161948 ++carry;
376*2139Sjp161948 nist_set_224(t_d, buf, 13, 12, 11, 10, 9, 8, 7);
377*2139Sjp161948 if (bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP))
378*2139Sjp161948 --carry;
379*2139Sjp161948 nist_set_224(t_d, buf, 0, 0, 0, 0, 13, 12, 11);
380*2139Sjp161948 if (bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP))
381*2139Sjp161948 --carry;
382*2139Sjp161948
383*2139Sjp161948 if (carry > 0)
384*2139Sjp161948 while (carry)
385*2139Sjp161948 {
386*2139Sjp161948 if (bn_sub_words(r_d,r_d,_nist_p_224,BN_NIST_224_TOP))
387*2139Sjp161948 --carry;
388*2139Sjp161948 }
389*2139Sjp161948 else if (carry < 0)
390*2139Sjp161948 while (carry)
391*2139Sjp161948 {
392*2139Sjp161948 if (bn_add_words(r_d,r_d,_nist_p_224,BN_NIST_224_TOP))
393*2139Sjp161948 ++carry;
394*2139Sjp161948 }
395*2139Sjp161948
396*2139Sjp161948 r->top = BN_NIST_224_TOP;
397*2139Sjp161948 bn_correct_top(r);
398*2139Sjp161948 if (BN_ucmp(r, field) >= 0)
399*2139Sjp161948 {
400*2139Sjp161948 bn_sub_words(r_d, r_d, _nist_p_224, BN_NIST_224_TOP);
401*2139Sjp161948 bn_correct_top(r);
402*2139Sjp161948 }
403*2139Sjp161948 bn_check_top(r);
404*2139Sjp161948 return 1;
405*2139Sjp161948 #else
406*2139Sjp161948 return 0;
407*2139Sjp161948 #endif
408*2139Sjp161948 }
409*2139Sjp161948
410*2139Sjp161948 #if BN_BITS2 != 64
_init_256_data(void)411*2139Sjp161948 static void _init_256_data(void)
412*2139Sjp161948 {
413*2139Sjp161948 int i;
414*2139Sjp161948 BN_ULONG *tmp1 = _256_data;
415*2139Sjp161948 const BN_ULONG *tmp2 = tmp1;
416*2139Sjp161948
417*2139Sjp161948 memcpy(tmp1, _nist_p_256, BN_NIST_256_TOP * sizeof(BN_ULONG));
418*2139Sjp161948 tmp1 += BN_NIST_256_TOP;
419*2139Sjp161948
420*2139Sjp161948 for (i=0; i<5; i++)
421*2139Sjp161948 {
422*2139Sjp161948 bn_add_words(tmp1, _nist_p_256, tmp2, BN_NIST_256_TOP);
423*2139Sjp161948 tmp2 = tmp1;
424*2139Sjp161948 tmp1 += BN_NIST_256_TOP;
425*2139Sjp161948 }
426*2139Sjp161948 _is_set_256_data = 1;
427*2139Sjp161948 }
428*2139Sjp161948 #endif
429*2139Sjp161948
430*2139Sjp161948 #define nist_set_256(to, from, a1, a2, a3, a4, a5, a6, a7, a8) \
431*2139Sjp161948 { \
432*2139Sjp161948 if (a8 != 0) bn_cp_32(to, 0, from, (a8) - 8) else bn_32_set_0(to, 0)\
433*2139Sjp161948 if (a7 != 0) bn_cp_32(to, 1, from, (a7) - 8) else bn_32_set_0(to, 1)\
434*2139Sjp161948 if (a6 != 0) bn_cp_32(to, 2, from, (a6) - 8) else bn_32_set_0(to, 2)\
435*2139Sjp161948 if (a5 != 0) bn_cp_32(to, 3, from, (a5) - 8) else bn_32_set_0(to, 3)\
436*2139Sjp161948 if (a4 != 0) bn_cp_32(to, 4, from, (a4) - 8) else bn_32_set_0(to, 4)\
437*2139Sjp161948 if (a3 != 0) bn_cp_32(to, 5, from, (a3) - 8) else bn_32_set_0(to, 5)\
438*2139Sjp161948 if (a2 != 0) bn_cp_32(to, 6, from, (a2) - 8) else bn_32_set_0(to, 6)\
439*2139Sjp161948 if (a1 != 0) bn_cp_32(to, 7, from, (a1) - 8) else bn_32_set_0(to, 7)\
440*2139Sjp161948 }
441*2139Sjp161948
BN_nist_mod_256(BIGNUM * r,const BIGNUM * a,const BIGNUM * field,BN_CTX * ctx)442*2139Sjp161948 int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
443*2139Sjp161948 BN_CTX *ctx)
444*2139Sjp161948 {
445*2139Sjp161948 #if BN_BITS2 != 64
446*2139Sjp161948 int i, top = a->top;
447*2139Sjp161948 int carry = 0;
448*2139Sjp161948 register BN_ULONG *a_d = a->d, *r_d;
449*2139Sjp161948 BN_ULONG t_d[BN_NIST_256_TOP],
450*2139Sjp161948 t_d2[BN_NIST_256_TOP],
451*2139Sjp161948 buf[BN_NIST_256_TOP];
452*2139Sjp161948
453*2139Sjp161948 if (!_is_set_256_data)
454*2139Sjp161948 {
455*2139Sjp161948 CRYPTO_w_lock(CRYPTO_LOCK_BN);
456*2139Sjp161948
457*2139Sjp161948 if (!_is_set_256_data)
458*2139Sjp161948 _init_256_data();
459*2139Sjp161948
460*2139Sjp161948 CRYPTO_w_unlock(CRYPTO_LOCK_BN);
461*2139Sjp161948 }
462*2139Sjp161948
463*2139Sjp161948 i = BN_ucmp(field, a);
464*2139Sjp161948 if (i == 0)
465*2139Sjp161948 {
466*2139Sjp161948 BN_zero(r);
467*2139Sjp161948 return 1;
468*2139Sjp161948 }
469*2139Sjp161948 else if (i > 0)
470*2139Sjp161948 return (r == a)? 1 : (BN_copy(r ,a) != NULL);
471*2139Sjp161948
472*2139Sjp161948 if (top == BN_NIST_256_TOP)
473*2139Sjp161948 return BN_usub(r, a, field);
474*2139Sjp161948
475*2139Sjp161948 if (r != a)
476*2139Sjp161948 {
477*2139Sjp161948 if (!bn_wexpand(r, BN_NIST_256_TOP))
478*2139Sjp161948 return 0;
479*2139Sjp161948 r_d = r->d;
480*2139Sjp161948 nist_cp_bn(r_d, a_d, BN_NIST_256_TOP);
481*2139Sjp161948 }
482*2139Sjp161948 else
483*2139Sjp161948 r_d = a_d;
484*2139Sjp161948
485*2139Sjp161948 nist_cp_bn_0(buf, a_d + BN_NIST_256_TOP, top - BN_NIST_256_TOP, BN_NIST_256_TOP);
486*2139Sjp161948
487*2139Sjp161948 /*S1*/
488*2139Sjp161948 nist_set_256(t_d, buf, 15, 14, 13, 12, 11, 0, 0, 0);
489*2139Sjp161948 /*S2*/
490*2139Sjp161948 nist_set_256(t_d2,buf, 0, 15, 14, 13, 12, 0, 0, 0);
491*2139Sjp161948 if (bn_add_words(t_d, t_d, t_d2, BN_NIST_256_TOP))
492*2139Sjp161948 carry = 2;
493*2139Sjp161948 /* left shift */
494*2139Sjp161948 {
495*2139Sjp161948 register BN_ULONG *ap,t,c;
496*2139Sjp161948 ap = t_d;
497*2139Sjp161948 c=0;
498*2139Sjp161948 for (i = BN_NIST_256_TOP; i != 0; --i)
499*2139Sjp161948 {
500*2139Sjp161948 t= *ap;
501*2139Sjp161948 *(ap++)=((t<<1)|c)&BN_MASK2;
502*2139Sjp161948 c=(t & BN_TBIT)?1:0;
503*2139Sjp161948 }
504*2139Sjp161948 if (c)
505*2139Sjp161948 ++carry;
506*2139Sjp161948 }
507*2139Sjp161948
508*2139Sjp161948 if (bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP))
509*2139Sjp161948 ++carry;
510*2139Sjp161948 /*S3*/
511*2139Sjp161948 nist_set_256(t_d, buf, 15, 14, 0, 0, 0, 10, 9, 8);
512*2139Sjp161948 if (bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP))
513*2139Sjp161948 ++carry;
514*2139Sjp161948 /*S4*/
515*2139Sjp161948 nist_set_256(t_d, buf, 8, 13, 15, 14, 13, 11, 10, 9);
516*2139Sjp161948 if (bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP))
517*2139Sjp161948 ++carry;
518*2139Sjp161948 /*D1*/
519*2139Sjp161948 nist_set_256(t_d, buf, 10, 8, 0, 0, 0, 13, 12, 11);
520*2139Sjp161948 if (bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP))
521*2139Sjp161948 --carry;
522*2139Sjp161948 /*D2*/
523*2139Sjp161948 nist_set_256(t_d, buf, 11, 9, 0, 0, 15, 14, 13, 12);
524*2139Sjp161948 if (bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP))
525*2139Sjp161948 --carry;
526*2139Sjp161948 /*D3*/
527*2139Sjp161948 nist_set_256(t_d, buf, 12, 0, 10, 9, 8, 15, 14, 13);
528*2139Sjp161948 if (bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP))
529*2139Sjp161948 --carry;
530*2139Sjp161948 /*D4*/
531*2139Sjp161948 nist_set_256(t_d, buf, 13, 0, 11, 10, 9, 0, 15, 14);
532*2139Sjp161948 if (bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP))
533*2139Sjp161948 --carry;
534*2139Sjp161948
535*2139Sjp161948 if (carry)
536*2139Sjp161948 {
537*2139Sjp161948 if (carry > 0)
538*2139Sjp161948 bn_sub_words(r_d, r_d, _256_data + BN_NIST_256_TOP *
539*2139Sjp161948 --carry, BN_NIST_256_TOP);
540*2139Sjp161948 else
541*2139Sjp161948 {
542*2139Sjp161948 carry = -carry;
543*2139Sjp161948 bn_add_words(r_d, r_d, _256_data + BN_NIST_256_TOP *
544*2139Sjp161948 --carry, BN_NIST_256_TOP);
545*2139Sjp161948 }
546*2139Sjp161948 }
547*2139Sjp161948
548*2139Sjp161948 r->top = BN_NIST_256_TOP;
549*2139Sjp161948 bn_correct_top(r);
550*2139Sjp161948 if (BN_ucmp(r, field) >= 0)
551*2139Sjp161948 {
552*2139Sjp161948 bn_sub_words(r_d, r_d, _nist_p_256, BN_NIST_256_TOP);
553*2139Sjp161948 bn_correct_top(r);
554*2139Sjp161948 }
555*2139Sjp161948 bn_check_top(r);
556*2139Sjp161948 return 1;
557*2139Sjp161948 #else
558*2139Sjp161948 return 0;
559*2139Sjp161948 #endif
560*2139Sjp161948 }
561*2139Sjp161948
562*2139Sjp161948 #if BN_BITS2 != 64
_init_384_data(void)563*2139Sjp161948 static void _init_384_data(void)
564*2139Sjp161948 {
565*2139Sjp161948 int i;
566*2139Sjp161948 BN_ULONG *tmp1 = _384_data;
567*2139Sjp161948 const BN_ULONG *tmp2 = tmp1;
568*2139Sjp161948
569*2139Sjp161948 memcpy(tmp1, _nist_p_384, BN_NIST_384_TOP * sizeof(BN_ULONG));
570*2139Sjp161948 tmp1 += BN_NIST_384_TOP;
571*2139Sjp161948
572*2139Sjp161948 for (i=0; i<7; i++)
573*2139Sjp161948 {
574*2139Sjp161948 bn_add_words(tmp1, _nist_p_384, tmp2, BN_NIST_384_TOP);
575*2139Sjp161948 tmp2 = tmp1;
576*2139Sjp161948 tmp1 += BN_NIST_384_TOP;
577*2139Sjp161948 }
578*2139Sjp161948 _is_set_384_data = 1;
579*2139Sjp161948 }
580*2139Sjp161948 #endif
581*2139Sjp161948
582*2139Sjp161948 #define nist_set_384(to,from,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) \
583*2139Sjp161948 { \
584*2139Sjp161948 if (a12 != 0) bn_cp_32(to, 0, from, (a12) - 12) else bn_32_set_0(to, 0)\
585*2139Sjp161948 if (a11 != 0) bn_cp_32(to, 1, from, (a11) - 12) else bn_32_set_0(to, 1)\
586*2139Sjp161948 if (a10 != 0) bn_cp_32(to, 2, from, (a10) - 12) else bn_32_set_0(to, 2)\
587*2139Sjp161948 if (a9 != 0) bn_cp_32(to, 3, from, (a9) - 12) else bn_32_set_0(to, 3)\
588*2139Sjp161948 if (a8 != 0) bn_cp_32(to, 4, from, (a8) - 12) else bn_32_set_0(to, 4)\
589*2139Sjp161948 if (a7 != 0) bn_cp_32(to, 5, from, (a7) - 12) else bn_32_set_0(to, 5)\
590*2139Sjp161948 if (a6 != 0) bn_cp_32(to, 6, from, (a6) - 12) else bn_32_set_0(to, 6)\
591*2139Sjp161948 if (a5 != 0) bn_cp_32(to, 7, from, (a5) - 12) else bn_32_set_0(to, 7)\
592*2139Sjp161948 if (a4 != 0) bn_cp_32(to, 8, from, (a4) - 12) else bn_32_set_0(to, 8)\
593*2139Sjp161948 if (a3 != 0) bn_cp_32(to, 9, from, (a3) - 12) else bn_32_set_0(to, 9)\
594*2139Sjp161948 if (a2 != 0) bn_cp_32(to, 10, from, (a2) - 12) else bn_32_set_0(to, 10)\
595*2139Sjp161948 if (a1 != 0) bn_cp_32(to, 11, from, (a1) - 12) else bn_32_set_0(to, 11)\
596*2139Sjp161948 }
597*2139Sjp161948
BN_nist_mod_384(BIGNUM * r,const BIGNUM * a,const BIGNUM * field,BN_CTX * ctx)598*2139Sjp161948 int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
599*2139Sjp161948 BN_CTX *ctx)
600*2139Sjp161948 {
601*2139Sjp161948 #if BN_BITS2 != 64
602*2139Sjp161948 int i, top = a->top;
603*2139Sjp161948 int carry = 0;
604*2139Sjp161948 register BN_ULONG *r_d, *a_d = a->d;
605*2139Sjp161948 BN_ULONG t_d[BN_NIST_384_TOP],
606*2139Sjp161948 buf[BN_NIST_384_TOP];
607*2139Sjp161948
608*2139Sjp161948 if (!_is_set_384_data)
609*2139Sjp161948 {
610*2139Sjp161948 CRYPTO_w_lock(CRYPTO_LOCK_BN);
611*2139Sjp161948
612*2139Sjp161948 if (!_is_set_384_data)
613*2139Sjp161948 _init_384_data();
614*2139Sjp161948
615*2139Sjp161948 CRYPTO_w_unlock(CRYPTO_LOCK_BN);
616*2139Sjp161948 }
617*2139Sjp161948
618*2139Sjp161948 i = BN_ucmp(field, a);
619*2139Sjp161948 if (i == 0)
620*2139Sjp161948 {
621*2139Sjp161948 BN_zero(r);
622*2139Sjp161948 return 1;
623*2139Sjp161948 }
624*2139Sjp161948 else if (i > 0)
625*2139Sjp161948 return (r == a)? 1 : (BN_copy(r ,a) != NULL);
626*2139Sjp161948
627*2139Sjp161948 if (top == BN_NIST_384_TOP)
628*2139Sjp161948 return BN_usub(r, a, field);
629*2139Sjp161948
630*2139Sjp161948 if (r != a)
631*2139Sjp161948 {
632*2139Sjp161948 if (!bn_wexpand(r, BN_NIST_384_TOP))
633*2139Sjp161948 return 0;
634*2139Sjp161948 r_d = r->d;
635*2139Sjp161948 nist_cp_bn(r_d, a_d, BN_NIST_384_TOP);
636*2139Sjp161948 }
637*2139Sjp161948 else
638*2139Sjp161948 r_d = a_d;
639*2139Sjp161948
640*2139Sjp161948 nist_cp_bn_0(buf, a_d + BN_NIST_384_TOP, top - BN_NIST_384_TOP, BN_NIST_384_TOP);
641*2139Sjp161948
642*2139Sjp161948 /*S1*/
643*2139Sjp161948 nist_set_256(t_d, buf, 0, 0, 0, 0, 0, 23-4, 22-4, 21-4);
644*2139Sjp161948 /* left shift */
645*2139Sjp161948 {
646*2139Sjp161948 register BN_ULONG *ap,t,c;
647*2139Sjp161948 ap = t_d;
648*2139Sjp161948 c=0;
649*2139Sjp161948 for (i = BN_NIST_256_TOP; i != 0; --i)
650*2139Sjp161948 {
651*2139Sjp161948 t= *ap;
652*2139Sjp161948 *(ap++)=((t<<1)|c)&BN_MASK2;
653*2139Sjp161948 c=(t & BN_TBIT)?1:0;
654*2139Sjp161948 }
655*2139Sjp161948 }
656*2139Sjp161948 if (bn_add_words(r_d+(128/BN_BITS2), r_d+(128/BN_BITS2),
657*2139Sjp161948 t_d, BN_NIST_256_TOP))
658*2139Sjp161948 ++carry;
659*2139Sjp161948 /*S2 */
660*2139Sjp161948 if (bn_add_words(r_d, r_d, buf, BN_NIST_384_TOP))
661*2139Sjp161948 ++carry;
662*2139Sjp161948 /*S3*/
663*2139Sjp161948 nist_set_384(t_d,buf,20,19,18,17,16,15,14,13,12,23,22,21);
664*2139Sjp161948 if (bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP))
665*2139Sjp161948 ++carry;
666*2139Sjp161948 /*S4*/
667*2139Sjp161948 nist_set_384(t_d,buf,19,18,17,16,15,14,13,12,20,0,23,0);
668*2139Sjp161948 if (bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP))
669*2139Sjp161948 ++carry;
670*2139Sjp161948 /*S5*/
671*2139Sjp161948 nist_set_256(t_d, buf, 0, 0, 0, 0, 23-4, 22-4, 21-4, 20-4);
672*2139Sjp161948 if (bn_add_words(r_d+(128/BN_BITS2), r_d+(128/BN_BITS2),
673*2139Sjp161948 t_d, BN_NIST_256_TOP))
674*2139Sjp161948 ++carry;
675*2139Sjp161948 /*S6*/
676*2139Sjp161948 nist_set_384(t_d,buf,0,0,0,0,0,0,23,22,21,0,0,20);
677*2139Sjp161948 if (bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP))
678*2139Sjp161948 ++carry;
679*2139Sjp161948 /*D1*/
680*2139Sjp161948 nist_set_384(t_d,buf,22,21,20,19,18,17,16,15,14,13,12,23);
681*2139Sjp161948 if (bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP))
682*2139Sjp161948 --carry;
683*2139Sjp161948 /*D2*/
684*2139Sjp161948 nist_set_384(t_d,buf,0,0,0,0,0,0,0,23,22,21,20,0);
685*2139Sjp161948 if (bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP))
686*2139Sjp161948 --carry;
687*2139Sjp161948 /*D3*/
688*2139Sjp161948 nist_set_384(t_d,buf,0,0,0,0,0,0,0,23,23,0,0,0);
689*2139Sjp161948 if (bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP))
690*2139Sjp161948 --carry;
691*2139Sjp161948
692*2139Sjp161948 if (carry)
693*2139Sjp161948 {
694*2139Sjp161948 if (carry > 0)
695*2139Sjp161948 bn_sub_words(r_d, r_d, _384_data + BN_NIST_384_TOP *
696*2139Sjp161948 --carry, BN_NIST_384_TOP);
697*2139Sjp161948 else
698*2139Sjp161948 {
699*2139Sjp161948 carry = -carry;
700*2139Sjp161948 bn_add_words(r_d, r_d, _384_data + BN_NIST_384_TOP *
701*2139Sjp161948 --carry, BN_NIST_384_TOP);
702*2139Sjp161948 }
703*2139Sjp161948 }
704*2139Sjp161948
705*2139Sjp161948 r->top = BN_NIST_384_TOP;
706*2139Sjp161948 bn_correct_top(r);
707*2139Sjp161948 if (BN_ucmp(r, field) >= 0)
708*2139Sjp161948 {
709*2139Sjp161948 bn_sub_words(r_d, r_d, _nist_p_384, BN_NIST_384_TOP);
710*2139Sjp161948 bn_correct_top(r);
711*2139Sjp161948 }
712*2139Sjp161948 bn_check_top(r);
713*2139Sjp161948 return 1;
714*2139Sjp161948 #else
715*2139Sjp161948 return 0;
716*2139Sjp161948 #endif
717*2139Sjp161948 }
718*2139Sjp161948
BN_nist_mod_521(BIGNUM * r,const BIGNUM * a,const BIGNUM * field,BN_CTX * ctx)719*2139Sjp161948 int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
720*2139Sjp161948 BN_CTX *ctx)
721*2139Sjp161948 {
722*2139Sjp161948 #if BN_BITS2 == 64
723*2139Sjp161948 #define BN_NIST_521_TOP_MASK (BN_ULONG)0x1FF
724*2139Sjp161948 #elif BN_BITS2 == 32
725*2139Sjp161948 #define BN_NIST_521_TOP_MASK (BN_ULONG)0x1FF
726*2139Sjp161948 #elif BN_BITS2 == 16
727*2139Sjp161948 #define BN_NIST_521_TOP_MASK (BN_ULONG)0x1FF
728*2139Sjp161948 #elif BN_BITS2 == 8
729*2139Sjp161948 #define BN_NIST_521_TOP_MASK (BN_ULONG)0x1
730*2139Sjp161948 #endif
731*2139Sjp161948 int top, ret = 0;
732*2139Sjp161948 BN_ULONG *r_d;
733*2139Sjp161948 BIGNUM *tmp;
734*2139Sjp161948
735*2139Sjp161948 /* check whether a reduction is necessary */
736*2139Sjp161948 top = a->top;
737*2139Sjp161948 if (top < BN_NIST_521_TOP || ( top == BN_NIST_521_TOP &&
738*2139Sjp161948 (!(a->d[BN_NIST_521_TOP-1] & ~(BN_NIST_521_TOP_MASK)))))
739*2139Sjp161948 return (r == a)? 1 : (BN_copy(r ,a) != NULL);
740*2139Sjp161948
741*2139Sjp161948 BN_CTX_start(ctx);
742*2139Sjp161948 tmp = BN_CTX_get(ctx);
743*2139Sjp161948 if (!tmp)
744*2139Sjp161948 goto err;
745*2139Sjp161948
746*2139Sjp161948 if (!bn_wexpand(tmp, BN_NIST_521_TOP))
747*2139Sjp161948 goto err;
748*2139Sjp161948 nist_cp_bn(tmp->d, a->d, BN_NIST_521_TOP);
749*2139Sjp161948
750*2139Sjp161948 tmp->top = BN_NIST_521_TOP;
751*2139Sjp161948 tmp->d[BN_NIST_521_TOP-1] &= BN_NIST_521_TOP_MASK;
752*2139Sjp161948 bn_correct_top(tmp);
753*2139Sjp161948
754*2139Sjp161948 if (!BN_rshift(r, a, 521))
755*2139Sjp161948 goto err;
756*2139Sjp161948
757*2139Sjp161948 if (!BN_uadd(r, tmp, r))
758*2139Sjp161948 goto err;
759*2139Sjp161948 top = r->top;
760*2139Sjp161948 r_d = r->d;
761*2139Sjp161948 if (top == BN_NIST_521_TOP &&
762*2139Sjp161948 (r_d[BN_NIST_521_TOP-1] & ~(BN_NIST_521_TOP_MASK)))
763*2139Sjp161948 {
764*2139Sjp161948 BN_NIST_ADD_ONE(r_d)
765*2139Sjp161948 r_d[BN_NIST_521_TOP-1] &= BN_NIST_521_TOP_MASK;
766*2139Sjp161948 }
767*2139Sjp161948 bn_correct_top(r);
768*2139Sjp161948
769*2139Sjp161948 ret = 1;
770*2139Sjp161948 err:
771*2139Sjp161948 BN_CTX_end(ctx);
772*2139Sjp161948
773*2139Sjp161948 bn_check_top(r);
774*2139Sjp161948 return ret;
775*2139Sjp161948 }
776