fast reduction for NIST curves

Submitted by: Nils Larsch
This commit is contained in:
Bodo Möller 2002-10-28 13:23:24 +00:00
parent f72ed6153b
commit 5c6bf03117
12 changed files with 1134 additions and 45 deletions

View File

@ -4,6 +4,12 @@
Changes between 0.9.7 and 0.9.8 [xx XXX 2002] Changes between 0.9.7 and 0.9.8 [xx XXX 2002]
*) Implement fast modular reduction for pseudo-Mersenne primes
used in NIST curves (crypto/bn/bn_nist.c, crypto/ec/ecp_nist.c).
EC_GROUP_new_curve_GFp() will now automatically use this
if applicable.
[Nils Larsch <nla@trustcenter.de>]
*) Change the ENGINE framework to automatically load engines *) Change the ENGINE framework to automatically load engines
dynamically from specific directories unless they could be dynamically from specific directories unless they could be
found to already be built in or loaded. Move all the found to already be built in or loaded. Move all the

View File

@ -261,7 +261,7 @@ static int do_multi(int multi);
#define RSA_NUM 4 #define RSA_NUM 4
#define DSA_NUM 3 #define DSA_NUM 3
#define EC_NUM 15 #define EC_NUM 16
#define MAX_ECDH_SIZE 256 #define MAX_ECDH_SIZE 256
static const char *names[ALGOR_NUM]={ static const char *names[ALGOR_NUM]={
@ -520,20 +520,21 @@ int MAIN(int argc, char **argv)
#define R_RSA_4096 3 #define R_RSA_4096 3
#define R_EC_P160 0 #define R_EC_P160 0
#define R_EC_P224 1 #define R_EC_P192 1
#define R_EC_P256 2 #define R_EC_P224 2
#define R_EC_P384 3 #define R_EC_P256 3
#define R_EC_P521 4 #define R_EC_P384 4
#define R_EC_K163 5 #define R_EC_P521 5
#define R_EC_K233 6 #define R_EC_K163 6
#define R_EC_K283 7 #define R_EC_K233 7
#define R_EC_K409 8 #define R_EC_K283 8
#define R_EC_K571 9 #define R_EC_K409 9
#define R_EC_B163 10 #define R_EC_K571 10
#define R_EC_B233 11 #define R_EC_B163 11
#define R_EC_B283 12 #define R_EC_B233 12
#define R_EC_B409 13 #define R_EC_B283 13
#define R_EC_B571 14 #define R_EC_B409 14
#define R_EC_B571 15
#ifndef OPENSSL_NO_RSA #ifndef OPENSSL_NO_RSA
RSA *rsa_key[RSA_NUM]; RSA *rsa_key[RSA_NUM];
@ -560,6 +561,7 @@ int MAIN(int argc, char **argv)
{ {
/* Prime Curves */ /* Prime Curves */
NID_secp160r1, NID_secp160r1,
NID_X9_62_prime192v1,
NID_secp224r1, NID_secp224r1,
NID_X9_62_prime256v1, NID_X9_62_prime256v1,
NID_secp384r1, NID_secp384r1,
@ -580,6 +582,7 @@ int MAIN(int argc, char **argv)
{ {
/* Prime Curves */ /* Prime Curves */
"secp160r1", "secp160r1",
"nistp192",
"nistp224", "nistp224",
"nistp256", "nistp256",
"nistp384", "nistp384",
@ -598,7 +601,7 @@ int MAIN(int argc, char **argv)
}; };
static int test_curves_bits[EC_NUM] = static int test_curves_bits[EC_NUM] =
{ {
160, 224, 256, 384, 521, 160, 192, 224, 256, 384, 521,
163, 233, 283, 409, 571, 163, 233, 283, 409, 571,
163, 233, 283, 409, 571 163, 233, 283, 409, 571
}; };

View File

@ -39,12 +39,12 @@ LIB=$(TOP)/libcrypto.a
LIBSRC= bn_add.c bn_div.c bn_exp.c bn_lib.c bn_ctx.c bn_mul.c bn_mod.c \ LIBSRC= bn_add.c bn_div.c bn_exp.c bn_lib.c bn_ctx.c bn_mul.c bn_mod.c \
bn_print.c bn_rand.c bn_shift.c bn_word.c bn_blind.c \ bn_print.c bn_rand.c bn_shift.c bn_word.c bn_blind.c \
bn_kron.c bn_sqrt.c bn_gcd.c bn_prime.c bn_err.c bn_sqr.c bn_asm.c \ bn_kron.c bn_sqrt.c bn_gcd.c bn_prime.c bn_err.c bn_sqr.c bn_asm.c \
bn_recp.c bn_mont.c bn_mpi.c bn_exp2.c bn_gf2m.c bn_recp.c bn_mont.c bn_mpi.c bn_exp2.c bn_gf2m.c bn_nist.c
LIBOBJ= bn_add.o bn_div.o bn_exp.o bn_lib.o bn_ctx.o bn_mul.o bn_mod.o \ LIBOBJ= bn_add.o bn_div.o bn_exp.o bn_lib.o bn_ctx.o bn_mul.o bn_mod.o \
bn_print.o bn_rand.o bn_shift.o bn_word.o bn_blind.o \ bn_print.o bn_rand.o bn_shift.o bn_word.o bn_blind.o \
bn_kron.o bn_sqrt.o bn_gcd.o bn_prime.o bn_err.o bn_sqr.o $(BN_ASM) \ bn_kron.o bn_sqrt.o bn_gcd.o bn_prime.o bn_err.o bn_sqr.o $(BN_ASM) \
bn_recp.o bn_mont.o bn_mpi.o bn_exp2.o bn_gf2m.o bn_recp.o bn_mont.o bn_mpi.o bn_exp2.o bn_gf2m.o bn_nist.o
SRC= $(LIBSRC) SRC= $(LIBSRC)
@ -286,6 +286,8 @@ bn_mul.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
bn_mul.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h bn_mul.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
bn_mul.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h bn_mul.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
bn_mul.o: ../cryptlib.h bn_lcl.h bn_mul.c bn_mul.o: ../cryptlib.h bn_lcl.h bn_mul.c
bn_nist.o: ../../include/openssl/bn.h ../../include/openssl/e_os2.h
bn_nist.o: ../../include/openssl/opensslconf.h bn_lcl.h bn_nist.c
bn_prime.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h bn_prime.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
bn_prime.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h bn_prime.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
bn_prime.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h bn_prime.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h

View File

@ -355,6 +355,8 @@ BIGNUM *BN_new(void);
void BN_init(BIGNUM *); void BN_init(BIGNUM *);
void BN_clear_free(BIGNUM *a); void BN_clear_free(BIGNUM *a);
BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b); BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b);
/* BN_ncopy(): like BN_copy() but copies at most the first n BN_ULONGs */
BIGNUM *BN_ncopy(BIGNUM *a, const BIGNUM *b, size_t n);
void BN_swap(BIGNUM *a, BIGNUM *b); void BN_swap(BIGNUM *a, BIGNUM *b);
BIGNUM *BN_bin2bn(const unsigned char *s,int len,BIGNUM *ret); BIGNUM *BN_bin2bn(const unsigned char *s,int len,BIGNUM *ret);
int BN_bn2bin(const BIGNUM *a, unsigned char *to); int BN_bn2bin(const BIGNUM *a, unsigned char *to);
@ -513,6 +515,20 @@ int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[
int BN_GF2m_poly2arr(const BIGNUM *a, unsigned int p[], int max); int BN_GF2m_poly2arr(const BIGNUM *a, unsigned int p[], int max);
int BN_GF2m_arr2poly(const unsigned int p[], BIGNUM *a); int BN_GF2m_arr2poly(const unsigned int p[], BIGNUM *a);
/* faster mod functions for the 'NIST primes'
* 0 <= a < p^2 */
int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
const BIGNUM *BN_get0_nist_prime_192(void);
const BIGNUM *BN_get0_nist_prime_224(void);
const BIGNUM *BN_get0_nist_prime_256(void);
const BIGNUM *BN_get0_nist_prime_384(void);
const BIGNUM *BN_get0_nist_prime_521(void);
/* library internal functions */ /* library internal functions */
#define bn_expand(a,bits) ((((((bits+BN_BITS2-1))/BN_BITS2)) <= (a)->dmax)?\ #define bn_expand(a,bits) ((((((bits+BN_BITS2-1))/BN_BITS2)) <= (a)->dmax)?\
@ -531,6 +547,14 @@ BIGNUM *bn_dup_expand(const BIGNUM *a, int words);
} \ } \
} }
#define bn_clear_top2max(a) \
{ \
int index = (a)->dmax - (a)->top; \
BN_ULONG *ftl = &(a)->d[(a)->top-1]; \
for (; index != 0; index--) \
*(++ftl) = 0x0; \
}
BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w); BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w); BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num); void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num);

