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]
*) 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
dynamically from specific directories unless they could be
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 DSA_NUM 3
#define EC_NUM 15
#define EC_NUM 16
#define MAX_ECDH_SIZE 256
static const char *names[ALGOR_NUM]={
@ -520,20 +520,21 @@ int MAIN(int argc, char **argv)
#define R_RSA_4096 3
#define R_EC_P160 0
#define R_EC_P224 1
#define R_EC_P256 2
#define R_EC_P384 3
#define R_EC_P521 4
#define R_EC_K163 5
#define R_EC_K233 6
#define R_EC_K283 7
#define R_EC_K409 8
#define R_EC_K571 9
#define R_EC_B163 10
#define R_EC_B233 11
#define R_EC_B283 12
#define R_EC_B409 13
#define R_EC_B571 14
#define R_EC_P192 1
#define R_EC_P224 2
#define R_EC_P256 3
#define R_EC_P384 4
#define R_EC_P521 5
#define R_EC_K163 6
#define R_EC_K233 7
#define R_EC_K283 8
#define R_EC_K409 9
#define R_EC_K571 10
#define R_EC_B163 11
#define R_EC_B233 12
#define R_EC_B283 13
#define R_EC_B409 14
#define R_EC_B571 15
#ifndef OPENSSL_NO_RSA
RSA *rsa_key[RSA_NUM];
@ -560,6 +561,7 @@ int MAIN(int argc, char **argv)
{
/* Prime Curves */
NID_secp160r1,
NID_X9_62_prime192v1,
NID_secp224r1,
NID_X9_62_prime256v1,
NID_secp384r1,
@ -580,6 +582,7 @@ int MAIN(int argc, char **argv)
{
/* Prime Curves */
"secp160r1",
"nistp192",
"nistp224",
"nistp256",
"nistp384",
@ -598,7 +601,7 @@ int MAIN(int argc, char **argv)
};
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
};

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 \
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_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 \
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_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)
@ -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/stack.h ../../include/openssl/symhacks.h
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: ../../include/openssl/buffer.h ../../include/openssl/crypto.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_clear_free(BIGNUM *a);
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);
BIGNUM *BN_bin2bn(const unsigned char *s,int len,BIGNUM *ret);
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_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 */
#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_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);

View File

@ -522,6 +522,51 @@ BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
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)
{
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/bn.h ../../include/openssl/crypto.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/opensslv.h ../../include/openssl/ossl_typ.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/bn.h ../../include/openssl/crypto.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/opensslv.h ../../include/openssl/ossl_typ.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_mont_method(void);
const EC_METHOD *EC_GFp_nist_method(void);
#if 0
const EC_METHOD *EC_GFp_recp_method(void); /* TODO */
const EC_METHOD *EC_GFp_nist_method(void); /* TODO */
#endif
/* 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_ECPUBLICKEY_GET_OCTET 151
#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_GROUP2FIELDID 154
#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_MUL 131
#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_SET_CURVE 166
#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_I2D_ECPKPARAMETERS_FAILURE 121
#define EC_R_INCOMPATIBLE_OBJECTS 101
#define EC_R_INTERNAL_ERROR 132
#define EC_R_INVALID_ARGUMENT 112
#define EC_R_INVALID_COMPRESSED_POINT 110
#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_NOT_IMPLEMENTED 126
#define EC_R_NOT_INITIALIZED 111
#define EC_R_NO_FIELD_MOD 133
#define EC_R_NO_SUCH_EXTRA_DATA 105
#define EC_R_PASSED_NULL_PARAMETER 134
#define EC_R_PKPARAMETERS2GROUP_FAILURE 127
#define EC_R_POINT_AT_INFINITY 106
#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_UNDEFINED_GENERATOR 113
#define EC_R_UNDEFINED_ORDER 128

View File

@ -82,6 +82,7 @@
*
*/
#include <openssl/err.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;
EC_GROUP *ret;
/* Finally, this will use EC_GFp_nist_method if 'p' is a special
* prime with optimized modular arithmetics (for NIST curves)
*/
meth = EC_GFp_mont_method();
meth = EC_GFp_nist_method();
ret = EC_GROUP_new(meth);
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))
{
/* remove the last error code form the error queue */
ERR_get_error();
/* try the normal mont method */
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;

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_ECPUBLICKEY_GET_OCTET,0), "ECPUBLICKEY_GET_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_GROUP2FIELDID,0), "EC_ASN1_GROUP2FIELDID"},
{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_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_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_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"},
@ -177,6 +184,7 @@ static ERR_STRING_DATA EC_str_reasons[]=
{EC_R_GROUP2PKPARAMETERS_FAILURE ,"group2pkparameters failure"},
{EC_R_I2D_ECPKPARAMETERS_FAILURE ,"i2d ecpkparameters failure"},
{EC_R_INCOMPATIBLE_OBJECTS ,"incompatible objects"},
{EC_R_INTERNAL_ERROR ,"internal error"},
{EC_R_INVALID_ARGUMENT ,"invalid argument"},
{EC_R_INVALID_COMPRESSED_POINT ,"invalid compressed point"},
{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_NOT_IMPLEMENTED ,"not implemented"},
{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_PASSED_NULL_PARAMETER ,"passed null parameter"},
{EC_R_PKPARAMETERS2GROUP_FAILURE ,"pkparameters2group failure"},
{EC_R_POINT_AT_INFINITY ,"point at infinity"},
{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_UNDEFINED_GENERATOR ,"undefined generator"},
{EC_R_UNDEFINED_ORDER ,"undefined order"},

View File

@ -1,6 +1,9 @@
/* 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
* modification, are permitted provided that the following conditions
@ -58,12 +61,14 @@
* and contributed to the OpenSSL project.
*/
#include <openssl/err.h>
#include <openssl/obj_mac.h>
#include "ec_lcl.h"
#if 0
const EC_METHOD *EC_GFp_nist_method(void)
{
static const EC_METHOD ret = {
NID_X9_62_prime_field,
ec_GFp_nist_group_init,
ec_GFp_nist_group_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_simple_group_get_curve,
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_point_init,
ec_GFp_simple_point_finish,
@ -107,8 +108,13 @@ const EC_METHOD *EC_GFp_nist_method(void)
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)
{
@ -119,26 +125,154 @@ int ec_GFp_nist_group_init(EC_GROUP *group)
return ok;
}
int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
/* TODO */
void ec_GFp_nist_group_finish(EC_GROUP *group)
{
BN_free(&group->field);
BN_free(&group->a);
BN_free(&group->b);
}
void ec_GFp_nist_group_finish(EC_GROUP *group);
/* TODO */
void ec_GFp_nist_group_clear_finish(EC_GROUP *group)
{
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);
/* TODO */
int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
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);
/* TODO */
if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0)
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);
/* TODO */
/* group->a */
(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);
/* TODO */
/* group->a_is_minus3 */
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:
ENGINE_up_ref 3456 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: