1160814Ssimon/* crypto/bn/bn_nist.c */ 2160814Ssimon/* 3160814Ssimon * Written by Nils Larsch for the OpenSSL project 4160814Ssimon */ 5160814Ssimon/* ==================================================================== 6160814Ssimon * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. 7160814Ssimon * 8160814Ssimon * Redistribution and use in source and binary forms, with or without 9160814Ssimon * modification, are permitted provided that the following conditions 10160814Ssimon * are met: 11160814Ssimon * 12160814Ssimon * 1. Redistributions of source code must retain the above copyright 13160814Ssimon * notice, this list of conditions and the following disclaimer. 14160814Ssimon * 15160814Ssimon * 2. Redistributions in binary form must reproduce the above copyright 16160814Ssimon * notice, this list of conditions and the following disclaimer in 17160814Ssimon * the documentation and/or other materials provided with the 18160814Ssimon * distribution. 19160814Ssimon * 20160814Ssimon * 3. All advertising materials mentioning features or use of this 21160814Ssimon * software must display the following acknowledgment: 22160814Ssimon * "This product includes software developed by the OpenSSL Project 23160814Ssimon * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 24160814Ssimon * 25160814Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26160814Ssimon * endorse or promote products derived from this software without 27160814Ssimon * prior written permission. For written permission, please contact 28160814Ssimon * openssl-core@openssl.org. 29160814Ssimon * 30160814Ssimon * 5. Products derived from this software may not be called "OpenSSL" 31160814Ssimon * nor may "OpenSSL" appear in their names without prior written 32160814Ssimon * permission of the OpenSSL Project. 33160814Ssimon * 34160814Ssimon * 6. Redistributions of any form whatsoever must retain the following 35160814Ssimon * acknowledgment: 36160814Ssimon * "This product includes software developed by the OpenSSL Project 37160814Ssimon * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 38160814Ssimon * 39160814Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40160814Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41160814Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42160814Ssimon * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43160814Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44160814Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45160814Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46160814Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47160814Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48160814Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49160814Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50160814Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE. 51160814Ssimon * ==================================================================== 52160814Ssimon * 53160814Ssimon * This product includes cryptographic software written by Eric Young 54160814Ssimon * (eay@cryptsoft.com). This product includes software written by Tim 55160814Ssimon * Hudson (tjh@cryptsoft.com). 56160814Ssimon * 57160814Ssimon */ 58160814Ssimon 59160814Ssimon#include "bn_lcl.h" 60160814Ssimon#include "cryptlib.h" 61160814Ssimon 62194206Ssimon 63160814Ssimon#define BN_NIST_192_TOP (192+BN_BITS2-1)/BN_BITS2 64160814Ssimon#define BN_NIST_224_TOP (224+BN_BITS2-1)/BN_BITS2 65160814Ssimon#define BN_NIST_256_TOP (256+BN_BITS2-1)/BN_BITS2 66160814Ssimon#define BN_NIST_384_TOP (384+BN_BITS2-1)/BN_BITS2 67160814Ssimon#define BN_NIST_521_TOP (521+BN_BITS2-1)/BN_BITS2 68160814Ssimon 69194206Ssimon/* pre-computed tables are "carry-less" values of modulus*(i+1) */ 70160814Ssimon#if BN_BITS2 == 64 71194206Ssimonstatic const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = { 72194206Ssimon {0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFEULL,0xFFFFFFFFFFFFFFFFULL}, 73194206Ssimon {0xFFFFFFFFFFFFFFFEULL,0xFFFFFFFFFFFFFFFDULL,0xFFFFFFFFFFFFFFFFULL}, 74194206Ssimon {0xFFFFFFFFFFFFFFFDULL,0xFFFFFFFFFFFFFFFCULL,0xFFFFFFFFFFFFFFFFULL} 75194206Ssimon }; 76194206Ssimonstatic const BN_ULONG _nist_p_192_sqr[] = { 77194206Ssimon 0x0000000000000001ULL,0x0000000000000002ULL,0x0000000000000001ULL, 78194206Ssimon 0xFFFFFFFFFFFFFFFEULL,0xFFFFFFFFFFFFFFFDULL,0xFFFFFFFFFFFFFFFFULL 79194206Ssimon }; 80194206Ssimonstatic const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = { 81160814Ssimon {0x0000000000000001ULL,0xFFFFFFFF00000000ULL, 82194206Ssimon 0xFFFFFFFFFFFFFFFFULL,0x00000000FFFFFFFFULL}, 83194206Ssimon {0x0000000000000002ULL,0xFFFFFFFE00000000ULL, 84194206Ssimon 0xFFFFFFFFFFFFFFFFULL,0x00000001FFFFFFFFULL} /* this one is "carry-full" */ 85194206Ssimon }; 86194206Ssimonstatic const BN_ULONG _nist_p_224_sqr[] = { 87194206Ssimon 0x0000000000000001ULL,0xFFFFFFFE00000000ULL, 88194206Ssimon 0xFFFFFFFFFFFFFFFFULL,0x0000000200000000ULL, 89194206Ssimon 0x0000000000000000ULL,0xFFFFFFFFFFFFFFFEULL, 90194206Ssimon 0xFFFFFFFFFFFFFFFFULL 91194206Ssimon }; 92194206Ssimonstatic const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = { 93160814Ssimon {0xFFFFFFFFFFFFFFFFULL,0x00000000FFFFFFFFULL, 94194206Ssimon 0x0000000000000000ULL,0xFFFFFFFF00000001ULL}, 95194206Ssimon {0xFFFFFFFFFFFFFFFEULL,0x00000001FFFFFFFFULL, 96194206Ssimon 0x0000000000000000ULL,0xFFFFFFFE00000002ULL}, 97194206Ssimon {0xFFFFFFFFFFFFFFFDULL,0x00000002FFFFFFFFULL, 98194206Ssimon 0x0000000000000000ULL,0xFFFFFFFD00000003ULL}, 99194206Ssimon {0xFFFFFFFFFFFFFFFCULL,0x00000003FFFFFFFFULL, 100194206Ssimon 0x0000000000000000ULL,0xFFFFFFFC00000004ULL}, 101194206Ssimon {0xFFFFFFFFFFFFFFFBULL,0x00000004FFFFFFFFULL, 102194206Ssimon 0x0000000000000000ULL,0xFFFFFFFB00000005ULL}, 103194206Ssimon }; 104194206Ssimonstatic const BN_ULONG _nist_p_256_sqr[] = { 105194206Ssimon 0x0000000000000001ULL,0xFFFFFFFE00000000ULL, 106194206Ssimon 0xFFFFFFFFFFFFFFFFULL,0x00000001FFFFFFFEULL, 107194206Ssimon 0x00000001FFFFFFFEULL,0x00000001FFFFFFFEULL, 108194206Ssimon 0xFFFFFFFE00000001ULL,0xFFFFFFFE00000002ULL 109194206Ssimon }; 110194206Ssimonstatic const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = { 111194206Ssimon {0x00000000FFFFFFFFULL,0xFFFFFFFF00000000ULL,0xFFFFFFFFFFFFFFFEULL, 112194206Ssimon 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL}, 113194206Ssimon {0x00000001FFFFFFFEULL,0xFFFFFFFE00000000ULL,0xFFFFFFFFFFFFFFFDULL, 114194206Ssimon 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL}, 115194206Ssimon {0x00000002FFFFFFFDULL,0xFFFFFFFD00000000ULL,0xFFFFFFFFFFFFFFFCULL, 116194206Ssimon 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL}, 117194206Ssimon {0x00000003FFFFFFFCULL,0xFFFFFFFC00000000ULL,0xFFFFFFFFFFFFFFFBULL, 118194206Ssimon 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL}, 119194206Ssimon {0x00000004FFFFFFFBULL,0xFFFFFFFB00000000ULL,0xFFFFFFFFFFFFFFFAULL, 120194206Ssimon 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL}, 121194206Ssimon }; 122194206Ssimonstatic const BN_ULONG _nist_p_384_sqr[] = { 123194206Ssimon 0xFFFFFFFE00000001ULL,0x0000000200000000ULL,0xFFFFFFFE00000000ULL, 124194206Ssimon 0x0000000200000000ULL,0x0000000000000001ULL,0x0000000000000000ULL, 125194206Ssimon 0x00000001FFFFFFFEULL,0xFFFFFFFE00000000ULL,0xFFFFFFFFFFFFFFFDULL, 126194206Ssimon 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL 127194206Ssimon }; 128160814Ssimonstatic const BN_ULONG _nist_p_521[] = 129160814Ssimon {0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL, 130160814Ssimon 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL, 131160814Ssimon 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL, 132160814Ssimon 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL, 133160814Ssimon 0x00000000000001FFULL}; 134194206Ssimonstatic const BN_ULONG _nist_p_521_sqr[] = { 135194206Ssimon 0x0000000000000001ULL,0x0000000000000000ULL,0x0000000000000000ULL, 136194206Ssimon 0x0000000000000000ULL,0x0000000000000000ULL,0x0000000000000000ULL, 137194206Ssimon 0x0000000000000000ULL,0x0000000000000000ULL,0xFFFFFFFFFFFFFC00ULL, 138194206Ssimon 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL, 139194206Ssimon 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL, 140194206Ssimon 0xFFFFFFFFFFFFFFFFULL,0x000000000003FFFFULL 141194206Ssimon }; 142160814Ssimon#elif BN_BITS2 == 32 143194206Ssimonstatic const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = { 144194206Ssimon {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}, 145194206Ssimon {0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFD,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}, 146194206Ssimon {0xFFFFFFFD,0xFFFFFFFF,0xFFFFFFFC,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF} 147194206Ssimon }; 148194206Ssimonstatic const BN_ULONG _nist_p_192_sqr[] = { 149194206Ssimon 0x00000001,0x00000000,0x00000002,0x00000000,0x00000001,0x00000000, 150194206Ssimon 0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFD,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF 151194206Ssimon }; 152194206Ssimonstatic const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = { 153194206Ssimon {0x00000001,0x00000000,0x00000000,0xFFFFFFFF, 154194206Ssimon 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}, 155194206Ssimon {0x00000002,0x00000000,0x00000000,0xFFFFFFFE, 156194206Ssimon 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF} 157194206Ssimon }; 158194206Ssimonstatic const BN_ULONG _nist_p_224_sqr[] = { 159194206Ssimon 0x00000001,0x00000000,0x00000000,0xFFFFFFFE, 160194206Ssimon 0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000002, 161194206Ssimon 0x00000000,0x00000000,0xFFFFFFFE,0xFFFFFFFF, 162194206Ssimon 0xFFFFFFFF,0xFFFFFFFF 163194206Ssimon }; 164194206Ssimonstatic const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = { 165194206Ssimon {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x00000000, 166194206Ssimon 0x00000000,0x00000000,0x00000001,0xFFFFFFFF}, 167194206Ssimon {0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0x00000001, 168194206Ssimon 0x00000000,0x00000000,0x00000002,0xFFFFFFFE}, 169194206Ssimon {0xFFFFFFFD,0xFFFFFFFF,0xFFFFFFFF,0x00000002, 170194206Ssimon 0x00000000,0x00000000,0x00000003,0xFFFFFFFD}, 171194206Ssimon {0xFFFFFFFC,0xFFFFFFFF,0xFFFFFFFF,0x00000003, 172194206Ssimon 0x00000000,0x00000000,0x00000004,0xFFFFFFFC}, 173194206Ssimon {0xFFFFFFFB,0xFFFFFFFF,0xFFFFFFFF,0x00000004, 174194206Ssimon 0x00000000,0x00000000,0x00000005,0xFFFFFFFB}, 175194206Ssimon }; 176194206Ssimonstatic const BN_ULONG _nist_p_256_sqr[] = { 177194206Ssimon 0x00000001,0x00000000,0x00000000,0xFFFFFFFE, 178194206Ssimon 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFE,0x00000001, 179194206Ssimon 0xFFFFFFFE,0x00000001,0xFFFFFFFE,0x00000001, 180194206Ssimon 0x00000001,0xFFFFFFFE,0x00000002,0xFFFFFFFE 181194206Ssimon }; 182194206Ssimonstatic const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = { 183194206Ssimon {0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF, 184194206Ssimon 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}, 185194206Ssimon {0xFFFFFFFE,0x00000001,0x00000000,0xFFFFFFFE,0xFFFFFFFD,0xFFFFFFFF, 186194206Ssimon 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}, 187194206Ssimon {0xFFFFFFFD,0x00000002,0x00000000,0xFFFFFFFD,0xFFFFFFFC,0xFFFFFFFF, 188194206Ssimon 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}, 189194206Ssimon {0xFFFFFFFC,0x00000003,0x00000000,0xFFFFFFFC,0xFFFFFFFB,0xFFFFFFFF, 190194206Ssimon 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}, 191194206Ssimon {0xFFFFFFFB,0x00000004,0x00000000,0xFFFFFFFB,0xFFFFFFFA,0xFFFFFFFF, 192194206Ssimon 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}, 193194206Ssimon }; 194194206Ssimonstatic const BN_ULONG _nist_p_384_sqr[] = { 195194206Ssimon 0x00000001,0xFFFFFFFE,0x00000000,0x00000002,0x00000000,0xFFFFFFFE, 196194206Ssimon 0x00000000,0x00000002,0x00000001,0x00000000,0x00000000,0x00000000, 197194206Ssimon 0xFFFFFFFE,0x00000001,0x00000000,0xFFFFFFFE,0xFFFFFFFD,0xFFFFFFFF, 198194206Ssimon 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF 199194206Ssimon }; 200160814Ssimonstatic const BN_ULONG _nist_p_521[] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, 201160814Ssimon 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, 202160814Ssimon 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, 203160814Ssimon 0xFFFFFFFF,0x000001FF}; 204194206Ssimonstatic const BN_ULONG _nist_p_521_sqr[] = { 205194206Ssimon 0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 206194206Ssimon 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 207194206Ssimon 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFC00,0xFFFFFFFF, 208194206Ssimon 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, 209194206Ssimon 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, 210194206Ssimon 0xFFFFFFFF,0xFFFFFFFF,0x0003FFFF 211194206Ssimon }; 212194206Ssimon#else 213194206Ssimon#error "unsupported BN_BITS2" 214160814Ssimon#endif 215160814Ssimon 216194206Ssimon 217194206Ssimonstatic const BIGNUM _bignum_nist_p_192 = 218194206Ssimon { 219194206Ssimon (BN_ULONG *)_nist_p_192[0], 220194206Ssimon BN_NIST_192_TOP, 221194206Ssimon BN_NIST_192_TOP, 222194206Ssimon 0, 223194206Ssimon BN_FLG_STATIC_DATA 224194206Ssimon }; 225194206Ssimon 226194206Ssimonstatic const BIGNUM _bignum_nist_p_224 = 227194206Ssimon { 228194206Ssimon (BN_ULONG *)_nist_p_224[0], 229194206Ssimon BN_NIST_224_TOP, 230194206Ssimon BN_NIST_224_TOP, 231194206Ssimon 0, 232194206Ssimon BN_FLG_STATIC_DATA 233194206Ssimon }; 234194206Ssimon 235194206Ssimonstatic const BIGNUM _bignum_nist_p_256 = 236194206Ssimon { 237194206Ssimon (BN_ULONG *)_nist_p_256[0], 238194206Ssimon BN_NIST_256_TOP, 239194206Ssimon BN_NIST_256_TOP, 240194206Ssimon 0, 241194206Ssimon BN_FLG_STATIC_DATA 242194206Ssimon }; 243194206Ssimon 244194206Ssimonstatic const BIGNUM _bignum_nist_p_384 = 245194206Ssimon { 246194206Ssimon (BN_ULONG *)_nist_p_384[0], 247194206Ssimon BN_NIST_384_TOP, 248194206Ssimon BN_NIST_384_TOP, 249194206Ssimon 0, 250194206Ssimon BN_FLG_STATIC_DATA 251194206Ssimon }; 252194206Ssimon 253194206Ssimonstatic const BIGNUM _bignum_nist_p_521 = 254194206Ssimon { 255194206Ssimon (BN_ULONG *)_nist_p_521, 256194206Ssimon BN_NIST_521_TOP, 257194206Ssimon BN_NIST_521_TOP, 258194206Ssimon 0, 259194206Ssimon BN_FLG_STATIC_DATA 260194206Ssimon }; 261194206Ssimon 262194206Ssimon 263160814Ssimonconst BIGNUM *BN_get0_nist_prime_192(void) 264160814Ssimon { 265194206Ssimon return &_bignum_nist_p_192; 266160814Ssimon } 267160814Ssimon 268160814Ssimonconst BIGNUM *BN_get0_nist_prime_224(void) 269160814Ssimon { 270194206Ssimon return &_bignum_nist_p_224; 271160814Ssimon } 272160814Ssimon 273160814Ssimonconst BIGNUM *BN_get0_nist_prime_256(void) 274160814Ssimon { 275194206Ssimon return &_bignum_nist_p_256; 276160814Ssimon } 277160814Ssimon 278160814Ssimonconst BIGNUM *BN_get0_nist_prime_384(void) 279160814Ssimon { 280194206Ssimon return &_bignum_nist_p_384; 281160814Ssimon } 282160814Ssimon 283160814Ssimonconst BIGNUM *BN_get0_nist_prime_521(void) 284160814Ssimon { 285194206Ssimon return &_bignum_nist_p_521; 286160814Ssimon } 287160814Ssimon 288160814Ssimon 289279264Sdelphijstatic void nist_cp_bn_0(BN_ULONG *dst, const BN_ULONG *src, int top, int max) 290194206Ssimon { 291160814Ssimon int i; 292160814Ssimon 293194206Ssimon#ifdef BN_DEBUG 294194206Ssimon OPENSSL_assert(top <= max); 295194206Ssimon#endif 296279264Sdelphij for (i = 0; i < top; i++) 297279264Sdelphij dst[i] = src[i]; 298279264Sdelphij for (; i < max; i++) 299279264Sdelphij dst[i] = 0; 300194206Ssimon } 301194206Ssimon 302279264Sdelphijstatic void nist_cp_bn(BN_ULONG *dst, const BN_ULONG *src, int top) 303194206Ssimon { 304160814Ssimon int i; 305279264Sdelphij 306279264Sdelphij for (i = 0; i < top; i++) 307279264Sdelphij dst[i] = src[i]; 308194206Ssimon } 309160814Ssimon 310160814Ssimon#if BN_BITS2 == 64 311194206Ssimon#define bn_cp_64(to, n, from, m) (to)[n] = (m>=0)?((from)[m]):0; 312160814Ssimon#define bn_64_set_0(to, n) (to)[n] = (BN_ULONG)0; 313194206Ssimon/* 314194206Ssimon * two following macros are implemented under assumption that they 315194206Ssimon * are called in a sequence with *ascending* n, i.e. as they are... 316194206Ssimon */ 317194206Ssimon#define bn_cp_32_naked(to, n, from, m) (((n)&1)?(to[(n)/2]|=((m)&1)?(from[(m)/2]&BN_MASK2h):(from[(m)/2]<<32))\ 318194206Ssimon :(to[(n)/2] =((m)&1)?(from[(m)/2]>>32):(from[(m)/2]&BN_MASK2l))) 319194206Ssimon#define bn_32_set_0(to, n) (((n)&1)?(to[(n)/2]&=BN_MASK2l):(to[(n)/2]=0)); 320194206Ssimon#define bn_cp_32(to,n,from,m) ((m)>=0)?bn_cp_32_naked(to,n,from,m):bn_32_set_0(to,n) 321238405Sjkim# if defined(L_ENDIAN) 322238405Sjkim# if defined(__arch64__) 323238405Sjkim# define NIST_INT64 long 324238405Sjkim# else 325238405Sjkim# define NIST_INT64 long long 326238405Sjkim# endif 327238405Sjkim# endif 328160814Ssimon#else 329160814Ssimon#define bn_cp_64(to, n, from, m) \ 330160814Ssimon { \ 331160814Ssimon bn_cp_32(to, (n)*2, from, (m)*2); \ 332160814Ssimon bn_cp_32(to, (n)*2+1, from, (m)*2+1); \ 333160814Ssimon } 334160814Ssimon#define bn_64_set_0(to, n) \ 335160814Ssimon { \ 336160814Ssimon bn_32_set_0(to, (n)*2); \ 337160814Ssimon bn_32_set_0(to, (n)*2+1); \ 338160814Ssimon } 339194206Ssimon#define bn_cp_32(to, n, from, m) (to)[n] = (m>=0)?((from)[m]):0; 340160814Ssimon#define bn_32_set_0(to, n) (to)[n] = (BN_ULONG)0; 341238405Sjkim# if defined(_WIN32) && !defined(__GNUC__) 342238405Sjkim# define NIST_INT64 __int64 343238405Sjkim# elif defined(BN_LLONG) 344238405Sjkim# define NIST_INT64 long long 345238405Sjkim# endif 346160814Ssimon#endif /* BN_BITS2 != 64 */ 347160814Ssimon 348160814Ssimon#define nist_set_192(to, from, a1, a2, a3) \ 349160814Ssimon { \ 350194206Ssimon bn_cp_64(to, 0, from, (a3) - 3) \ 351160814Ssimon bn_cp_64(to, 1, from, (a2) - 3) \ 352194206Ssimon bn_cp_64(to, 2, from, (a1) - 3) \ 353160814Ssimon } 354160814Ssimon 355160814Ssimonint BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, 356160814Ssimon BN_CTX *ctx) 357160814Ssimon { 358160814Ssimon int top = a->top, i; 359194206Ssimon int carry; 360160814Ssimon register BN_ULONG *r_d, *a_d = a->d; 361238405Sjkim union { 362238405Sjkim BN_ULONG bn[BN_NIST_192_TOP]; 363238405Sjkim unsigned int ui[BN_NIST_192_TOP*sizeof(BN_ULONG)/sizeof(unsigned int)]; 364238405Sjkim } buf; 365238405Sjkim BN_ULONG c_d[BN_NIST_192_TOP], 366194206Ssimon *res; 367238405Sjkim PTR_SIZE_INT mask; 368194206Ssimon static const BIGNUM _bignum_nist_p_192_sqr = { 369194206Ssimon (BN_ULONG *)_nist_p_192_sqr, 370194206Ssimon sizeof(_nist_p_192_sqr)/sizeof(_nist_p_192_sqr[0]), 371194206Ssimon sizeof(_nist_p_192_sqr)/sizeof(_nist_p_192_sqr[0]), 372194206Ssimon 0,BN_FLG_STATIC_DATA }; 373160814Ssimon 374194206Ssimon field = &_bignum_nist_p_192; /* just to make sure */ 375194206Ssimon 376194206Ssimon if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_192_sqr)>=0) 377194206Ssimon return BN_nnmod(r, a, field, ctx); 378194206Ssimon 379160814Ssimon i = BN_ucmp(field, a); 380160814Ssimon if (i == 0) 381160814Ssimon { 382160814Ssimon BN_zero(r); 383160814Ssimon return 1; 384160814Ssimon } 385160814Ssimon else if (i > 0) 386160814Ssimon return (r == a) ? 1 : (BN_copy(r ,a) != NULL); 387160814Ssimon 388160814Ssimon if (r != a) 389160814Ssimon { 390160814Ssimon if (!bn_wexpand(r, BN_NIST_192_TOP)) 391160814Ssimon return 0; 392160814Ssimon r_d = r->d; 393160814Ssimon nist_cp_bn(r_d, a_d, BN_NIST_192_TOP); 394160814Ssimon } 395160814Ssimon else 396160814Ssimon r_d = a_d; 397160814Ssimon 398238405Sjkim nist_cp_bn_0(buf.bn, a_d + BN_NIST_192_TOP, top - BN_NIST_192_TOP, BN_NIST_192_TOP); 399160814Ssimon 400238405Sjkim#if defined(NIST_INT64) 401238405Sjkim { 402238405Sjkim NIST_INT64 acc; /* accumulator */ 403238405Sjkim unsigned int *rp=(unsigned int *)r_d; 404238405Sjkim const unsigned int *bp=(const unsigned int *)buf.ui; 405238405Sjkim 406238405Sjkim acc = rp[0]; acc += bp[3*2-6]; 407238405Sjkim acc += bp[5*2-6]; rp[0] = (unsigned int)acc; acc >>= 32; 408238405Sjkim 409238405Sjkim acc += rp[1]; acc += bp[3*2-5]; 410238405Sjkim acc += bp[5*2-5]; rp[1] = (unsigned int)acc; acc >>= 32; 411238405Sjkim 412238405Sjkim acc += rp[2]; acc += bp[3*2-6]; 413238405Sjkim acc += bp[4*2-6]; 414238405Sjkim acc += bp[5*2-6]; rp[2] = (unsigned int)acc; acc >>= 32; 415238405Sjkim 416238405Sjkim acc += rp[3]; acc += bp[3*2-5]; 417238405Sjkim acc += bp[4*2-5]; 418238405Sjkim acc += bp[5*2-5]; rp[3] = (unsigned int)acc; acc >>= 32; 419238405Sjkim 420238405Sjkim acc += rp[4]; acc += bp[4*2-6]; 421238405Sjkim acc += bp[5*2-6]; rp[4] = (unsigned int)acc; acc >>= 32; 422238405Sjkim 423238405Sjkim acc += rp[5]; acc += bp[4*2-5]; 424238405Sjkim acc += bp[5*2-5]; rp[5] = (unsigned int)acc; 425238405Sjkim 426238405Sjkim carry = (int)(acc>>32); 427238405Sjkim } 428238405Sjkim#else 429238405Sjkim { 430238405Sjkim BN_ULONG t_d[BN_NIST_192_TOP]; 431238405Sjkim 432238405Sjkim nist_set_192(t_d, buf.bn, 0, 3, 3); 433194206Ssimon carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP); 434238405Sjkim nist_set_192(t_d, buf.bn, 4, 4, 0); 435194206Ssimon carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP); 436238405Sjkim nist_set_192(t_d, buf.bn, 5, 5, 5) 437194206Ssimon carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP); 438238405Sjkim } 439238405Sjkim#endif 440194206Ssimon if (carry > 0) 441194206Ssimon carry = (int)bn_sub_words(r_d,r_d,_nist_p_192[carry-1],BN_NIST_192_TOP); 442194206Ssimon else 443194206Ssimon carry = 1; 444160814Ssimon 445194206Ssimon /* 446194206Ssimon * we need 'if (carry==0 || result>=modulus) result-=modulus;' 447194206Ssimon * as comparison implies subtraction, we can write 448194206Ssimon * 'tmp=result-modulus; if (!carry || !borrow) result=tmp;' 449194206Ssimon * this is what happens below, but without explicit if:-) a. 450194206Ssimon */ 451238405Sjkim mask = 0-(PTR_SIZE_INT)bn_sub_words(c_d,r_d,_nist_p_192[0],BN_NIST_192_TOP); 452238405Sjkim mask &= 0-(PTR_SIZE_INT)carry; 453279264Sdelphij res = c_d; 454238405Sjkim res = (BN_ULONG *) 455279264Sdelphij (((PTR_SIZE_INT)res&~mask) | ((PTR_SIZE_INT)r_d&mask)); 456194206Ssimon nist_cp_bn(r_d, res, BN_NIST_192_TOP); 457160814Ssimon r->top = BN_NIST_192_TOP; 458160814Ssimon bn_correct_top(r); 459160814Ssimon 460160814Ssimon return 1; 461160814Ssimon } 462160814Ssimon 463194206Ssimontypedef BN_ULONG (*bn_addsub_f)(BN_ULONG *,const BN_ULONG *,const BN_ULONG *,int); 464194206Ssimon 465160814Ssimon#define nist_set_224(to, from, a1, a2, a3, a4, a5, a6, a7) \ 466160814Ssimon { \ 467194206Ssimon bn_cp_32(to, 0, from, (a7) - 7) \ 468194206Ssimon bn_cp_32(to, 1, from, (a6) - 7) \ 469194206Ssimon bn_cp_32(to, 2, from, (a5) - 7) \ 470194206Ssimon bn_cp_32(to, 3, from, (a4) - 7) \ 471194206Ssimon bn_cp_32(to, 4, from, (a3) - 7) \ 472194206Ssimon bn_cp_32(to, 5, from, (a2) - 7) \ 473194206Ssimon bn_cp_32(to, 6, from, (a1) - 7) \ 474160814Ssimon } 475160814Ssimon 476160814Ssimonint BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, 477160814Ssimon BN_CTX *ctx) 478160814Ssimon { 479160814Ssimon int top = a->top, i; 480194206Ssimon int carry; 481160814Ssimon BN_ULONG *r_d, *a_d = a->d; 482279264Sdelphij union { 483279264Sdelphij BN_ULONG bn[BN_NIST_224_TOP]; 484279264Sdelphij unsigned int ui[BN_NIST_224_TOP*sizeof(BN_ULONG)/sizeof(unsigned int)]; 485279264Sdelphij } buf; 486279264Sdelphij BN_ULONG c_d[BN_NIST_224_TOP], 487194206Ssimon *res; 488238405Sjkim PTR_SIZE_INT mask; 489238405Sjkim union { bn_addsub_f f; PTR_SIZE_INT p; } u; 490194206Ssimon static const BIGNUM _bignum_nist_p_224_sqr = { 491194206Ssimon (BN_ULONG *)_nist_p_224_sqr, 492194206Ssimon sizeof(_nist_p_224_sqr)/sizeof(_nist_p_224_sqr[0]), 493194206Ssimon sizeof(_nist_p_224_sqr)/sizeof(_nist_p_224_sqr[0]), 494194206Ssimon 0,BN_FLG_STATIC_DATA }; 495160814Ssimon 496194206Ssimon 497194206Ssimon field = &_bignum_nist_p_224; /* just to make sure */ 498194206Ssimon 499194206Ssimon if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_224_sqr)>=0) 500194206Ssimon return BN_nnmod(r, a, field, ctx); 501194206Ssimon 502160814Ssimon i = BN_ucmp(field, a); 503160814Ssimon if (i == 0) 504160814Ssimon { 505160814Ssimon BN_zero(r); 506160814Ssimon return 1; 507160814Ssimon } 508160814Ssimon else if (i > 0) 509160814Ssimon return (r == a)? 1 : (BN_copy(r ,a) != NULL); 510160814Ssimon 511160814Ssimon if (r != a) 512160814Ssimon { 513160814Ssimon if (!bn_wexpand(r, BN_NIST_224_TOP)) 514160814Ssimon return 0; 515160814Ssimon r_d = r->d; 516160814Ssimon nist_cp_bn(r_d, a_d, BN_NIST_224_TOP); 517160814Ssimon } 518160814Ssimon else 519160814Ssimon r_d = a_d; 520160814Ssimon 521194206Ssimon#if BN_BITS2==64 522194206Ssimon /* copy upper 256 bits of 448 bit number ... */ 523238405Sjkim nist_cp_bn_0(c_d, a_d + (BN_NIST_224_TOP-1), top - (BN_NIST_224_TOP-1), BN_NIST_224_TOP); 524194206Ssimon /* ... and right shift by 32 to obtain upper 224 bits */ 525279264Sdelphij nist_set_224(buf.bn, c_d, 14, 13, 12, 11, 10, 9, 8); 526194206Ssimon /* truncate lower part to 224 bits too */ 527194206Ssimon r_d[BN_NIST_224_TOP-1] &= BN_MASK2l; 528194206Ssimon#else 529279264Sdelphij nist_cp_bn_0(buf.bn, a_d + BN_NIST_224_TOP, top - BN_NIST_224_TOP, BN_NIST_224_TOP); 530194206Ssimon#endif 531238405Sjkim 532238405Sjkim#if defined(NIST_INT64) && BN_BITS2!=64 533238405Sjkim { 534238405Sjkim NIST_INT64 acc; /* accumulator */ 535238405Sjkim unsigned int *rp=(unsigned int *)r_d; 536279264Sdelphij const unsigned int *bp=(const unsigned int *)buf.ui; 537238405Sjkim 538238405Sjkim acc = rp[0]; acc -= bp[7-7]; 539238405Sjkim acc -= bp[11-7]; rp[0] = (unsigned int)acc; acc >>= 32; 540238405Sjkim 541238405Sjkim acc += rp[1]; acc -= bp[8-7]; 542238405Sjkim acc -= bp[12-7]; rp[1] = (unsigned int)acc; acc >>= 32; 543238405Sjkim 544238405Sjkim acc += rp[2]; acc -= bp[9-7]; 545238405Sjkim acc -= bp[13-7]; rp[2] = (unsigned int)acc; acc >>= 32; 546238405Sjkim 547238405Sjkim acc += rp[3]; acc += bp[7-7]; 548238405Sjkim acc += bp[11-7]; 549238405Sjkim acc -= bp[10-7]; rp[3] = (unsigned int)acc; acc>>= 32; 550238405Sjkim 551238405Sjkim acc += rp[4]; acc += bp[8-7]; 552238405Sjkim acc += bp[12-7]; 553238405Sjkim acc -= bp[11-7]; rp[4] = (unsigned int)acc; acc >>= 32; 554238405Sjkim 555238405Sjkim acc += rp[5]; acc += bp[9-7]; 556238405Sjkim acc += bp[13-7]; 557238405Sjkim acc -= bp[12-7]; rp[5] = (unsigned int)acc; acc >>= 32; 558238405Sjkim 559238405Sjkim acc += rp[6]; acc += bp[10-7]; 560238405Sjkim acc -= bp[13-7]; rp[6] = (unsigned int)acc; 561238405Sjkim 562238405Sjkim carry = (int)(acc>>32); 563238405Sjkim# if BN_BITS2==64 564238405Sjkim rp[7] = carry; 565238405Sjkim# endif 566238405Sjkim } 567238405Sjkim#else 568238405Sjkim { 569238405Sjkim BN_ULONG t_d[BN_NIST_224_TOP]; 570238405Sjkim 571279264Sdelphij nist_set_224(t_d, buf.bn, 10, 9, 8, 7, 0, 0, 0); 572194206Ssimon carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP); 573279264Sdelphij nist_set_224(t_d, buf.bn, 0, 13, 12, 11, 0, 0, 0); 574194206Ssimon carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP); 575279264Sdelphij nist_set_224(t_d, buf.bn, 13, 12, 11, 10, 9, 8, 7); 576194206Ssimon carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP); 577279264Sdelphij nist_set_224(t_d, buf.bn, 0, 0, 0, 0, 13, 12, 11); 578194206Ssimon carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP); 579160814Ssimon 580194206Ssimon#if BN_BITS2==64 581194206Ssimon carry = (int)(r_d[BN_NIST_224_TOP-1]>>32); 582194206Ssimon#endif 583238405Sjkim } 584238405Sjkim#endif 585194206Ssimon u.f = bn_sub_words; 586160814Ssimon if (carry > 0) 587194206Ssimon { 588194206Ssimon carry = (int)bn_sub_words(r_d,r_d,_nist_p_224[carry-1],BN_NIST_224_TOP); 589194206Ssimon#if BN_BITS2==64 590194206Ssimon carry=(int)(~(r_d[BN_NIST_224_TOP-1]>>32))&1; 591194206Ssimon#endif 592194206Ssimon } 593160814Ssimon else if (carry < 0) 594194206Ssimon { 595194206Ssimon /* it's a bit more comlicated logic in this case. 596194206Ssimon * if bn_add_words yields no carry, then result 597194206Ssimon * has to be adjusted by unconditionally *adding* 598194206Ssimon * the modulus. but if it does, then result has 599194206Ssimon * to be compared to the modulus and conditionally 600194206Ssimon * adjusted by *subtracting* the latter. */ 601194206Ssimon carry = (int)bn_add_words(r_d,r_d,_nist_p_224[-carry-1],BN_NIST_224_TOP); 602238405Sjkim mask = 0-(PTR_SIZE_INT)carry; 603238405Sjkim u.p = ((PTR_SIZE_INT)bn_sub_words&mask) | 604238405Sjkim ((PTR_SIZE_INT)bn_add_words&~mask); 605194206Ssimon } 606194206Ssimon else 607194206Ssimon carry = 1; 608160814Ssimon 609194206Ssimon /* otherwise it's effectively same as in BN_nist_mod_192... */ 610238405Sjkim mask = 0-(PTR_SIZE_INT)(*u.f)(c_d,r_d,_nist_p_224[0],BN_NIST_224_TOP); 611238405Sjkim mask &= 0-(PTR_SIZE_INT)carry; 612279264Sdelphij res = c_d; 613279264Sdelphij res = (BN_ULONG *)(((PTR_SIZE_INT)res&~mask) | 614238405Sjkim ((PTR_SIZE_INT)r_d&mask)); 615194206Ssimon nist_cp_bn(r_d, res, BN_NIST_224_TOP); 616160814Ssimon r->top = BN_NIST_224_TOP; 617160814Ssimon bn_correct_top(r); 618194206Ssimon 619160814Ssimon return 1; 620160814Ssimon } 621160814Ssimon 622160814Ssimon#define nist_set_256(to, from, a1, a2, a3, a4, a5, a6, a7, a8) \ 623160814Ssimon { \ 624194206Ssimon bn_cp_32(to, 0, from, (a8) - 8) \ 625194206Ssimon bn_cp_32(to, 1, from, (a7) - 8) \ 626194206Ssimon bn_cp_32(to, 2, from, (a6) - 8) \ 627194206Ssimon bn_cp_32(to, 3, from, (a5) - 8) \ 628194206Ssimon bn_cp_32(to, 4, from, (a4) - 8) \ 629194206Ssimon bn_cp_32(to, 5, from, (a3) - 8) \ 630194206Ssimon bn_cp_32(to, 6, from, (a2) - 8) \ 631194206Ssimon bn_cp_32(to, 7, from, (a1) - 8) \ 632160814Ssimon } 633160814Ssimon 634160814Ssimonint BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, 635160814Ssimon BN_CTX *ctx) 636160814Ssimon { 637160814Ssimon int i, top = a->top; 638160814Ssimon int carry = 0; 639160814Ssimon register BN_ULONG *a_d = a->d, *r_d; 640238405Sjkim union { 641238405Sjkim BN_ULONG bn[BN_NIST_256_TOP]; 642238405Sjkim unsigned int ui[BN_NIST_256_TOP*sizeof(BN_ULONG)/sizeof(unsigned int)]; 643238405Sjkim } buf; 644238405Sjkim BN_ULONG c_d[BN_NIST_256_TOP], 645194206Ssimon *res; 646238405Sjkim PTR_SIZE_INT mask; 647238405Sjkim union { bn_addsub_f f; PTR_SIZE_INT p; } u; 648194206Ssimon static const BIGNUM _bignum_nist_p_256_sqr = { 649194206Ssimon (BN_ULONG *)_nist_p_256_sqr, 650194206Ssimon sizeof(_nist_p_256_sqr)/sizeof(_nist_p_256_sqr[0]), 651194206Ssimon sizeof(_nist_p_256_sqr)/sizeof(_nist_p_256_sqr[0]), 652194206Ssimon 0,BN_FLG_STATIC_DATA }; 653160814Ssimon 654194206Ssimon field = &_bignum_nist_p_256; /* just to make sure */ 655194206Ssimon 656194206Ssimon if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_256_sqr)>=0) 657194206Ssimon return BN_nnmod(r, a, field, ctx); 658194206Ssimon 659160814Ssimon i = BN_ucmp(field, a); 660160814Ssimon if (i == 0) 661160814Ssimon { 662160814Ssimon BN_zero(r); 663160814Ssimon return 1; 664160814Ssimon } 665160814Ssimon else if (i > 0) 666160814Ssimon return (r == a)? 1 : (BN_copy(r ,a) != NULL); 667160814Ssimon 668160814Ssimon if (r != a) 669160814Ssimon { 670160814Ssimon if (!bn_wexpand(r, BN_NIST_256_TOP)) 671160814Ssimon return 0; 672160814Ssimon r_d = r->d; 673160814Ssimon nist_cp_bn(r_d, a_d, BN_NIST_256_TOP); 674160814Ssimon } 675160814Ssimon else 676160814Ssimon r_d = a_d; 677160814Ssimon 678238405Sjkim nist_cp_bn_0(buf.bn, a_d + BN_NIST_256_TOP, top - BN_NIST_256_TOP, BN_NIST_256_TOP); 679160814Ssimon 680238405Sjkim#if defined(NIST_INT64) 681238405Sjkim { 682238405Sjkim NIST_INT64 acc; /* accumulator */ 683238405Sjkim unsigned int *rp=(unsigned int *)r_d; 684238405Sjkim const unsigned int *bp=(const unsigned int *)buf.ui; 685238405Sjkim 686238405Sjkim acc = rp[0]; acc += bp[8-8]; 687238405Sjkim acc += bp[9-8]; 688238405Sjkim acc -= bp[11-8]; 689238405Sjkim acc -= bp[12-8]; 690238405Sjkim acc -= bp[13-8]; 691238405Sjkim acc -= bp[14-8]; rp[0] = (unsigned int)acc; acc >>= 32; 692238405Sjkim 693238405Sjkim acc += rp[1]; acc += bp[9-8]; 694238405Sjkim acc += bp[10-8]; 695238405Sjkim acc -= bp[12-8]; 696238405Sjkim acc -= bp[13-8]; 697238405Sjkim acc -= bp[14-8]; 698238405Sjkim acc -= bp[15-8]; rp[1] = (unsigned int)acc; acc >>= 32; 699238405Sjkim 700238405Sjkim acc += rp[2]; acc += bp[10-8]; 701238405Sjkim acc += bp[11-8]; 702238405Sjkim acc -= bp[13-8]; 703238405Sjkim acc -= bp[14-8]; 704238405Sjkim acc -= bp[15-8]; rp[2] = (unsigned int)acc; acc >>= 32; 705238405Sjkim 706238405Sjkim acc += rp[3]; acc += bp[11-8]; 707238405Sjkim acc += bp[11-8]; 708238405Sjkim acc += bp[12-8]; 709238405Sjkim acc += bp[12-8]; 710238405Sjkim acc += bp[13-8]; 711238405Sjkim acc -= bp[15-8]; 712238405Sjkim acc -= bp[8-8]; 713238405Sjkim acc -= bp[9-8]; rp[3] = (unsigned int)acc; acc >>= 32; 714238405Sjkim 715238405Sjkim acc += rp[4]; acc += bp[12-8]; 716238405Sjkim acc += bp[12-8]; 717238405Sjkim acc += bp[13-8]; 718238405Sjkim acc += bp[13-8]; 719238405Sjkim acc += bp[14-8]; 720238405Sjkim acc -= bp[9-8]; 721238405Sjkim acc -= bp[10-8]; rp[4] = (unsigned int)acc; acc >>= 32; 722238405Sjkim 723238405Sjkim acc += rp[5]; acc += bp[13-8]; 724238405Sjkim acc += bp[13-8]; 725238405Sjkim acc += bp[14-8]; 726238405Sjkim acc += bp[14-8]; 727238405Sjkim acc += bp[15-8]; 728238405Sjkim acc -= bp[10-8]; 729238405Sjkim acc -= bp[11-8]; rp[5] = (unsigned int)acc; acc >>= 32; 730238405Sjkim 731238405Sjkim acc += rp[6]; acc += bp[14-8]; 732238405Sjkim acc += bp[14-8]; 733238405Sjkim acc += bp[15-8]; 734238405Sjkim acc += bp[15-8]; 735238405Sjkim acc += bp[14-8]; 736238405Sjkim acc += bp[13-8]; 737238405Sjkim acc -= bp[8-8]; 738238405Sjkim acc -= bp[9-8]; rp[6] = (unsigned int)acc; acc >>= 32; 739238405Sjkim 740238405Sjkim acc += rp[7]; acc += bp[15-8]; 741238405Sjkim acc += bp[15-8]; 742238405Sjkim acc += bp[15-8]; 743238405Sjkim acc += bp[8 -8]; 744238405Sjkim acc -= bp[10-8]; 745238405Sjkim acc -= bp[11-8]; 746238405Sjkim acc -= bp[12-8]; 747238405Sjkim acc -= bp[13-8]; rp[7] = (unsigned int)acc; 748238405Sjkim 749238405Sjkim carry = (int)(acc>>32); 750238405Sjkim } 751238405Sjkim#else 752238405Sjkim { 753238405Sjkim BN_ULONG t_d[BN_NIST_256_TOP]; 754238405Sjkim 755160814Ssimon /*S1*/ 756238405Sjkim nist_set_256(t_d, buf.bn, 15, 14, 13, 12, 11, 0, 0, 0); 757160814Ssimon /*S2*/ 758238405Sjkim nist_set_256(c_d, buf.bn, 0, 15, 14, 13, 12, 0, 0, 0); 759194206Ssimon carry = (int)bn_add_words(t_d, t_d, c_d, BN_NIST_256_TOP); 760160814Ssimon /* left shift */ 761160814Ssimon { 762160814Ssimon register BN_ULONG *ap,t,c; 763160814Ssimon ap = t_d; 764160814Ssimon c=0; 765160814Ssimon for (i = BN_NIST_256_TOP; i != 0; --i) 766160814Ssimon { 767160814Ssimon t= *ap; 768160814Ssimon *(ap++)=((t<<1)|c)&BN_MASK2; 769160814Ssimon c=(t & BN_TBIT)?1:0; 770160814Ssimon } 771194206Ssimon carry <<= 1; 772194206Ssimon carry |= c; 773160814Ssimon } 774194206Ssimon carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP); 775160814Ssimon /*S3*/ 776238405Sjkim nist_set_256(t_d, buf.bn, 15, 14, 0, 0, 0, 10, 9, 8); 777194206Ssimon carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP); 778160814Ssimon /*S4*/ 779238405Sjkim nist_set_256(t_d, buf.bn, 8, 13, 15, 14, 13, 11, 10, 9); 780194206Ssimon carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP); 781160814Ssimon /*D1*/ 782238405Sjkim nist_set_256(t_d, buf.bn, 10, 8, 0, 0, 0, 13, 12, 11); 783194206Ssimon carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP); 784160814Ssimon /*D2*/ 785238405Sjkim nist_set_256(t_d, buf.bn, 11, 9, 0, 0, 15, 14, 13, 12); 786194206Ssimon carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP); 787160814Ssimon /*D3*/ 788238405Sjkim nist_set_256(t_d, buf.bn, 12, 0, 10, 9, 8, 15, 14, 13); 789194206Ssimon carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP); 790160814Ssimon /*D4*/ 791238405Sjkim nist_set_256(t_d, buf.bn, 13, 0, 11, 10, 9, 0, 15, 14); 792194206Ssimon carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP); 793194206Ssimon 794238405Sjkim } 795238405Sjkim#endif 796194206Ssimon /* see BN_nist_mod_224 for explanation */ 797194206Ssimon u.f = bn_sub_words; 798194206Ssimon if (carry > 0) 799194206Ssimon carry = (int)bn_sub_words(r_d,r_d,_nist_p_256[carry-1],BN_NIST_256_TOP); 800194206Ssimon else if (carry < 0) 801160814Ssimon { 802194206Ssimon carry = (int)bn_add_words(r_d,r_d,_nist_p_256[-carry-1],BN_NIST_256_TOP); 803238405Sjkim mask = 0-(PTR_SIZE_INT)carry; 804238405Sjkim u.p = ((PTR_SIZE_INT)bn_sub_words&mask) | 805238405Sjkim ((PTR_SIZE_INT)bn_add_words&~mask); 806160814Ssimon } 807194206Ssimon else 808194206Ssimon carry = 1; 809160814Ssimon 810238405Sjkim mask = 0-(PTR_SIZE_INT)(*u.f)(c_d,r_d,_nist_p_256[0],BN_NIST_256_TOP); 811238405Sjkim mask &= 0-(PTR_SIZE_INT)carry; 812279264Sdelphij res = c_d; 813279264Sdelphij res = (BN_ULONG *)(((PTR_SIZE_INT)res&~mask) | 814238405Sjkim ((PTR_SIZE_INT)r_d&mask)); 815194206Ssimon nist_cp_bn(r_d, res, BN_NIST_256_TOP); 816160814Ssimon r->top = BN_NIST_256_TOP; 817160814Ssimon bn_correct_top(r); 818194206Ssimon 819160814Ssimon return 1; 820160814Ssimon } 821160814Ssimon 822160814Ssimon#define nist_set_384(to,from,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) \ 823160814Ssimon { \ 824194206Ssimon bn_cp_32(to, 0, from, (a12) - 12) \ 825194206Ssimon bn_cp_32(to, 1, from, (a11) - 12) \ 826194206Ssimon bn_cp_32(to, 2, from, (a10) - 12) \ 827194206Ssimon bn_cp_32(to, 3, from, (a9) - 12) \ 828194206Ssimon bn_cp_32(to, 4, from, (a8) - 12) \ 829194206Ssimon bn_cp_32(to, 5, from, (a7) - 12) \ 830194206Ssimon bn_cp_32(to, 6, from, (a6) - 12) \ 831194206Ssimon bn_cp_32(to, 7, from, (a5) - 12) \ 832194206Ssimon bn_cp_32(to, 8, from, (a4) - 12) \ 833194206Ssimon bn_cp_32(to, 9, from, (a3) - 12) \ 834194206Ssimon bn_cp_32(to, 10, from, (a2) - 12) \ 835194206Ssimon bn_cp_32(to, 11, from, (a1) - 12) \ 836160814Ssimon } 837160814Ssimon 838160814Ssimonint BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, 839160814Ssimon BN_CTX *ctx) 840160814Ssimon { 841160814Ssimon int i, top = a->top; 842160814Ssimon int carry = 0; 843160814Ssimon register BN_ULONG *r_d, *a_d = a->d; 844238405Sjkim union { 845238405Sjkim BN_ULONG bn[BN_NIST_384_TOP]; 846238405Sjkim unsigned int ui[BN_NIST_384_TOP*sizeof(BN_ULONG)/sizeof(unsigned int)]; 847238405Sjkim } buf; 848238405Sjkim BN_ULONG c_d[BN_NIST_384_TOP], 849194206Ssimon *res; 850238405Sjkim PTR_SIZE_INT mask; 851238405Sjkim union { bn_addsub_f f; PTR_SIZE_INT p; } u; 852194206Ssimon static const BIGNUM _bignum_nist_p_384_sqr = { 853194206Ssimon (BN_ULONG *)_nist_p_384_sqr, 854194206Ssimon sizeof(_nist_p_384_sqr)/sizeof(_nist_p_384_sqr[0]), 855194206Ssimon sizeof(_nist_p_384_sqr)/sizeof(_nist_p_384_sqr[0]), 856194206Ssimon 0,BN_FLG_STATIC_DATA }; 857160814Ssimon 858160814Ssimon 859194206Ssimon field = &_bignum_nist_p_384; /* just to make sure */ 860160814Ssimon 861194206Ssimon if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_384_sqr)>=0) 862194206Ssimon return BN_nnmod(r, a, field, ctx); 863194206Ssimon 864160814Ssimon i = BN_ucmp(field, a); 865160814Ssimon if (i == 0) 866160814Ssimon { 867160814Ssimon BN_zero(r); 868160814Ssimon return 1; 869160814Ssimon } 870160814Ssimon else if (i > 0) 871160814Ssimon return (r == a)? 1 : (BN_copy(r ,a) != NULL); 872160814Ssimon 873160814Ssimon if (r != a) 874160814Ssimon { 875160814Ssimon if (!bn_wexpand(r, BN_NIST_384_TOP)) 876160814Ssimon return 0; 877160814Ssimon r_d = r->d; 878160814Ssimon nist_cp_bn(r_d, a_d, BN_NIST_384_TOP); 879160814Ssimon } 880160814Ssimon else 881160814Ssimon r_d = a_d; 882160814Ssimon 883238405Sjkim nist_cp_bn_0(buf.bn, a_d + BN_NIST_384_TOP, top - BN_NIST_384_TOP, BN_NIST_384_TOP); 884160814Ssimon 885238405Sjkim#if defined(NIST_INT64) 886238405Sjkim { 887238405Sjkim NIST_INT64 acc; /* accumulator */ 888238405Sjkim unsigned int *rp=(unsigned int *)r_d; 889238405Sjkim const unsigned int *bp=(const unsigned int *)buf.ui; 890238405Sjkim 891238405Sjkim acc = rp[0]; acc += bp[12-12]; 892238405Sjkim acc += bp[21-12]; 893238405Sjkim acc += bp[20-12]; 894238405Sjkim acc -= bp[23-12]; rp[0] = (unsigned int)acc; acc >>= 32; 895238405Sjkim 896238405Sjkim acc += rp[1]; acc += bp[13-12]; 897238405Sjkim acc += bp[22-12]; 898238405Sjkim acc += bp[23-12]; 899238405Sjkim acc -= bp[12-12]; 900238405Sjkim acc -= bp[20-12]; rp[1] = (unsigned int)acc; acc >>= 32; 901238405Sjkim 902238405Sjkim acc += rp[2]; acc += bp[14-12]; 903238405Sjkim acc += bp[23-12]; 904238405Sjkim acc -= bp[13-12]; 905238405Sjkim acc -= bp[21-12]; rp[2] = (unsigned int)acc; acc >>= 32; 906238405Sjkim 907238405Sjkim acc += rp[3]; acc += bp[15-12]; 908238405Sjkim acc += bp[12-12]; 909238405Sjkim acc += bp[20-12]; 910238405Sjkim acc += bp[21-12]; 911238405Sjkim acc -= bp[14-12]; 912238405Sjkim acc -= bp[22-12]; 913238405Sjkim acc -= bp[23-12]; rp[3] = (unsigned int)acc; acc >>= 32; 914238405Sjkim 915238405Sjkim acc += rp[4]; acc += bp[21-12]; 916238405Sjkim acc += bp[21-12]; 917238405Sjkim acc += bp[16-12]; 918238405Sjkim acc += bp[13-12]; 919238405Sjkim acc += bp[12-12]; 920238405Sjkim acc += bp[20-12]; 921238405Sjkim acc += bp[22-12]; 922238405Sjkim acc -= bp[15-12]; 923238405Sjkim acc -= bp[23-12]; 924238405Sjkim acc -= bp[23-12]; rp[4] = (unsigned int)acc; acc >>= 32; 925238405Sjkim 926238405Sjkim acc += rp[5]; acc += bp[22-12]; 927238405Sjkim acc += bp[22-12]; 928238405Sjkim acc += bp[17-12]; 929238405Sjkim acc += bp[14-12]; 930238405Sjkim acc += bp[13-12]; 931238405Sjkim acc += bp[21-12]; 932238405Sjkim acc += bp[23-12]; 933238405Sjkim acc -= bp[16-12]; rp[5] = (unsigned int)acc; acc >>= 32; 934238405Sjkim 935238405Sjkim acc += rp[6]; acc += bp[23-12]; 936238405Sjkim acc += bp[23-12]; 937238405Sjkim acc += bp[18-12]; 938238405Sjkim acc += bp[15-12]; 939238405Sjkim acc += bp[14-12]; 940238405Sjkim acc += bp[22-12]; 941238405Sjkim acc -= bp[17-12]; rp[6] = (unsigned int)acc; acc >>= 32; 942238405Sjkim 943238405Sjkim acc += rp[7]; acc += bp[19-12]; 944238405Sjkim acc += bp[16-12]; 945238405Sjkim acc += bp[15-12]; 946238405Sjkim acc += bp[23-12]; 947238405Sjkim acc -= bp[18-12]; rp[7] = (unsigned int)acc; acc >>= 32; 948238405Sjkim 949238405Sjkim acc += rp[8]; acc += bp[20-12]; 950238405Sjkim acc += bp[17-12]; 951238405Sjkim acc += bp[16-12]; 952238405Sjkim acc -= bp[19-12]; rp[8] = (unsigned int)acc; acc >>= 32; 953238405Sjkim 954238405Sjkim acc += rp[9]; acc += bp[21-12]; 955238405Sjkim acc += bp[18-12]; 956238405Sjkim acc += bp[17-12]; 957238405Sjkim acc -= bp[20-12]; rp[9] = (unsigned int)acc; acc >>= 32; 958238405Sjkim 959238405Sjkim acc += rp[10]; acc += bp[22-12]; 960238405Sjkim acc += bp[19-12]; 961238405Sjkim acc += bp[18-12]; 962238405Sjkim acc -= bp[21-12]; rp[10] = (unsigned int)acc; acc >>= 32; 963238405Sjkim 964238405Sjkim acc += rp[11]; acc += bp[23-12]; 965238405Sjkim acc += bp[20-12]; 966238405Sjkim acc += bp[19-12]; 967238405Sjkim acc -= bp[22-12]; rp[11] = (unsigned int)acc; 968238405Sjkim 969238405Sjkim carry = (int)(acc>>32); 970238405Sjkim } 971238405Sjkim#else 972238405Sjkim { 973238405Sjkim BN_ULONG t_d[BN_NIST_384_TOP]; 974238405Sjkim 975160814Ssimon /*S1*/ 976238405Sjkim nist_set_256(t_d, buf.bn, 0, 0, 0, 0, 0, 23-4, 22-4, 21-4); 977160814Ssimon /* left shift */ 978160814Ssimon { 979160814Ssimon register BN_ULONG *ap,t,c; 980160814Ssimon ap = t_d; 981160814Ssimon c=0; 982194206Ssimon for (i = 3; i != 0; --i) 983160814Ssimon { 984160814Ssimon t= *ap; 985160814Ssimon *(ap++)=((t<<1)|c)&BN_MASK2; 986160814Ssimon c=(t & BN_TBIT)?1:0; 987160814Ssimon } 988194206Ssimon *ap=c; 989160814Ssimon } 990194206Ssimon carry = (int)bn_add_words(r_d+(128/BN_BITS2), r_d+(128/BN_BITS2), 991194206Ssimon t_d, BN_NIST_256_TOP); 992160814Ssimon /*S2 */ 993238405Sjkim carry += (int)bn_add_words(r_d, r_d, buf.bn, BN_NIST_384_TOP); 994160814Ssimon /*S3*/ 995238405Sjkim nist_set_384(t_d,buf.bn,20,19,18,17,16,15,14,13,12,23,22,21); 996194206Ssimon carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP); 997160814Ssimon /*S4*/ 998238405Sjkim nist_set_384(t_d,buf.bn,19,18,17,16,15,14,13,12,20,0,23,0); 999194206Ssimon carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP); 1000160814Ssimon /*S5*/ 1001238405Sjkim nist_set_384(t_d, buf.bn,0,0,0,0,23,22,21,20,0,0,0,0); 1002194206Ssimon carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP); 1003160814Ssimon /*S6*/ 1004238405Sjkim nist_set_384(t_d,buf.bn,0,0,0,0,0,0,23,22,21,0,0,20); 1005194206Ssimon carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP); 1006160814Ssimon /*D1*/ 1007238405Sjkim nist_set_384(t_d,buf.bn,22,21,20,19,18,17,16,15,14,13,12,23); 1008194206Ssimon carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP); 1009160814Ssimon /*D2*/ 1010238405Sjkim nist_set_384(t_d,buf.bn,0,0,0,0,0,0,0,23,22,21,20,0); 1011194206Ssimon carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP); 1012160814Ssimon /*D3*/ 1013238405Sjkim nist_set_384(t_d,buf.bn,0,0,0,0,0,0,0,23,23,0,0,0); 1014194206Ssimon carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP); 1015194206Ssimon 1016238405Sjkim } 1017238405Sjkim#endif 1018194206Ssimon /* see BN_nist_mod_224 for explanation */ 1019194206Ssimon u.f = bn_sub_words; 1020194206Ssimon if (carry > 0) 1021194206Ssimon carry = (int)bn_sub_words(r_d,r_d,_nist_p_384[carry-1],BN_NIST_384_TOP); 1022194206Ssimon else if (carry < 0) 1023160814Ssimon { 1024194206Ssimon carry = (int)bn_add_words(r_d,r_d,_nist_p_384[-carry-1],BN_NIST_384_TOP); 1025238405Sjkim mask = 0-(PTR_SIZE_INT)carry; 1026238405Sjkim u.p = ((PTR_SIZE_INT)bn_sub_words&mask) | 1027238405Sjkim ((PTR_SIZE_INT)bn_add_words&~mask); 1028160814Ssimon } 1029194206Ssimon else 1030194206Ssimon carry = 1; 1031160814Ssimon 1032238405Sjkim mask = 0-(PTR_SIZE_INT)(*u.f)(c_d,r_d,_nist_p_384[0],BN_NIST_384_TOP); 1033238405Sjkim mask &= 0-(PTR_SIZE_INT)carry; 1034279264Sdelphij res = c_d; 1035279264Sdelphij res = (BN_ULONG *)(((PTR_SIZE_INT)res&~mask) | 1036238405Sjkim ((PTR_SIZE_INT)r_d&mask)); 1037194206Ssimon nist_cp_bn(r_d, res, BN_NIST_384_TOP); 1038160814Ssimon r->top = BN_NIST_384_TOP; 1039160814Ssimon bn_correct_top(r); 1040194206Ssimon 1041160814Ssimon return 1; 1042160814Ssimon } 1043160814Ssimon 1044194206Ssimon#define BN_NIST_521_RSHIFT (521%BN_BITS2) 1045194206Ssimon#define BN_NIST_521_LSHIFT (BN_BITS2-BN_NIST_521_RSHIFT) 1046194206Ssimon#define BN_NIST_521_TOP_MASK ((BN_ULONG)BN_MASK2>>BN_NIST_521_LSHIFT) 1047194206Ssimon 1048160814Ssimonint BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, 1049160814Ssimon BN_CTX *ctx) 1050160814Ssimon { 1051194206Ssimon int top = a->top, i; 1052194206Ssimon BN_ULONG *r_d, *a_d = a->d, 1053194206Ssimon t_d[BN_NIST_521_TOP], 1054194206Ssimon val,tmp,*res; 1055238405Sjkim PTR_SIZE_INT mask; 1056194206Ssimon static const BIGNUM _bignum_nist_p_521_sqr = { 1057194206Ssimon (BN_ULONG *)_nist_p_521_sqr, 1058194206Ssimon sizeof(_nist_p_521_sqr)/sizeof(_nist_p_521_sqr[0]), 1059194206Ssimon sizeof(_nist_p_521_sqr)/sizeof(_nist_p_521_sqr[0]), 1060194206Ssimon 0,BN_FLG_STATIC_DATA }; 1061160814Ssimon 1062194206Ssimon field = &_bignum_nist_p_521; /* just to make sure */ 1063160814Ssimon 1064194206Ssimon if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_521_sqr)>=0) 1065194206Ssimon return BN_nnmod(r, a, field, ctx); 1066160814Ssimon 1067194206Ssimon i = BN_ucmp(field, a); 1068194206Ssimon if (i == 0) 1069194206Ssimon { 1070194206Ssimon BN_zero(r); 1071194206Ssimon return 1; 1072194206Ssimon } 1073194206Ssimon else if (i > 0) 1074194206Ssimon return (r == a)? 1 : (BN_copy(r ,a) != NULL); 1075160814Ssimon 1076194206Ssimon if (r != a) 1077194206Ssimon { 1078194206Ssimon if (!bn_wexpand(r,BN_NIST_521_TOP)) 1079194206Ssimon return 0; 1080194206Ssimon r_d = r->d; 1081194206Ssimon nist_cp_bn(r_d,a_d, BN_NIST_521_TOP); 1082194206Ssimon } 1083194206Ssimon else 1084194206Ssimon r_d = a_d; 1085160814Ssimon 1086194206Ssimon /* upper 521 bits, copy ... */ 1087194206Ssimon nist_cp_bn_0(t_d,a_d + (BN_NIST_521_TOP-1), top - (BN_NIST_521_TOP-1),BN_NIST_521_TOP); 1088194206Ssimon /* ... and right shift */ 1089194206Ssimon for (val=t_d[0],i=0; i<BN_NIST_521_TOP-1; i++) 1090160814Ssimon { 1091279264Sdelphij t_d[i] = ( val>>BN_NIST_521_RSHIFT | 1092279264Sdelphij (tmp=t_d[i+1])<<BN_NIST_521_LSHIFT ) & BN_MASK2; 1093279264Sdelphij val=tmp; 1094160814Ssimon } 1095194206Ssimon t_d[i] = val>>BN_NIST_521_RSHIFT; 1096194206Ssimon /* lower 521 bits */ 1097194206Ssimon r_d[i] &= BN_NIST_521_TOP_MASK; 1098194206Ssimon 1099194206Ssimon bn_add_words(r_d,r_d,t_d,BN_NIST_521_TOP); 1100238405Sjkim mask = 0-(PTR_SIZE_INT)bn_sub_words(t_d,r_d,_nist_p_521,BN_NIST_521_TOP); 1101279264Sdelphij res = t_d; 1102279264Sdelphij res = (BN_ULONG *)(((PTR_SIZE_INT)res&~mask) | 1103238405Sjkim ((PTR_SIZE_INT)r_d&mask)); 1104194206Ssimon nist_cp_bn(r_d,res,BN_NIST_521_TOP); 1105194206Ssimon r->top = BN_NIST_521_TOP; 1106160814Ssimon bn_correct_top(r); 1107160814Ssimon 1108194206Ssimon return 1; 1109160814Ssimon } 1110