View File

@ -522,6 +522,51 @@ BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
return(a); return(a);
} }
BIGNUM *BN_ncopy(BIGNUM *a, const BIGNUM *b, size_t n)
{
int i, min;
BN_ULONG *A;
const BN_ULONG *B;
bn_check_top(b);
if (a == b)
return a;
min = (b->top < (int)n)? b->top: (int)n;
if (!min)
{
BN_zero(a);
return a;
}
if (bn_wexpand(a, min) == NULL)
return NULL;
A=a->d;
B=b->d;
for (i=min>>2; i>0; i--, A+=4, B+=4)
{
BN_ULONG a0,a1,a2,a3;
a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
}
switch (min&3)
{
case 3: A[2]=B[2];
case 2: A[1]=B[1];
case 1: A[0]=B[0];
case 0: ;
}
a->top = min;
a->neg = b->neg;
bn_fix_top(a);
return(a);
}
void BN_swap(BIGNUM *a, BIGNUM *b) void BN_swap(BIGNUM *a, BIGNUM *b)
{ {
int flags_old_a, flags_old_b; int flags_old_a, flags_old_b;

828
crypto/bn/bn_nist.c Normal file
View File

@ -0,0 +1,828 @@
/* crypto/bn/bn_nist.p */
/* ====================================================================
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include "bn_lcl.h"
#define BN_NIST_192_TOP (192+BN_BITS2-1)/BN_BITS2
#define BN_NIST_224_TOP (224+BN_BITS2-1)/BN_BITS2
#define BN_NIST_256_TOP (256+BN_BITS2-1)/BN_BITS2
#define BN_NIST_384_TOP (384+BN_BITS2-1)/BN_BITS2
#define BN_NIST_521_TOP (521+BN_BITS2-1)/BN_BITS2
#if BN_BITS2 == 64
const static BN_ULONG _nist_p_192[] = {0xFFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFFE,
0xFFFFFFFFFFFFFFFF};
const static BN_ULONG _nist_p_224[] = {0x0000000000000001,0xFFFFFFFF00000000,
0xFFFFFFFFFFFFFFFF,0x00000000FFFFFFFF};
const static BN_ULONG _nist_p_256[] = {0xFFFFFFFFFFFFFFFF,0x00000000FFFFFFFF,
0x0000000000000000,0xFFFFFFFF00000001};
const static BN_ULONG _nist_p_384[] = {0x00000000FFFFFFFF,0xFFFFFFFF00000000,
0xFFFFFFFFFFFFFFFE,0xFFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFFF,
0xFFFFFFFFFFFFFFFF};
const static BN_ULONG _nist_p_521[] = {0xFFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFFF,
0xFFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFFF,
0xFFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFFF,
0x00000000000001FF};
#elif BN_BITS2 == 32
const static BN_ULONG _nist_p_192[] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFE,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
const static BN_ULONG _nist_p_224[] = {0x00000001,0x00000000,0x00000000,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
const static BN_ULONG _nist_p_256[] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0x00000000,0x00000000,0x00000000,0x00000001,0xFFFFFFFF};
const static BN_ULONG _nist_p_384[] = {0xFFFFFFFF,0x00000000,0x00000000,
0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
const static BN_ULONG _nist_p_521[] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0x000001FF};
#elif BN_BITS2 == 16
const static BN_ULONG _nist_p_192[] = {0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFE,
0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF};
const static BN_ULONG _nist_p_224[] = {0x0001,0x0000,0x0000,0x0000,0x0000,
0x0000,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF};
const static BN_ULONG _nist_p_256[] = {0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
0xFFFF,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0001,0x0000,0xFFFF,
0xFFFF};
const static BN_ULONG _nist_p_384[] = {0xFFFF,0xFFFF,0x0000,0x0000,0x0000,
0x0000,0xFFFF,0xFFFF,0xFFFE,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF};
const static BN_ULONG _nist_p_521[] = {0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0x01FF};
#elif BN_BITS2 == 8
const static BN_ULONG _nist_p_192[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF};
const static BN_ULONG _nist_p_224[] = {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
const static BN_ULONG _nist_p_256[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x01,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF};
const static BN_ULONG _nist_p_384[] = {0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
const static BN_ULONG _nist_p_521[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0x01};
#endif
const BIGNUM *BN_get0_nist_prime_192(void)
{
static BIGNUM const_nist_192={(BN_ULONG *)_nist_p_192,BN_NIST_192_TOP,
BN_NIST_192_TOP, 0, BN_FLG_STATIC_DATA};
return &const_nist_192;
}
const BIGNUM *BN_get0_nist_prime_224(void)
{
static BIGNUM const_nist_224={(BN_ULONG *)_nist_p_224,BN_NIST_224_TOP,
BN_NIST_224_TOP, 0, BN_FLG_STATIC_DATA};
return &const_nist_224;
}
const BIGNUM *BN_get0_nist_prime_256(void)
{
static BIGNUM const_nist_256={(BN_ULONG *)_nist_p_256,BN_NIST_256_TOP,
BN_NIST_256_TOP, 0, BN_FLG_STATIC_DATA};
return &const_nist_256;
}
const BIGNUM *BN_get0_nist_prime_384(void)
{
static BIGNUM const_nist_384={(BN_ULONG *)_nist_p_384,BN_NIST_384_TOP,
BN_NIST_384_TOP, 0, BN_FLG_STATIC_DATA};
return &const_nist_384;
}
const BIGNUM *BN_get0_nist_prime_521(void)
{
static BIGNUM const_nist_521={(BN_ULONG *)_nist_p_521,BN_NIST_521_TOP,
BN_NIST_521_TOP, 0, BN_FLG_STATIC_DATA};
return &const_nist_521;
}
/* some misc internal functions */
static BN_ULONG _256_data[BN_NIST_256_TOP*6];
static int _is_set_256_data = 0;
static void _init_256_data(void);
static BN_ULONG _384_data[BN_NIST_384_TOP*8];
static int _is_set_384_data = 0;
static void _init_384_data(void);
#define BN_NIST_ADD_ONE(a) while (!(++(*(a)))) ++(a);
#define __buf_0 (BN_ULONG)0
#define __buf_0_1 (BN_ULONG)0
#define __buf_0_2 (BN_ULONG)0
#if BN_BITS2 == 64
#define BN_64_BIT_BUF(n) BN_ULONG __buf_##n = (BN_ULONG)0;
#define BN_CP_64_TO_BUF(n) __buf_##n = (a)[(n)];
#define BN_CP_64_FROM_BUF(a,n) *(a)++ = __buf_##n;
#define BN_CASE_64_BIT(n,a) case (n): __buf_##n = (a)[(n)];
#if UINT_MAX == 4294967295UL
#define nist32 unsigned int
#define BN_32_BIT_BUF(n) nist32 __buf_##n = (nist32)0;
#define BN_CP_32_TO_BUF(n) __buf_##n = ((nist32 *)(a))[(n)];
#define BN_CP_32_FROM_BUF(a,n) *((nist32)(a))++ = __buf_##n;
#define BN_CASE_32_BIT(n,a) case (n): __buf_##n = ((nist32)(a))[(n)];
#elif ULONG_MAX == 4294967295UL
#define nist32 unsigned long
#define BN_32_BIT_BUF(n) nist32 __buf_##n = (nist32)0;
#define BN_CP_32_TO_BUF(n) __buf_##n = ((nist32 *)(a))[(n)];
#define BN_CP_32_FROM_BUF(a,n) *((nist32)(a))++ = __buf_##n;
#define BN_CASE_32_BIT(n,a) case (n): __buf_##n = ((nist32)(a))[(n)];
#else
#define NO_32_BIT_TYPE
#endif
#elif BN_BITS2 == 32
#define BN_64_BIT_BUF(n) BN_ULONG __buf_##n##_1 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_2 = (BN_ULONG)0;
#define BN_CP_64_TO_BUF(n) __buf_##n##_2 = (a)[2*(n)+1];\
__buf_##n##_1 = (a)[2*(n)];
#define BN_CP_64_FROM_BUF(a,n) *(a)++ = __buf_##n##_1;\
*(a)++ = __buf_##n##_2;
#define BN_CASE_64_BIT(n,a) case 2*(n)+1: __buf_##n##_2 = (a)[2*(n)+1];\
case 2*(n): __buf_##n##_1 = (a)[2*(n)];
#define BN_32_BIT_BUF(n) BN_ULONG __buf_##n = (BN_ULONG)0;
#define BN_CP_32_TO_BUF(n) __buf_##n = (a)[(n)];
#define BN_CP_32_FROM_BUF(a,n) *(a)++ = __buf_##n;
#define BN_CASE_32_BIT(n,a) case (n): __buf_##n = (a)[(n)];
#elif BN_BITS2 == 16
#define __buf_0_3 (BN_ULONG)0
#define __buf_0_4 (BN_ULONG)0
#define BN_64_BIT_BUF(n) BN_ULONG __buf_##n##_1 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_2 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_3 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_4 = (BN_ULONG)0;
#define BN_CP_64_TO_BUF(n) __buf_##n##_4 = (a)[4*(n)+3];\
__buf_##n##_3 = (a)[4*(n)+2];\
__buf_##n##_2 = (a)[4*(n)+1];\
__buf_##n##_1 = (a)[4*(n)];
#define BN_CP_64_FROM_BUF(a,n) *(a)++ = __buf_##n##_1;\
*(a)++ = __buf_##n##_2;\
*(a)++ = __buf_##n##_3;\
*(a)++ = __buf_##n##_4;
#define BN_CASE_64_BIT(n,a) case 4*(n)+3: __buf_##n##_4 = (a)[4*(n)+3];\
case 4*(n)+2: __buf_##n##_3 = (a)[4*(n)+2];\
case 4*(n)+1: __buf_##n##_2 = (a)[4*(n)+1];\
case 4*(n): __buf_##n##_1 = (a)[4*(n)];
#define BN_32_BIT_BUF(n) BN_ULONG __buf_##n##_1 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_2 = (BN_ULONG)0;
#define BN_CP_32_TO_BUF(n) __buf_##n##_1 = (a)[2*(n)];\
__buf_##n##_2 = (a)[2*(n)+1];
#define BN_CP_32_FROM_BUF(a,n) *(a)++ = __buf_##n##_1;\
*(a)++ = __buf_##n##_2;
#define BN_CASE_32_BIT(n,a) case 2*(n)+1: __buf_##n##_2 = (a)[2*(n)+1];\
case 2*(n): __buf_##n##_1 = (a)[2*(n)];
#elif BN_BITS2 == 8
#define __buf_0_3 (BN_ULONG)0
#define __buf_0_4 (BN_ULONG)0
#define __buf_0_5 (BN_ULONG)0
#define __buf_0_6 (BN_ULONG)0
#define __buf_0_7 (BN_ULONG)0
#define __buf_0_8 (BN_ULONG)0
#define BN_64_BIT_BUF(n) BN_ULONG __buf_##n##_1 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_2 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_3 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_4 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_5 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_6 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_7 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_8 = (BN_ULONG)0;
#define BN_CP_64_TO_BUF(n) __buf_##n##_8 = (a)[8*(n)+7];\
__buf_##n##_7 = (a)[8*(n)+6];\
__buf_##n##_6 = (a)[8*(n)+5];\
__buf_##n##_5 = (a)[8*(n)+4];\
__buf_##n##_4 = (a)[8*(n)+3];\
__buf_##n##_3 = (a)[8*(n)+2];\
__buf_##n##_2 = (a)[8*(n)+1];\
__buf_##n##_1 = (a)[8*(n)];
#define BN_CP_64_FROM_BUF(a,n) *(a)++ = __buf_##n##_1;\
*(a)++ = __buf_##n##_2;\
*(a)++ = __buf_##n##_3;\
*(a)++ = __buf_##n##_4;\
*(a)++ = __buf_##n##_5;\
*(a)++ = __buf_##n##_6;\
*(a)++ = __buf_##n##_7;\
*(a)++ = __buf_##n##_8;
#define BN_CASE_64_BIT(n,a) case 8*(n)+7: __buf_##n##_8 = (a)[8*(n)+7];\
case 8*(n)+6: __buf_##n##_7 = (a)[8*(n)+6];\
case 8*(n)+5: __buf_##n##_6 = (a)[8*(n)+5];\
case 8*(n)+4: __buf_##n##_5 = (a)[8*(n)+4];\
case 8*(n)+3: __buf_##n##_4 = (a)[8*(n)+3];\
case 8*(n)+2: __buf_##n##_3 = (a)[8*(n)+2];\
case 8*(n)+1: __buf_##n##_2 = (a)[8*(n)+1];\
case 8*(n): __buf_##n##_1 = (a)[8*(n)];
#define BN_32_BIT_BUF(n) BN_ULONG __buf_##n##_1 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_2 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_3 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_4 = (BN_ULONG)0;
#define BN_CP_32_TO_BUF(n) __buf_##n##_1 = (a)[4*(n)];\
__buf_##n##_2 = (a)[4*(n)+1];\
__buf_##n##_3 = (a)[4*(n)+2];\
__buf_##n##_4 = (a)[4*(n)+3];
#define BN_CP_32_FROM_BUF(a,n) *(a)++ = __buf_##n##_1;\
*(a)++ = __buf_##n##_2;\
*(a)++ = __buf_##n##_3;\
*(a)++ = __buf_##n##_4;
#define BN_CASE_32_BIT(n,a) case 4*(n)+3: __buf_##n##_4 = (a)[4*(n)+3];\
case 4*(n)+2: __buf_##n##_3 = (a)[4*(n)+2];\
case 4*(n)+1: __buf_##n##_2 = (a)[4*(n)+1];\
case 4*(n): __buf_##n##_1 = (a)[4*(n)];
#endif
#define BN_192_SET(d,a1,a2,a3) \
{\
register BN_ULONG *td = (d);\
BN_CP_64_FROM_BUF(td,a3); BN_CP_64_FROM_BUF(td,a2);\
BN_CP_64_FROM_BUF(td,a1);\
}
int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
BN_CTX *ctx)
{
int top;
BN_ULONG carry = 0;
register BN_ULONG *r_d, *a_d;
BN_ULONG t_d[BN_NIST_192_TOP];
BN_64_BIT_BUF(3) BN_64_BIT_BUF(4)
BN_64_BIT_BUF(5)
top = BN_ucmp(field, a);
if (top == 0)
return BN_zero(r);
else if (top > 0)
return (r == a)? 1 : !!BN_copy(r ,a);
if (r != a)
if (!BN_ncopy(r, a, BN_NIST_192_TOP))
return 0;
r_d = r->d;
a_d = a->d;
top = a->top-1;
switch (top)
{
BN_CASE_64_BIT(5, a_d)
BN_CASE_64_BIT(4, a_d)
BN_CASE_64_BIT(3, a_d)
break;
default: /* a->top == field->top */
return BN_usub(r, a, field);
}
BN_192_SET(t_d,0,3,3)
if (bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP))
++carry;
BN_192_SET(t_d,4,4,0)
if (bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP))
++carry;
BN_192_SET(t_d,5,5,5)
if (bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP))
++carry;
while (carry)
{
if (bn_sub_words(r_d, r_d, _nist_p_192, BN_NIST_192_TOP))
--carry;
}
r->top = BN_NIST_192_TOP;
#if 0
bn_clear_top2max(r);
#endif
bn_fix_top(r);
if (BN_ucmp(r, field) >= 0)
{
bn_sub_words(r_d, r_d, _nist_p_192, BN_NIST_192_TOP);
bn_fix_top(r);
}
return 1;
}
#define BN_224_SET(d,a1,a2,a3,a4,a5,a6,a7) \
{\
register BN_ULONG *td = (d);\
BN_CP_32_FROM_BUF(td,a7); BN_CP_32_FROM_BUF(td,a6);\
BN_CP_32_FROM_BUF(td,a5); BN_CP_32_FROM_BUF(td,a4);\
BN_CP_32_FROM_BUF(td,a3); BN_CP_32_FROM_BUF(td,a2);\
BN_CP_32_FROM_BUF(td,a1);\
}
int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
BN_CTX *ctx)
{
#ifndef NO_32_BIT_TYPE
int tmp_int;
int carry = 0;
BN_ULONG *r_d, *a_d;
BN_ULONG t_d[BN_NIST_224_TOP];
BN_32_BIT_BUF(7) BN_32_BIT_BUF(8)
BN_32_BIT_BUF(9) BN_32_BIT_BUF(10)
BN_32_BIT_BUF(11) BN_32_BIT_BUF(12)
BN_32_BIT_BUF(13)
tmp_int = BN_ucmp(field, a);
if (tmp_int == 0)
return BN_zero(r);
else if (tmp_int > 0)
return (r == a)? 1 : !!BN_copy(r ,a);
if (r != a)
if (!BN_ncopy(r, a, BN_NIST_224_TOP))
return 0;
r_d = r->d;
a_d = a->d;
tmp_int = a->top-1;
switch (tmp_int)
{
BN_CASE_32_BIT(13, a_d)
BN_CASE_32_BIT(12, a_d)
BN_CASE_32_BIT(11, a_d)
BN_CASE_32_BIT(10, a_d)
BN_CASE_32_BIT(9, a_d)
BN_CASE_32_BIT(8, a_d)
BN_CASE_32_BIT(7, a_d)
break;
default: /* a->top == field->top */
return BN_usub(r, a, field);
}
BN_224_SET(t_d,10,9,8,7,0,0,0)
if (bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP))
++carry;
BN_224_SET(t_d,0,13,12,11,0,0,0)
if (bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP))
++carry;
BN_224_SET(t_d,13,12,11,10,9,8,7)
if (bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP))
--carry;
BN_224_SET(t_d,0,0,0,0,13,12,11)
if (bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP))
--carry;
if (carry > 0)
while (carry)
{
if (bn_sub_words(r_d,r_d,_nist_p_224,BN_NIST_224_TOP))
--carry;
}
else if (carry < 0)
while (carry)
{
if (bn_add_words(r_d,r_d,_nist_p_224,BN_NIST_224_TOP))
++carry;
}
r->top = BN_NIST_224_TOP;
#if 0
bn_clear_top2max(r);
#endif
bn_fix_top(r);
if (BN_ucmp(r, field) >= 0)
{
bn_sub_words(r_d, r_d, _nist_p_224, BN_NIST_224_TOP);
bn_fix_top(r);
}
return 1;
#else
return 0;
#endif
}
static void _init_256_data(void)
{
int i;
BN_ULONG *tmp1 = _256_data;
const BN_ULONG *tmp2 = tmp1;
memcpy(tmp1, _nist_p_256, BN_NIST_256_TOP * sizeof(BN_ULONG));
tmp1 += BN_NIST_256_TOP;
for (i=0; i<5; i++)
{
bn_add_words(tmp1, _nist_p_256, tmp2, BN_NIST_256_TOP);
tmp2 = tmp1;
tmp1 += BN_NIST_256_TOP;
}
_is_set_256_data = 1;
}
#define BN_256_SET(d,a1,a2,a3,a4,a5,a6,a7,a8) \
{\
register BN_ULONG *td = (d);\
BN_CP_32_FROM_BUF(td,a8); BN_CP_32_FROM_BUF(td,a7);\
BN_CP_32_FROM_BUF(td,a6); BN_CP_32_FROM_BUF(td,a5);\
BN_CP_32_FROM_BUF(td,a4); BN_CP_32_FROM_BUF(td,a3);\
BN_CP_32_FROM_BUF(td,a2); BN_CP_32_FROM_BUF(td,a1);\
}
int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
BN_CTX *ctx)
{
#ifndef NO_32_BIT_TYPE
int tmp_int;
int carry = 0;
register BN_ULONG *a_d, *r_d;
BN_ULONG t_d[BN_NIST_256_TOP];
BN_ULONG t_d2[BN_NIST_256_TOP];
BN_32_BIT_BUF(8) BN_32_BIT_BUF(9)
BN_32_BIT_BUF(10) BN_32_BIT_BUF(11)
BN_32_BIT_BUF(12) BN_32_BIT_BUF(13)
BN_32_BIT_BUF(14) BN_32_BIT_BUF(15)
if (!_is_set_256_data)
_init_256_data();
tmp_int = BN_ucmp(field, a);
if (tmp_int == 0)
return BN_zero(r);
else if (tmp_int > 0)
return (r == a)? 1 : !!BN_copy(r ,a);
if (r != a)
if (!BN_ncopy(r, a, BN_NIST_256_TOP))
return 0;
tmp_int = a->top-1;
a_d = a->d;
r_d = r->d;
switch (tmp_int)
{
BN_CASE_32_BIT(15, a_d)
BN_CASE_32_BIT(14, a_d)
BN_CASE_32_BIT(13, a_d)
BN_CASE_32_BIT(12, a_d)
BN_CASE_32_BIT(11, a_d)
BN_CASE_32_BIT(10, a_d)
BN_CASE_32_BIT(9, a_d)
BN_CASE_32_BIT(8, a_d)
break;
default: /* a->top == field->top */
return BN_usub(r, a, field);
}
/*S1*/
BN_256_SET(t_d,15,14,13,12,11,0,0,0)
/*S2*/
BN_256_SET(t_d2,0,15,14,13,12,0,0,0)
if (bn_add_words(t_d, t_d, t_d2, BN_NIST_256_TOP))
carry = 2;
/* left shift */
{
register BN_ULONG *ap,t,c;
ap = t_d;
c=0;
for (tmp_int=BN_NIST_256_TOP; tmp_int != 0; --tmp_int)
{
t= *ap;
*(ap++)=((t<<1)|c)&BN_MASK2;
c=(t & BN_TBIT)?1:0;
}
if (c)
++carry;
}
if (bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP))
++carry;
/*S3*/
BN_256_SET(t_d,15,14,0,0,0,10,9,8)
if (bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP))
++carry;
/*S4*/
BN_256_SET(t_d,8,13,15,14,13,11,10,9)
if (bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP))
++carry;
/*D1*/
BN_256_SET(t_d,10,8,0,0,0,13,12,11)
if (bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP))
--carry;
/*D2*/
BN_256_SET(t_d,11,9,0,0,15,14,13,12)
if (bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP))
--carry;
/*D3*/
BN_256_SET(t_d,12,0,10,9,8,15,14,13)
if (bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP))
--carry;
/*D4*/
BN_256_SET(t_d,13,0,11,10,9,0,15,14)
if (bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP))
--carry;
if (carry)
{
if (carry > 0)
bn_sub_words(r_d, r_d, _256_data + BN_NIST_256_TOP *
--carry, BN_NIST_256_TOP);
else
{
carry = -carry;
bn_add_words(r_d, r_d, _256_data + BN_NIST_256_TOP *
--carry, BN_NIST_256_TOP);
}
}
r->top = BN_NIST_256_TOP;
#if 0
bn_clear_top2max(r);
#endif
bn_fix_top(r);
if (BN_ucmp(r, field) >= 0)
{
bn_sub_words(r_d, r_d, _nist_p_256, BN_NIST_256_TOP);
bn_fix_top(r);
}
return 1;
#else
return 0;
#endif
}
static void _init_384_data(void)
{
int i;
BN_ULONG *tmp1 = _384_data;
const BN_ULONG *tmp2 = tmp1;
memcpy(tmp1, _nist_p_384, BN_NIST_384_TOP * sizeof(BN_ULONG));
tmp1 += BN_NIST_384_TOP;
for (i=0; i<7; i++)
{
bn_add_words(tmp1, _nist_p_384, tmp2, BN_NIST_384_TOP);
tmp2 = tmp1;
tmp1 += BN_NIST_384_TOP;
}
_is_set_384_data = 1;
}
#define BN_384_SET(d,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) \
{\
register BN_ULONG *td = (d);\
BN_CP_32_FROM_BUF(td,a12); BN_CP_32_FROM_BUF(td,a11);\
BN_CP_32_FROM_BUF(td,a10); BN_CP_32_FROM_BUF(td,a9);\
BN_CP_32_FROM_BUF(td,a8); BN_CP_32_FROM_BUF(td,a7);\
BN_CP_32_FROM_BUF(td,a6); BN_CP_32_FROM_BUF(td,a5);\
BN_CP_32_FROM_BUF(td,a4); BN_CP_32_FROM_BUF(td,a3);\
BN_CP_32_FROM_BUF(td,a2); BN_CP_32_FROM_BUF(td,a1);\
}
int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
BN_CTX *ctx)
{
#ifndef NO_32_BIT_TYPE
int tmp_int;
int carry = 0;
register BN_ULONG *r_d, *a_d;
BN_ULONG t_d[BN_NIST_384_TOP];
BN_32_BIT_BUF(12) BN_32_BIT_BUF(13)
BN_32_BIT_BUF(14) BN_32_BIT_BUF(15)
BN_32_BIT_BUF(16) BN_32_BIT_BUF(17)
BN_32_BIT_BUF(18) BN_32_BIT_BUF(19)
BN_32_BIT_BUF(20) BN_32_BIT_BUF(21)
BN_32_BIT_BUF(22) BN_32_BIT_BUF(23)
if (!_is_set_384_data)
_init_384_data();
tmp_int = BN_ucmp(field, a);
if (tmp_int == 0)
return BN_zero(r);
else if (tmp_int > 0)
return (r == a)? 1 : !!BN_copy(r ,a);
if (r != a)
if (!BN_ncopy(r, a, BN_NIST_384_TOP))
return 0;
r_d = r->d;
a_d = a->d;
tmp_int = a->top-1;
switch (tmp_int)
{
BN_CASE_32_BIT(23, a_d)
BN_CASE_32_BIT(22, a_d)
BN_CASE_32_BIT(21, a_d)
BN_CASE_32_BIT(20, a_d)
BN_CASE_32_BIT(19, a_d)
BN_CASE_32_BIT(18, a_d)
BN_CASE_32_BIT(17, a_d)
BN_CASE_32_BIT(16, a_d)
BN_CASE_32_BIT(15, a_d)
BN_CASE_32_BIT(14, a_d)
BN_CASE_32_BIT(13, a_d)
BN_CASE_32_BIT(12, a_d)
break;
default: /* a->top == field->top */
return BN_usub(r, a, field);
}
/*S1*/
BN_256_SET(t_d,0,0,0,0,0,23,22,21)
/* left shift */
{
register BN_ULONG *ap,t,c;
ap = t_d;
c=0;
for (tmp_int=BN_NIST_256_TOP; tmp_int != 0; --tmp_int)
{
t= *ap;
*(ap++)=((t<<1)|c)&BN_MASK2;
c=(t & BN_TBIT)?1:0;
}
}
if (bn_add_words(r_d+(128/BN_BITS2), r_d+(128/BN_BITS2),
t_d, BN_NIST_256_TOP))
++carry;
/*S2*/
BN_384_SET(t_d,23,22,21,20,19,18,17,16,15,14,13,12)
if (bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP))
++carry;
/*S3*/
BN_384_SET(t_d,20,19,18,17,16,15,14,13,12,23,22,21)
if (bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP))
++carry;
/*S4*/
BN_384_SET(t_d,19,18,17,16,15,14,13,12,20,0,23,0)
if (bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP))
++carry;
/*S5*/
BN_256_SET(t_d,0,0,0,0,23,22,21,20)
if (bn_add_words(r_d+(128/BN_BITS2), r_d+(128/BN_BITS2),
t_d, BN_NIST_256_TOP))
++carry;
/*S6*/
BN_384_SET(t_d,0,0,0,0,0,0,23,22,21,0,0,20)
if (bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP))
++carry;
/*D1*/
BN_384_SET(t_d,22,21,20,19,18,17,16,15,14,13,12,23)
if (bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP))
--carry;
/*D2*/
BN_384_SET(t_d,0,0,0,0,0,0,0,23,22,21,20,0)
if (bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP))
--carry;
/*D3*/
BN_384_SET(t_d,0,0,0,0,0,0,0,23,23,0,0,0)
if (bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP))
--carry;
if (carry)
{
if (carry > 0)
bn_sub_words(r_d, r_d, _384_data + BN_NIST_384_TOP *
--carry, BN_NIST_384_TOP);
else
{
carry = -carry;
bn_add_words(r_d, r_d, _384_data + BN_NIST_384_TOP *
--carry, BN_NIST_384_TOP);
}
}
r->top = BN_NIST_384_TOP;
#if 0
bn_clear_top2max(r);
#endif
bn_fix_top(r);
if (BN_ucmp(r, field) >= 0)
{
bn_sub_words(r_d, r_d, _nist_p_384, BN_NIST_384_TOP);
bn_fix_top(r);
}
return 1;
#else
return 0;
#endif
}
int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
BN_CTX *ctx)
{
#if BN_BITS2 == 64
#define BN_NIST_521_TOP_MASK (BN_ULONG)0x1FF
#elif BN_BITS2 == 32
#define BN_NIST_521_TOP_MASK (BN_ULONG)0x1FF
#elif BN_BITS2 == 16
#define BN_NIST_521_TOP_MASK (BN_ULONG)0x1FF
#elif BN_BITS2 == 8
#define BN_NIST_521_TOP_MASK (BN_ULONG)0x1
#endif
int top, ret = 0;
BN_ULONG *r_d;
BIGNUM *tmp;
/* check whether a reduction is necessary */
top = a->top;
if (top < BN_NIST_521_TOP || ( top == BN_NIST_521_TOP &&
(!(a->d[BN_NIST_521_TOP-1] & ~(BN_NIST_521_TOP_MASK)))))
return (r == a)? 1 : !!BN_copy(r ,a);
BN_CTX_start(ctx);
tmp = BN_CTX_get(ctx);
if (!tmp)
goto err;
if (!BN_ncopy(tmp, a, BN_NIST_521_TOP))
return 0;
if (!BN_rshift(r, a, 521))
return 0;
if (tmp->top == BN_NIST_521_TOP)
tmp->d[BN_NIST_521_TOP-1] &= BN_NIST_521_TOP_MASK;
if (!BN_uadd(r, tmp, r))
return 0;
top = r->top;
r_d = r->d;
if (top == BN_NIST_521_TOP &&
(r_d[BN_NIST_521_TOP-1] & ~(BN_NIST_521_TOP_MASK)))
{
BN_NIST_ADD_ONE(r_d)
r_d[BN_NIST_521_TOP-1] &= BN_NIST_521_TOP_MASK;
}
bn_fix_top(r);
ret = 1;
err:
BN_CTX_end(ctx);
return ret;
}

