xref: /onnv-gate/usr/src/common/openssl/crypto/bn/bn_nist.c (revision 2139:6243c3338933)
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