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