View File

@ -129,6 +129,7 @@ ec_curve.o: ../../include/openssl/symhacks.h ec_curve.c ec_lcl.h
ec_cvt.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h ec_cvt.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
ec_cvt.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h ec_cvt.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
ec_cvt.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h ec_cvt.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
ec_cvt.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
ec_cvt.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h ec_cvt.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
ec_cvt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h ec_cvt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
ec_cvt.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h ec_cvt.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
@ -183,6 +184,7 @@ ecp_mont.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_mont.c
ecp_nist.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h ecp_nist.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
ecp_nist.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h ecp_nist.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
ecp_nist.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h ecp_nist.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
ecp_nist.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
ecp_nist.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h ecp_nist.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
ecp_nist.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h ecp_nist.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
ecp_nist.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h ecp_nist.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h

View File

@ -127,9 +127,9 @@ typedef struct ec_point_st EC_POINT;
*/ */
const EC_METHOD *EC_GFp_simple_method(void); const EC_METHOD *EC_GFp_simple_method(void);
const EC_METHOD *EC_GFp_mont_method(void); const EC_METHOD *EC_GFp_mont_method(void);
const EC_METHOD *EC_GFp_nist_method(void);
#if 0 #if 0
const EC_METHOD *EC_GFp_recp_method(void); /* TODO */ const EC_METHOD *EC_GFp_recp_method(void); /* TODO */
const EC_METHOD *EC_GFp_nist_method(void); /* TODO */
#endif #endif
/* EC_METHOD for curves over GF(2^m). /* EC_METHOD for curves over GF(2^m).
@ -370,6 +370,10 @@ void ERR_load_EC_strings(void);
#define EC_F_ECPKPARAMETERS_PRINT_FP 150 #define EC_F_ECPKPARAMETERS_PRINT_FP 150
#define EC_F_ECPUBLICKEY_GET_OCTET 151 #define EC_F_ECPUBLICKEY_GET_OCTET 151
#define EC_F_ECPUBLICKEY_SET_OCTET 152 #define EC_F_ECPUBLICKEY_SET_OCTET 152
#define EC_F_ECP_NIST_MOD_192 203
#define EC_F_ECP_NIST_MOD_224 204
#define EC_F_ECP_NIST_MOD_256 205
#define EC_F_ECP_NIST_MOD_521 206
#define EC_F_EC_ASN1_GROUP2CURVE 153 #define EC_F_EC_ASN1_GROUP2CURVE 153
#define EC_F_EC_ASN1_GROUP2FIELDID 154 #define EC_F_EC_ASN1_GROUP2FIELDID 154
#define EC_F_EC_ASN1_GROUP2PARAMETERS 155 #define EC_F_EC_ASN1_GROUP2PARAMETERS 155
@ -387,6 +391,9 @@ void ERR_load_EC_strings(void);
#define EC_F_EC_GFP_MONT_FIELD_ENCODE 134 #define EC_F_EC_GFP_MONT_FIELD_ENCODE 134
#define EC_F_EC_GFP_MONT_FIELD_MUL 131 #define EC_F_EC_GFP_MONT_FIELD_MUL 131
#define EC_F_EC_GFP_MONT_FIELD_SQR 132 #define EC_F_EC_GFP_MONT_FIELD_SQR 132
#define EC_F_EC_GFP_NIST_FIELD_MUL 200
#define EC_F_EC_GFP_NIST_FIELD_SQR 201
#define EC_F_EC_GFP_NIST_GROUP_SET_CURVE_GFP 202
#define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT 165 #define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT 165
#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE 166 #define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE 166
#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP 100 #define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP 100
@ -468,6 +475,7 @@ void ERR_load_EC_strings(void);
#define EC_R_GROUP2PKPARAMETERS_FAILURE 120 #define EC_R_GROUP2PKPARAMETERS_FAILURE 120
#define EC_R_I2D_ECPKPARAMETERS_FAILURE 121 #define EC_R_I2D_ECPKPARAMETERS_FAILURE 121
#define EC_R_INCOMPATIBLE_OBJECTS 101 #define EC_R_INCOMPATIBLE_OBJECTS 101
#define EC_R_INTERNAL_ERROR 132
#define EC_R_INVALID_ARGUMENT 112 #define EC_R_INVALID_ARGUMENT 112
#define EC_R_INVALID_COMPRESSED_POINT 110 #define EC_R_INVALID_COMPRESSED_POINT 110
#define EC_R_INVALID_COMPRESSION_BIT 109 #define EC_R_INVALID_COMPRESSION_BIT 109
@ -480,10 +488,13 @@ void ERR_load_EC_strings(void);
#define EC_R_MISSING_PRIVATE_KEY 125 #define EC_R_MISSING_PRIVATE_KEY 125
#define EC_R_NOT_IMPLEMENTED 126 #define EC_R_NOT_IMPLEMENTED 126
#define EC_R_NOT_INITIALIZED 111 #define EC_R_NOT_INITIALIZED 111
#define EC_R_NO_FIELD_MOD 133
#define EC_R_NO_SUCH_EXTRA_DATA 105 #define EC_R_NO_SUCH_EXTRA_DATA 105
#define EC_R_PASSED_NULL_PARAMETER 134
#define EC_R_PKPARAMETERS2GROUP_FAILURE 127 #define EC_R_PKPARAMETERS2GROUP_FAILURE 127
#define EC_R_POINT_AT_INFINITY 106 #define EC_R_POINT_AT_INFINITY 106
#define EC_R_POINT_IS_NOT_ON_CURVE 107 #define EC_R_POINT_IS_NOT_ON_CURVE 107
#define EC_R_PRIME_IS_NOT_A_NIST_PRIME 135
#define EC_R_SLOT_FULL 108 #define EC_R_SLOT_FULL 108
#define EC_R_UNDEFINED_GENERATOR 113 #define EC_R_UNDEFINED_GENERATOR 113
#define EC_R_UNDEFINED_ORDER 128 #define EC_R_UNDEFINED_ORDER 128

View File

@ -82,6 +82,7 @@
* *
*/ */
#include <openssl/err.h>
#include "ec_lcl.h" #include "ec_lcl.h"
@ -89,11 +90,8 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM
{ {
const EC_METHOD *meth; const EC_METHOD *meth;
EC_GROUP *ret; EC_GROUP *ret;
/* Finally, this will use EC_GFp_nist_method if 'p' is a special meth = EC_GFp_nist_method();
* prime with optimized modular arithmetics (for NIST curves)
*/
meth = EC_GFp_mont_method();
ret = EC_GROUP_new(meth); ret = EC_GROUP_new(meth);
if (ret == NULL) if (ret == NULL)
@ -101,8 +99,21 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM
if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx))
{ {
/* remove the last error code form the error queue */
ERR_get_error();
/* try the normal mont method */
EC_GROUP_clear_free(ret); EC_GROUP_clear_free(ret);
return NULL; meth = EC_GFp_mont_method();
ret = EC_GROUP_new(meth);
if (ret == NULL)
return NULL;
if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx))
{
EC_GROUP_clear_free(ret);
return NULL;
}
} }
return ret; return ret;

View File

@ -76,6 +76,10 @@ static ERR_STRING_DATA EC_str_functs[]=
{ERR_PACK(0,EC_F_ECPKPARAMETERS_PRINT_FP,0), "ECPKParameters_print_fp"}, {ERR_PACK(0,EC_F_ECPKPARAMETERS_PRINT_FP,0), "ECPKParameters_print_fp"},
{ERR_PACK(0,EC_F_ECPUBLICKEY_GET_OCTET,0), "ECPUBLICKEY_GET_OCTET"}, {ERR_PACK(0,EC_F_ECPUBLICKEY_GET_OCTET,0), "ECPUBLICKEY_GET_OCTET"},
{ERR_PACK(0,EC_F_ECPUBLICKEY_SET_OCTET,0), "ECPUBLICKEY_SET_OCTET"}, {ERR_PACK(0,EC_F_ECPUBLICKEY_SET_OCTET,0), "ECPUBLICKEY_SET_OCTET"},
{ERR_PACK(0,EC_F_ECP_NIST_MOD_192,0), "ECP_NIST_MOD_192"},
{ERR_PACK(0,EC_F_ECP_NIST_MOD_224,0), "ECP_NIST_MOD_224"},
{ERR_PACK(0,EC_F_ECP_NIST_MOD_256,0), "ECP_NIST_MOD_256"},
{ERR_PACK(0,EC_F_ECP_NIST_MOD_521,0), "ECP_NIST_MOD_521"},
{ERR_PACK(0,EC_F_EC_ASN1_GROUP2CURVE,0), "EC_ASN1_GROUP2CURVE"}, {ERR_PACK(0,EC_F_EC_ASN1_GROUP2CURVE,0), "EC_ASN1_GROUP2CURVE"},
{ERR_PACK(0,EC_F_EC_ASN1_GROUP2FIELDID,0), "EC_ASN1_GROUP2FIELDID"}, {ERR_PACK(0,EC_F_EC_ASN1_GROUP2FIELDID,0), "EC_ASN1_GROUP2FIELDID"},
{ERR_PACK(0,EC_F_EC_ASN1_GROUP2PARAMETERS,0), "EC_ASN1_GROUP2PARAMETERS"}, {ERR_PACK(0,EC_F_EC_ASN1_GROUP2PARAMETERS,0), "EC_ASN1_GROUP2PARAMETERS"},
@ -93,6 +97,9 @@ static ERR_STRING_DATA EC_str_functs[]=
{ERR_PACK(0,EC_F_EC_GFP_MONT_FIELD_ENCODE,0), "ec_GFp_mont_field_encode"}, {ERR_PACK(0,EC_F_EC_GFP_MONT_FIELD_ENCODE,0), "ec_GFp_mont_field_encode"},
{ERR_PACK(0,EC_F_EC_GFP_MONT_FIELD_MUL,0), "ec_GFp_mont_field_mul"}, {ERR_PACK(0,EC_F_EC_GFP_MONT_FIELD_MUL,0), "ec_GFp_mont_field_mul"},
{ERR_PACK(0,EC_F_EC_GFP_MONT_FIELD_SQR,0), "ec_GFp_mont_field_sqr"}, {ERR_PACK(0,EC_F_EC_GFP_MONT_FIELD_SQR,0), "ec_GFp_mont_field_sqr"},
{ERR_PACK(0,EC_F_EC_GFP_NIST_FIELD_MUL,0), "ec_GFp_nist_field_mul"},
{ERR_PACK(0,EC_F_EC_GFP_NIST_FIELD_SQR,0), "ec_GFp_nist_field_sqr"},
{ERR_PACK(0,EC_F_EC_GFP_NIST_GROUP_SET_CURVE_GFP,0), "EC_GFP_NIST_GROUP_SET_CURVE_GFP"},
{ERR_PACK(0,EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT,0), "ec_GFp_simple_group_check_discriminant"}, {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT,0), "ec_GFp_simple_group_check_discriminant"},
{ERR_PACK(0,EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE,0), "ec_GFp_simple_group_set_curve"}, {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE,0), "ec_GFp_simple_group_set_curve"},
{ERR_PACK(0,EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP,0), "EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP"}, {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP,0), "EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP"},
@ -177,6 +184,7 @@ static ERR_STRING_DATA EC_str_reasons[]=
{EC_R_GROUP2PKPARAMETERS_FAILURE ,"group2pkparameters failure"}, {EC_R_GROUP2PKPARAMETERS_FAILURE ,"group2pkparameters failure"},
{EC_R_I2D_ECPKPARAMETERS_FAILURE ,"i2d ecpkparameters failure"}, {EC_R_I2D_ECPKPARAMETERS_FAILURE ,"i2d ecpkparameters failure"},
{EC_R_INCOMPATIBLE_OBJECTS ,"incompatible objects"}, {EC_R_INCOMPATIBLE_OBJECTS ,"incompatible objects"},
{EC_R_INTERNAL_ERROR ,"internal error"},
{EC_R_INVALID_ARGUMENT ,"invalid argument"}, {EC_R_INVALID_ARGUMENT ,"invalid argument"},
{EC_R_INVALID_COMPRESSED_POINT ,"invalid compressed point"}, {EC_R_INVALID_COMPRESSED_POINT ,"invalid compressed point"},
{EC_R_INVALID_COMPRESSION_BIT ,"invalid compression bit"}, {EC_R_INVALID_COMPRESSION_BIT ,"invalid compression bit"},
@ -189,10 +197,13 @@ static ERR_STRING_DATA EC_str_reasons[]=
{EC_R_MISSING_PRIVATE_KEY ,"missing private key"}, {EC_R_MISSING_PRIVATE_KEY ,"missing private key"},
{EC_R_NOT_IMPLEMENTED ,"not implemented"}, {EC_R_NOT_IMPLEMENTED ,"not implemented"},
{EC_R_NOT_INITIALIZED ,"not initialized"}, {EC_R_NOT_INITIALIZED ,"not initialized"},
{EC_R_NO_FIELD_MOD ,"no field mod"},
{EC_R_NO_SUCH_EXTRA_DATA ,"no such extra data"}, {EC_R_NO_SUCH_EXTRA_DATA ,"no such extra data"},
{EC_R_PASSED_NULL_PARAMETER ,"passed null parameter"},
{EC_R_PKPARAMETERS2GROUP_FAILURE ,"pkparameters2group failure"}, {EC_R_PKPARAMETERS2GROUP_FAILURE ,"pkparameters2group failure"},
{EC_R_POINT_AT_INFINITY ,"point at infinity"}, {EC_R_POINT_AT_INFINITY ,"point at infinity"},
{EC_R_POINT_IS_NOT_ON_CURVE ,"point is not on curve"}, {EC_R_POINT_IS_NOT_ON_CURVE ,"point is not on curve"},
{EC_R_PRIME_IS_NOT_A_NIST_PRIME ,"prime is not a nist prime"},
{EC_R_SLOT_FULL ,"slot full"}, {EC_R_SLOT_FULL ,"slot full"},
{EC_R_UNDEFINED_GENERATOR ,"undefined generator"}, {EC_R_UNDEFINED_GENERATOR ,"undefined generator"},
{EC_R_UNDEFINED_ORDER ,"undefined order"}, {EC_R_UNDEFINED_ORDER ,"undefined order"},

View File

@ -1,6 +1,9 @@
/* crypto/ec/ecp_nist.c */ /* crypto/ec/ecp_nist.c */
/*
* Written by Nils Larsch for the OpenSSL project.
*/
/* ==================================================================== /* ====================================================================
* Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -58,12 +61,14 @@
* and contributed to the OpenSSL project. * and contributed to the OpenSSL project.
*/ */
#include <openssl/err.h>
#include <openssl/obj_mac.h>
#include "ec_lcl.h" #include "ec_lcl.h"
#if 0
const EC_METHOD *EC_GFp_nist_method(void) const EC_METHOD *EC_GFp_nist_method(void)
{ {
static const EC_METHOD ret = { static const EC_METHOD ret = {
NID_X9_62_prime_field,
ec_GFp_nist_group_init, ec_GFp_nist_group_init,
ec_GFp_nist_group_finish, ec_GFp_nist_group_finish,
ec_GFp_nist_group_clear_finish, ec_GFp_nist_group_clear_finish,
@ -71,10 +76,6 @@ const EC_METHOD *EC_GFp_nist_method(void)
ec_GFp_nist_group_set_curve, ec_GFp_nist_group_set_curve,
ec_GFp_simple_group_get_curve, ec_GFp_simple_group_get_curve,
ec_GFp_simple_group_get_degree, ec_GFp_simple_group_get_degree,
ec_GFp_simple_group_set_generator,
ec_GFp_simple_group_get0_generator,
ec_GFp_simple_group_get_order,
ec_GFp_simple_group_get_cofactor,
ec_GFp_simple_group_check_discriminant, ec_GFp_simple_group_check_discriminant,
ec_GFp_simple_point_init, ec_GFp_simple_point_init,
ec_GFp_simple_point_finish, ec_GFp_simple_point_finish,
@ -107,8 +108,13 @@ const EC_METHOD *EC_GFp_nist_method(void)
return &ret; return &ret;
} }
#endif
#define ECP_MOD_CAST \
(int (*)(BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *))
#if BN_BITS2 == 64 && UINT_MAX != 4294967295UL && ULONG_MAX != 4294967295UL
#define NO_32_BIT_TYPE
#endif
int ec_GFp_nist_group_init(EC_GROUP *group) int ec_GFp_nist_group_init(EC_GROUP *group)
{ {
@ -119,26 +125,154 @@ int ec_GFp_nist_group_init(EC_GROUP *group)
return ok; return ok;
} }
void ec_GFp_nist_group_finish(EC_GROUP *group)
int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); {
/* TODO */ BN_free(&group->field);
BN_free(&group->a);
BN_free(&group->b);
}
void ec_GFp_nist_group_finish(EC_GROUP *group); void ec_GFp_nist_group_clear_finish(EC_GROUP *group)
/* TODO */ {
BN_clear_free(&group->field);
BN_clear_free(&group->a);
BN_clear_free(&group->b);
}
void ec_GFp_nist_group_clear_finish(EC_GROUP *group); int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
/* TODO */ const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
{
int ret = 0;
BN_CTX *new_ctx = NULL;
BIGNUM *tmp_bn;
if (ctx == NULL)
if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
BN_CTX_start(ctx);
if ((tmp_bn = BN_CTX_get(ctx)) == NULL) goto err;
int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src); if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0)
/* TODO */ group->field_data1 = (void *)BN_nist_mod_192;
else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0)
#if !defined(ECP_NO_32_BIT_TYPE) || defined(OPENSSL_NO_ASM)
group->field_data1 = (void *)BN_nist_mod_224;
#else
goto err;
#endif
else if (BN_ucmp(BN_get0_nist_prime_256(), p) == 0)
#if !defined(ECP_NO_32_BIT_TYPE) || defined(OPENSSL_NO_ASM)
group->field_data1 = (void *)BN_nist_mod_256;
#else
goto err;
#endif
else if (BN_ucmp(BN_get0_nist_prime_384(), p) == 0)
#if !defined(ECP_NO_32_BIT_TYPE) || defined(OPENSSL_NO_ASM)
group->field_data1 = (void *)BN_nist_mod_384;
#else
goto err;
#endif
else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0)
group->field_data1 = (void *)BN_nist_mod_521;
else
{
ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE_GFP,
EC_R_PRIME_IS_NOT_A_NIST_PRIME);
goto err;
}
/* group->field */
if (!BN_copy(&group->field, p)) goto err;
group->field.neg = 0;
int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); /* group->a */
/* TODO */ (ECP_MOD_CAST group->field_data1)(&group->a, a, p, ctx);
/* group->b */
(ECP_MOD_CAST group->field_data1)(&group->b, b, p, ctx);
int ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx); /* group->a_is_minus3 */
/* TODO */ if (!BN_add_word(tmp_bn, 3)) goto err;
group->a_is_minus3 = (0 == BN_cmp(tmp_bn, &group->field));
ret = 1;
err:
BN_CTX_end(ctx);
if (new_ctx != NULL)
BN_CTX_free(new_ctx);
return ret;
}
int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src)
{
if (dest == NULL || src == NULL)
return 0;
if (!BN_copy(&dest->field, &src->field))
return 0;
if (!BN_copy(&dest->a, &src->a))
return 0;
if (!BN_copy(&dest->b, &src->b))
return 0;
dest->curve_name = src->curve_name;
dest->a_is_minus3 = src->a_is_minus3;
dest->field_data1 = src->field_data1;
return 1;
}
int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
const BIGNUM *b, BN_CTX *ctx)
{
int ret=0;
BN_CTX *ctx_new=NULL;
if (!group || !r || !a || !b)
{
ECerr(EC_F_EC_GFP_NIST_FIELD_MUL, ERR_R_PASSED_NULL_PARAMETER);
goto err;
}
if (!ctx)
if ((ctx_new = ctx = BN_CTX_new()) == NULL) goto err;
if (!BN_mul(r, a, b, ctx)) goto err;
if (!(ECP_MOD_CAST group->field_data1)(r, r, &group->field, ctx))
goto err;
ret=1;
err:
if (ctx_new)
BN_CTX_free(ctx_new);
return ret;
}
int ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
BN_CTX *ctx)
{
int ret=0;
BN_CTX *ctx_new=NULL;
if (!group || !r || !a)
{
ECerr(EC_F_EC_GFP_NIST_FIELD_SQR, EC_R_PASSED_NULL_PARAMETER);
goto err;
}
if (!ctx)
if ((ctx_new = ctx = BN_CTX_new()) == NULL) goto err;
if (!BN_sqr(r, a, ctx)) goto err;
if (!(ECP_MOD_CAST group->field_data1)(r, r, &group->field, ctx))
goto err;
ret=1;
err:
if (ctx_new)
BN_CTX_free(ctx_new);
return ret;
}

View File

@ -3022,3 +3022,15 @@ ASN1_item_ndef_i2d 3454 EXIST::FUNCTION:
i2d_PKCS7_NDEF 3455 EXIST::FUNCTION: i2d_PKCS7_NDEF 3455 EXIST::FUNCTION:
ENGINE_up_ref 3456 EXIST::FUNCTION: ENGINE_up_ref 3456 EXIST::FUNCTION:
ENGINE_get_static_state 3457 EXIST::FUNCTION: ENGINE_get_static_state 3457 EXIST::FUNCTION:
BN_get0_nist_prime_384 3458 EXIST::FUNCTION:
BN_ncopy 3459 EXIST::FUNCTION:
BN_nist_mod_224 3460 EXIST::FUNCTION:
BN_nist_mod_256 3461 EXIST::FUNCTION:
EC_GFp_nist_method 3462 EXIST::FUNCTION:EC
BN_nist_mod_384 3463 EXIST::FUNCTION:
BN_get0_nist_prime_192 3464 EXIST::FUNCTION:
BN_get0_nist_prime_521 3465 EXIST::FUNCTION:
BN_get0_nist_prime_224 3466 EXIST::FUNCTION:
BN_get0_nist_prime_256 3467 EXIST::FUNCTION:
BN_nist_mod_192 3468 EXIST::FUNCTION:
BN_nist_mod_521 3469 EXIST::FUNCTION: