mirror of https://github.com/openssl/openssl.git
				
				
				
			Improve optional 64-bit NIST-P224 implementation, and add NIST-P256 and
NIST-P521. (Now -DEC_NISTP_64_GCC_128 enables all three of these; -DEC_NISTP224_64_GCC_128 no longer works.) Submitted by: Google Inc.
This commit is contained in:
		
							parent
							
								
									7e9cfcd0dc
								
							
						
					
					
						commit
						9c37519b55
					
				
							
								
								
									
										30
									
								
								CHANGES
								
								
								
								
							
							
						
						
									
										30
									
								
								CHANGES
								
								
								
								
							|  | @ -4,6 +4,24 @@ | |||
| 
 | ||||
|  Changes between 1.0.0f and 1.0.1  [xx XXX xxxx] | ||||
| 
 | ||||
|   *) Add optional 64-bit optimized implementations of elliptic curves NIST-P224, | ||||
|      NIST-P256, NIST-P521, with constant-time single point multiplication on | ||||
|      typical inputs. Compiler support for the nonstandard type __uint128_t is | ||||
|      required to use this. Code made available under Apache License version 2.0. | ||||
| 
 | ||||
|      To include this in your build of OpenSSL, use -DEC_NISTP_64_GCC_128 on | ||||
|      the Configure (or config) command line, and run "make depend" (or "make | ||||
|      update"). This enables the following EC_METHODs: | ||||
| 
 | ||||
|          EC_GFp_nistp224_method() | ||||
|          EC_GFp_nistp256_method() | ||||
|          EC_GFp_nistp521_method() | ||||
| 
 | ||||
|      EC_GROUP_new_by_curve_name() will automatically use these (while | ||||
|      EC_GROUP_new_curve_GFp() currently prefers the more flexible | ||||
|      implementations). | ||||
|      [Emilia Käsper, Adam Langley, Bodo Moeller (Google)] | ||||
| 
 | ||||
|   *) Use type ossl_ssize_t instad of ssize_t which isn't available on | ||||
|      all platforms. Move ssize_t definition from e_os.h to the public | ||||
|      header file e_os2.h as it now appears in public header file cms.h | ||||
|  | @ -190,18 +208,6 @@ | |||
|   *) Add functions to copy EVP_PKEY_METHOD and retrieve flags and id. | ||||
|      [Steve Henson] | ||||
| 
 | ||||
|   *) Add EC_GFp_nistp224_method(), a 64-bit optimized implementation for | ||||
|      elliptic curve NIST-P224 with constant-time single point multiplication on | ||||
|      typical inputs.  EC_GROUP_new_by_curve_name() will automatically use this | ||||
|      (while EC_GROUP_new_curve_GFp() currently won't and prefers the more | ||||
|      flexible implementations). | ||||
| 
 | ||||
|      The implementation requires support for the nonstandard type __uint128_t, | ||||
|      and so is disabled by default.  To include this in your build of OpenSSL, | ||||
|      use -DEC_NISTP224_64_GCC_128 on the Configure (or config) command line, | ||||
|      and run "make depend" (or "make update"). | ||||
|      [Emilia Käsper <emilia.kasper@esat.kuleuven.be> (Google)] | ||||
| 
 | ||||
|   *) Permit abbreviated handshakes when renegotiating using the function | ||||
|      SSL_renegotiate_abbreviated(). | ||||
|      [Robin Seggelmann <seggelmann@fh-muenster.de>] | ||||
|  |  | |||
|  | @ -20,12 +20,14 @@ LIB=$(TOP)/libcrypto.a | |||
| LIBSRC=	ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c\
 | ||||
| 	ec_err.c ec_curve.c ec_check.c ec_print.c ec_asn1.c ec_key.c\
 | ||||
| 	ec2_smpl.c ec2_mult.c ec_ameth.c ec_pmeth.c eck_prn.c \
 | ||||
| 	ecp_nistp224.c ecp_oct.c ec2_oct.c ec_oct.c | ||||
| 	ecp_nistp224.c ecp_nistp256.c ecp_nistp521.c ecp_nistputil.c \
 | ||||
| 	ecp_oct.c ec2_oct.c ec_oct.c | ||||
| 
 | ||||
| LIBOBJ=	ec_lib.o ecp_smpl.o ecp_mont.o ecp_nist.o ec_cvt.o ec_mult.o\
 | ||||
| 	ec_err.o ec_curve.o ec_check.o ec_print.o ec_asn1.o ec_key.o\
 | ||||
| 	ec2_smpl.o ec2_mult.o ec_ameth.o ec_pmeth.o eck_prn.o \
 | ||||
| 	ecp_nistp224.o ecp_oct.o ec2_oct.o ec_oct.o | ||||
| 	ecp_nistp224.o ecp_nistp256.o ecp_nistp521.o ecp_nistputil.o \
 | ||||
| 	ecp_oct.o ec2_oct.o ec_oct.o | ||||
| 
 | ||||
| SRC= $(LIBSRC) | ||||
| 
 | ||||
|  | @ -240,6 +242,9 @@ 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/symhacks.h ec_lcl.h ecp_nist.c | ||||
| ecp_nistp224.o: ../../include/openssl/opensslconf.h ecp_nistp224.c | ||||
| ecp_nistp256.o: ../../include/openssl/opensslconf.h ecp_nistp256.c | ||||
| ecp_nistp521.o: ../../include/openssl/opensslconf.h ecp_nistp521.c | ||||
| ecp_nistputil.o: ../../include/openssl/opensslconf.h ecp_nistputil.c | ||||
| ecp_oct.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h | ||||
| ecp_oct.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h | ||||
| ecp_oct.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h | ||||
|  |  | |||
|  | @ -151,11 +151,21 @@ const EC_METHOD *EC_GFp_mont_method(void); | |||
|  */ | ||||
| const EC_METHOD *EC_GFp_nist_method(void); | ||||
| 
 | ||||
| #ifndef OPENSSL_NO_EC_NISTP224_64_GCC_128 | ||||
| #ifdef EC_NISTP_64_GCC_128 | ||||
| /** Returns 64-bit optimized methods for nistp224
 | ||||
|  *  \return  EC_METHOD object | ||||
|  */ | ||||
| const EC_METHOD *EC_GFp_nistp224_method(void); | ||||
| 
 | ||||
| /** Returns 64-bit optimized methods for nistp256
 | ||||
|  *  \return  EC_METHOD object | ||||
|  */ | ||||
| const EC_METHOD *EC_GFp_nistp256_method(void); | ||||
| 
 | ||||
| /** Returns 64-bit optimized methods for nistp521
 | ||||
|  *  \return  EC_METHOD object | ||||
|  */ | ||||
| const EC_METHOD *EC_GFp_nistp521_method(void); | ||||
| #endif | ||||
| 
 | ||||
| #ifndef OPENSSL_NO_EC2M | ||||
|  | @ -1003,6 +1013,12 @@ void ERR_load_EC_strings(void); | |||
| #define EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE		 225 | ||||
| #define EC_F_EC_GFP_NISTP224_POINTS_MUL			 228 | ||||
| #define EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES 226 | ||||
| #define EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE		 230 | ||||
| #define EC_F_EC_GFP_NISTP256_POINTS_MUL			 231 | ||||
| #define EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES 232 | ||||
| #define EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE		 233 | ||||
| #define EC_F_EC_GFP_NISTP521_POINTS_MUL			 234 | ||||
| #define EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES 235 | ||||
| #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		 202 | ||||
|  | @ -1077,6 +1093,8 @@ void ERR_load_EC_strings(void); | |||
| #define EC_F_I2D_ECPRIVATEKEY				 192 | ||||
| #define EC_F_I2O_ECPUBLICKEY				 151 | ||||
| #define EC_F_NISTP224_PRE_COMP_NEW			 227 | ||||
| #define EC_F_NISTP256_PRE_COMP_NEW			 236 | ||||
| #define EC_F_NISTP521_PRE_COMP_NEW			 237 | ||||
| #define EC_F_O2I_ECPUBLICKEY				 152 | ||||
| #define EC_F_OLD_EC_PRIV_DECODE				 222 | ||||
| #define EC_F_PKEY_EC_CTRL				 197 | ||||
|  |  | |||
|  | @ -1841,16 +1841,19 @@ static const ec_list_element curve_list[] = { | |||
| 	/* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */ | ||||
| 	{ NID_secp192k1, &_EC_SECG_PRIME_192K1.h, 0, "SECG curve over a 192 bit prime field" }, | ||||
| 	{ NID_secp224k1, &_EC_SECG_PRIME_224K1.h, 0, "SECG curve over a 224 bit prime field" }, | ||||
| #ifdef EC_NISTP224_64_GCC_128 | ||||
|         { NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method, "NIST/SECG curve over a 224 bit prime field,\n" | ||||
| 	  "\t\t64-bit optimized implementation." }, | ||||
| #ifdef EC_NISTP_64_GCC_128 | ||||
| 	{ NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method, "NIST/SECG curve over a 224 bit prime field" }, | ||||
| #else | ||||
| 	{ NID_secp224r1, &_EC_NIST_PRIME_224.h, 0, "NIST/SECG curve over a 224 bit prime field" }, | ||||
| #endif | ||||
| 	{ NID_secp256k1, &_EC_SECG_PRIME_256K1.h, 0, "SECG curve over a 256 bit prime field" }, | ||||
| 	/* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */ | ||||
| 	{ NID_secp384r1, &_EC_NIST_PRIME_384.h, 0, "NIST/SECG curve over a 384 bit prime field" }, | ||||
| #ifdef EC_NISTP_64_GCC_128 | ||||
| 	{ NID_secp521r1, &_EC_NIST_PRIME_521.h, EC_GFp_nistp521_method, "NIST/SECG curve over a 521 bit prime field" }, | ||||
| #else | ||||
| 	{ NID_secp521r1, &_EC_NIST_PRIME_521.h, 0, "NIST/SECG curve over a 521 bit prime field" }, | ||||
| #endif | ||||
| 	/* X9.62 curves */ | ||||
| 	{ NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0, "NIST/X9.62/SECG curve over a 192 bit prime field" }, | ||||
| 	{ NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2.h, 0, "X9.62 curve over a 192 bit prime field" }, | ||||
|  | @ -1858,7 +1861,11 @@ static const ec_list_element curve_list[] = { | |||
| 	{ NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1.h, 0, "X9.62 curve over a 239 bit prime field" }, | ||||
| 	{ NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, 0, "X9.62 curve over a 239 bit prime field" }, | ||||
| 	{ NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, 0, "X9.62 curve over a 239 bit prime field" }, | ||||
| #ifdef EC_NISTP_64_GCC_128 | ||||
| 	{ NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, EC_GFp_nistp256_method, "X9.62/SECG curve over a 256 bit prime field" }, | ||||
| #else | ||||
| 	{ NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, 0, "X9.62/SECG curve over a 256 bit prime field" }, | ||||
| #endif | ||||
| #ifndef OPENSSL_NO_EC2M | ||||
| 	/* characteristic two field curves */ | ||||
| 	/* NIST/SECG curves */ | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| /* crypto/ec/ec_err.c */ | ||||
| /* ====================================================================
 | ||||
|  * Copyright (c) 1999-2010 The OpenSSL Project.  All rights reserved. | ||||
|  * Copyright (c) 1999-2011 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 | ||||
|  | @ -116,6 +116,12 @@ static ERR_STRING_DATA EC_str_functs[]= | |||
| {ERR_FUNC(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE),	"ec_GFp_nistp224_group_set_curve"}, | ||||
| {ERR_FUNC(EC_F_EC_GFP_NISTP224_POINTS_MUL),	"ec_GFp_nistp224_points_mul"}, | ||||
| {ERR_FUNC(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES),	"ec_GFp_nistp224_point_get_affine_coordinates"}, | ||||
| {ERR_FUNC(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE),	"ec_GFp_nistp256_group_set_curve"}, | ||||
| {ERR_FUNC(EC_F_EC_GFP_NISTP256_POINTS_MUL),	"ec_GFp_nistp256_points_mul"}, | ||||
| {ERR_FUNC(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES),	"ec_GFp_nistp256_point_get_affine_coordinates"}, | ||||
| {ERR_FUNC(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE),	"ec_GFp_nistp521_group_set_curve"}, | ||||
| {ERR_FUNC(EC_F_EC_GFP_NISTP521_POINTS_MUL),	"ec_GFp_nistp521_points_mul"}, | ||||
| {ERR_FUNC(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES),	"ec_GFp_nistp521_point_get_affine_coordinates"}, | ||||
| {ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_MUL),	"ec_GFp_nist_field_mul"}, | ||||
| {ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_SQR),	"ec_GFp_nist_field_sqr"}, | ||||
| {ERR_FUNC(EC_F_EC_GFP_NIST_GROUP_SET_CURVE),	"ec_GFp_nist_group_set_curve"}, | ||||
|  | @ -190,6 +196,8 @@ static ERR_STRING_DATA EC_str_functs[]= | |||
| {ERR_FUNC(EC_F_I2D_ECPRIVATEKEY),	"i2d_ECPrivateKey"}, | ||||
| {ERR_FUNC(EC_F_I2O_ECPUBLICKEY),	"i2o_ECPublicKey"}, | ||||
| {ERR_FUNC(EC_F_NISTP224_PRE_COMP_NEW),	"NISTP224_PRE_COMP_NEW"}, | ||||
| {ERR_FUNC(EC_F_NISTP256_PRE_COMP_NEW),	"NISTP256_PRE_COMP_NEW"}, | ||||
| {ERR_FUNC(EC_F_NISTP521_PRE_COMP_NEW),	"NISTP521_PRE_COMP_NEW"}, | ||||
| {ERR_FUNC(EC_F_O2I_ECPUBLICKEY),	"o2i_ECPublicKey"}, | ||||
| {ERR_FUNC(EC_F_OLD_EC_PRIV_DECODE),	"OLD_EC_PRIV_DECODE"}, | ||||
| {ERR_FUNC(EC_F_PKEY_EC_CTRL),	"PKEY_EC_CTRL"}, | ||||
|  |  | |||
|  | @ -398,15 +398,49 @@ int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, | |||
| int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx); | ||||
| int ec_GF2m_have_precompute_mult(const EC_GROUP *group); | ||||
| 
 | ||||
| #ifdef EC_NISTP224_64_GCC_128 | ||||
| #ifdef EC_NISTP_64_GCC_128 | ||||
| /* method functions in ec2_mult.c */ | ||||
| int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, | ||||
| 	size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *); | ||||
| int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx); | ||||
| int ec_GF2m_have_precompute_mult(const EC_GROUP *group); | ||||
| 
 | ||||
| /* method functions in ecp_nistp224.c */ | ||||
| int ec_GFp_nistp224_group_init(EC_GROUP *group); | ||||
| int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p, | ||||
| 	const BIGNUM *a, const BIGNUM *n, BN_CTX *); | ||||
| int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group, | ||||
| 	const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx); | ||||
| int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, | ||||
| 	size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *); | ||||
| int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *n, BN_CTX *); | ||||
| int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx); | ||||
| int ec_GFp_nistp224_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *); | ||||
| int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx); | ||||
| int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx); | ||||
| int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group); | ||||
| 
 | ||||
| /* method functions in ecp_nistp256.c */ | ||||
| int ec_GFp_nistp256_group_init(EC_GROUP *group); | ||||
| int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *n, BN_CTX *); | ||||
| int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx); | ||||
| int ec_GFp_nistp256_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *); | ||||
| int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx); | ||||
| int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx); | ||||
| int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group); | ||||
| 
 | ||||
| /* method functions in ecp_nistp521.c */ | ||||
| int ec_GFp_nistp521_group_init(EC_GROUP *group); | ||||
| int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *n, BN_CTX *); | ||||
| int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx); | ||||
| int ec_GFp_nistp521_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *); | ||||
| int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx); | ||||
| int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx); | ||||
| int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group); | ||||
| 
 | ||||
| /* utility functions in ecp_nistputil.c */ | ||||
| void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array, | ||||
| 	size_t felem_size, void *tmp_felems, | ||||
| 	void (*felem_one)(void *out), | ||||
| 	int (*felem_is_zero)(const void *in), | ||||
| 	void (*felem_assign)(void *out, const void *in), | ||||
| 	void (*felem_square)(void *out, const void *in), | ||||
| 	void (*felem_mul)(void *out, const void *in1, const void *in2), | ||||
| 	void (*felem_inv)(void *out, const void *in), | ||||
| 	void (*felem_contract)(void *out, const void *in)); | ||||
| void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, unsigned char *digit, unsigned char in); | ||||
| #endif | ||||
|  |  | |||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -0,0 +1,196 @@ | |||
| /* crypto/ec/ecp_nistputil.c */ | ||||
| /*
 | ||||
|  * Written by Bodo Moeller for the OpenSSL project. | ||||
|  */ | ||||
| /* Copyright 2011 Google Inc.
 | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0
 | ||||
|  * | ||||
|  *  Unless required by applicable law or agreed to in writing, software | ||||
|  *  distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  *  See the License for the specific language governing permissions and | ||||
|  *  limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| #ifdef EC_NISTP_64_GCC_128 | ||||
| 
 | ||||
| /*
 | ||||
|  * Common utility functions for ecp_nistp224.c, ecp_nistp256.c, ecp_nistp521.c. | ||||
|  */ | ||||
| 
 | ||||
| #include <stddef.h> | ||||
| #include "ec_lcl.h" | ||||
| 
 | ||||
| /* Convert an array of points into affine coordinates.
 | ||||
|  * (If the point at infinity is found (Z = 0), it remains unchanged.) | ||||
|  * This function is essentially an equivalent to EC_POINTs_make_affine(), but | ||||
|  * works with the internal representation of points as used by ecp_nistp###.c | ||||
|  * rather than with (BIGNUM-based) EC_POINT data structures. | ||||
|  * | ||||
|  * point_array is the input/output buffer ('num' points in projective form, | ||||
|  * i.e. three coordinates each), based on an internal representation of | ||||
|  * field elements of size 'felem_size'. | ||||
|  * | ||||
|  * tmp_felems needs to point to a temporary array of 'num'+1 field elements | ||||
|  * for storage of intermediate values. | ||||
|  */ | ||||
| void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array, | ||||
| 	size_t felem_size, void *tmp_felems, | ||||
| 	void (*felem_one)(void *out), | ||||
| 	int (*felem_is_zero)(const void *in), | ||||
| 	void (*felem_assign)(void *out, const void *in), | ||||
| 	void (*felem_square)(void *out, const void *in), | ||||
| 	void (*felem_mul)(void *out, const void *in1, const void *in2), | ||||
| 	void (*felem_inv)(void *out, const void *in), | ||||
| 	void (*felem_contract)(void *out, const void *in)) | ||||
| 	{ | ||||
| 	int i = 0; | ||||
| 
 | ||||
| #define tmp_felem(I) (&((char *)tmp_felems)[(I) * felem_size]) | ||||
| #define X(I) (&((char *)point_array)[3*(I) * felem_size]) | ||||
| #define Y(I) (&((char *)point_array)[(3*(I) + 1) * felem_size]) | ||||
| #define Z(I) (&((char *)point_array)[(3*(I) + 2) * felem_size]) | ||||
| 
 | ||||
| 	if (!felem_is_zero(Z(0))) | ||||
| 		felem_assign(tmp_felem(0), Z(0)); | ||||
| 	else | ||||
| 		felem_one(tmp_felem(0)); | ||||
| 	for (i = 1; i < (int)num; i++) | ||||
| 		{ | ||||
| 		if (!felem_is_zero(Z(i))) | ||||
| 			felem_mul(tmp_felem(i), tmp_felem(i-1), Z(i)); | ||||
| 		else | ||||
| 			felem_assign(tmp_felem(i), tmp_felem(i-1)); | ||||
| 		} | ||||
| 	/* Now each tmp_felem(i) is the product of Z(0) .. Z(i), skipping any zero-valued factors:
 | ||||
| 	 * if Z(i) = 0, we essentially pretend that Z(i) = 1 */ | ||||
| 
 | ||||
| 	felem_inv(tmp_felem(num-1), tmp_felem(num-1)); | ||||
| 	for (i = num - 1; i >= 0; i--) | ||||
| 		{ | ||||
| 		if (i > 0) | ||||
| 			/* tmp_felem(i-1) is the product of Z(0) .. Z(i-1),
 | ||||
| 			 * tmp_felem(i) is the inverse of the product of Z(0) .. Z(i) | ||||
| 			 */ | ||||
| 			felem_mul(tmp_felem(num), tmp_felem(i-1), tmp_felem(i)); /* 1/Z(i) */ | ||||
| 		else | ||||
| 			felem_assign(tmp_felem(num), tmp_felem(0)); /* 1/Z(0) */ | ||||
| 
 | ||||
| 		if (!felem_is_zero(Z(i))) | ||||
| 			{ | ||||
| 			if (i > 0) | ||||
| 				/* For next iteration, replace tmp_felem(i-1) by its inverse */ | ||||
| 				felem_mul(tmp_felem(i-1), tmp_felem(i), Z(i)); | ||||
| 
 | ||||
| 			/* Convert point (X, Y, Z) into affine form (X/(Z^2), Y/(Z^3), 1) */ | ||||
| 			felem_square(Z(i), tmp_felem(num)); /* 1/(Z^2) */ | ||||
| 			felem_mul(X(i), X(i), Z(i)); /* X/(Z^2) */ | ||||
| 			felem_mul(Z(i), Z(i), tmp_felem(num)); /* 1/(Z^3) */ | ||||
| 			felem_mul(Y(i), Y(i), Z(i)); /* Y/(Z^3) */ | ||||
| 			felem_contract(X(i), X(i)); | ||||
| 			felem_contract(Y(i), Y(i)); | ||||
| 			felem_one(Z(i)); | ||||
| 			} | ||||
| 		else | ||||
| 			{ | ||||
| 			if (i > 0) | ||||
| 				/* For next iteration, replace tmp_felem(i-1) by its inverse */ | ||||
| 				felem_assign(tmp_felem(i-1), tmp_felem(i)); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| /*
 | ||||
|  * This function looks at 5+1 scalar bits (5 current, 1 adjacent less | ||||
|  * significant bit), and recodes them into a signed digit for use in fast point | ||||
|  * multiplication: the use of signed rather than unsigned digits means that | ||||
|  * fewer points need to be precomputed, given that point inversion is easy | ||||
|  * (a precomputed point dP makes -dP available as well). | ||||
|  * | ||||
|  * BACKGROUND: | ||||
|  * | ||||
|  * Signed digits for multiplication were introduced by Booth ("A signed binary | ||||
|  * multiplication technique", Quart. Journ. Mech. and Applied Math., vol. IV, | ||||
|  * pt. 2 (1951), pp. 236-240), in that case for multiplication of integers. | ||||
|  * Booth's original encoding did not generally improve the density of nonzero | ||||
|  * digits over the binary representation, and was merely meant to simplify the | ||||
|  * handling of signed factors given in two's complement; but it has since been | ||||
|  * shown to be the basis of various signed-digit representations that do have | ||||
|  * further advantages, including the wNAF, using the following general approach: | ||||
|  * | ||||
|  * (1) Given a binary representation | ||||
|  * | ||||
|  *       b_k  ...  b_2  b_1  b_0, | ||||
|  * | ||||
|  *     of a nonnegative integer (b_k in {0, 1}), rewrite it in digits 0, 1, -1 | ||||
|  *     by using bit-wise subtraction as follows: | ||||
|  * | ||||
|  *        b_k b_(k-1)  ...  b_2  b_1  b_0 | ||||
|  *      -     b_k      ...  b_3  b_2  b_1  b_0 | ||||
|  *       ------------------------------------- | ||||
|  *        s_k b_(k-1)  ...  s_3  s_2  s_1  s_0 | ||||
|  * | ||||
|  *     A left-shift followed by subtraction of the original value yields a new | ||||
|  *     representation of the same value, using signed bits s_i = b_(i+1) - b_i. | ||||
|  *     This representation from Booth's paper has since appeared in the | ||||
|  *     literature under a variety of different names including "reversed binary | ||||
|  *     form", "alternating greedy expansion", "mutual opposite form", and | ||||
|  *     "sign-alternating {+-1}-representation". | ||||
|  * | ||||
|  *     An interesting property is that among the nonzero bits, values 1 and -1 | ||||
|  *     strictly alternate. | ||||
|  * | ||||
|  * (2) Various window schemes can be applied to the Booth representation of | ||||
|  *     integers: for example, right-to-left sliding windows yield the wNAF | ||||
|  *     (a signed-digit encoding independently discovered by various researchers | ||||
|  *     in the 1990s), and left-to-right sliding windows yield a left-to-right | ||||
|  *     equivalent of the wNAF (independently discovered by various researchers | ||||
|  *     around 2004). | ||||
|  * | ||||
|  * To prevent leaking information through side channels in point multiplication, | ||||
|  * we need to recode the given integer into a regular pattern: sliding windows | ||||
|  * as in wNAFs won't do, we need their fixed-window equivalent -- which is a few | ||||
|  * decades older: we'll be using the so-called "modified Booth encoding" due to | ||||
|  * MacSorley ("High-speed arithmetic in binary computers", Proc. IRE, vol. 49 | ||||
|  * (1961), pp. 67-91), in a radix-2^5 setting.  That is, we always combine five | ||||
|  * signed bits into a signed digit: | ||||
|  * | ||||
|  *       s_(4j + 4) s_(4j + 3) s_(4j + 2) s_(4j + 1) s_(4j) | ||||
|  * | ||||
|  * The sign-alternating property implies that the resulting digit values are | ||||
|  * integers from -16 to 16. | ||||
|  * | ||||
|  * Of course, we don't actually need to compute the signed digits s_i as an | ||||
|  * intermediate step (that's just a nice way to see how this scheme relates | ||||
|  * to the wNAF): a direct computation obtains the recoded digit from the | ||||
|  * six bits b_(4j + 4) ... b_(4j - 1). | ||||
|  * | ||||
|  * This function takes those five bits as an integer (0 .. 63), writing the | ||||
|  * recoded digit to *sign (0 for positive, 1 for negative) and *digit (absolute | ||||
|  * value, in the range 0 .. 8).  Note that this integer essentially provides the | ||||
|  * input bits "shifted to the left" by one position: for example, the input to | ||||
|  * compute the least significant recoded digit, given that there's no bit b_-1, | ||||
|  * has to be b_4 b_3 b_2 b_1 b_0 0. | ||||
|  * | ||||
|  */ | ||||
| void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, unsigned char *digit, unsigned char in) | ||||
| 	{ | ||||
| 	unsigned char s, d; | ||||
| 
 | ||||
| 	s = ~((in >> 5) - 1); /* sets all bits to MSB(in), 'in' seen as 6-bit value */ | ||||
| 	d = (1 << 6) - in - 1; | ||||
| 	d = (d & s) | (in & ~s); | ||||
| 	d = (d >> 1) + (d & 1); | ||||
| 
 | ||||
| 	*sign = s & 1; | ||||
| 	*digit = d; | ||||
| 	} | ||||
| #else | ||||
| static void *dummy=&dummy; | ||||
| #endif | ||||
|  | @ -234,7 +234,7 @@ static void group_order_tests(EC_GROUP *group) | |||
| 	BN_CTX_free(ctx); | ||||
| 	} | ||||
| 
 | ||||
| static void prime_field_tests() | ||||
| static void prime_field_tests(void) | ||||
| 	{	 | ||||
| 	BN_CTX *ctx = NULL; | ||||
| 	BIGNUM *p, *a, *b; | ||||
|  | @ -778,7 +778,7 @@ static void prime_field_tests() | |||
| 
 | ||||
| #ifndef OPENSSL_NO_EC2M | ||||
| 
 | ||||
| static void char2_field_tests() | ||||
| static void char2_field_tests(void) | ||||
| 	{ | ||||
| 	BN_CTX *ctx = NULL; | ||||
| 	BIGNUM *p, *a, *b; | ||||
|  | @ -1262,15 +1262,76 @@ static void internal_curve_test(void) | |||
| 	if (ok) | ||||
| 		fprintf(stdout, " ok\n\n"); | ||||
| 	else | ||||
| 		{ | ||||
| 		fprintf(stdout, " failed\n\n"); | ||||
| 		ABORT; | ||||
| 		} | ||||
| 	OPENSSL_free(curves); | ||||
| 	return; | ||||
| 	} | ||||
| 
 | ||||
| #ifdef EC_NISTP224_64_GCC_128 | ||||
| void nistp224_test() | ||||
| #ifdef EC_NISTP_64_GCC_128 | ||||
| /* nistp_test_params contains magic numbers for testing our optimized
 | ||||
|  * implementations of several NIST curves with characteristic > 3. */ | ||||
| struct nistp_test_params | ||||
| 	{ | ||||
| 	fprintf(stdout, "\nNIST curve P-224 (optimised implementation):\n"); | ||||
| 	const EC_METHOD* (*meth) (); | ||||
| 	int degree; | ||||
| 	/* Qx, Qy and D are taken from
 | ||||
| 	 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf
 | ||||
| 	 * Otherwise, values are standard curve parameters from FIPS 180-3 */ | ||||
| 	const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d; | ||||
| 	}; | ||||
| 
 | ||||
| static const struct nistp_test_params nistp_tests_params[] = | ||||
| 	{ | ||||
| 		{ | ||||
| 		/* P-224 */ | ||||
| 		EC_GFp_nistp224_method, | ||||
| 		224, | ||||
| 		"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* p */ | ||||
| 		"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* a */ | ||||
| 		"B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", /* b */ | ||||
| 		"E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E", /* Qx */ | ||||
| 		"4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555", /* Qy */ | ||||
| 		"B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", /* Gx */ | ||||
| 		"BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", /* Gy */ | ||||
| 		"FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* order */ | ||||
| 		"3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8", /* d */ | ||||
| 		}, | ||||
| 		{ | ||||
| 		/* P-256 */ | ||||
| 		EC_GFp_nistp256_method, | ||||
| 		256, | ||||
| 		"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", /* p */ | ||||
| 		"ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", /* a */ | ||||
| 		"5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", /* b */ | ||||
| 		"b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19", /* Qx */ | ||||
| 		"3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09", /* Qy */ | ||||
| 		"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", /* Gx */ | ||||
| 		"4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", /* Gy */ | ||||
| 		"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", /* order */ | ||||
| 		"c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96", /* d */ | ||||
| 		}, | ||||
| 		{ | ||||
| 		/* P-521 */ | ||||
| 		EC_GFp_nistp521_method, | ||||
| 		521, | ||||
| 		"1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", /* p */ | ||||
| 		"1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc", /* a */ | ||||
| 		"051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", /* b */ | ||||
| 		"0098e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4", /* Qx */ | ||||
| 		"0164350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e", /* Qy */ | ||||
| 		"c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", /* Gx */ | ||||
| 		"11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", /* Gy */ | ||||
| 		"1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", /* order */ | ||||
| 		"0100085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eeedf09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722", /* d */ | ||||
| 		}, | ||||
| 	}; | ||||
| 
 | ||||
| void nistp_single_test(const struct nistp_test_params *test) | ||||
| 	{ | ||||
| 	fprintf(stdout, "\nNIST curve P-%d (optimised implementation):\n", test->degree); | ||||
| 	BIGNUM *p, *a, *b, *x, *y, *n, *m, *order; | ||||
| 	p = BN_new(); | ||||
| 	a = BN_new(); | ||||
|  | @ -1278,82 +1339,82 @@ void nistp224_test() | |||
| 	x = BN_new(); y = BN_new(); | ||||
| 	m = BN_new(); n = BN_new(); order = BN_new(); | ||||
| 	BN_CTX *ctx = BN_CTX_new(); | ||||
| 	EC_GROUP *NISTP224; | ||||
| 	EC_GROUP *NISTP; | ||||
| 	EC_POINT *G, *P, *Q, *Q_CHECK; | ||||
| 
 | ||||
| 	NISTP224 = EC_GROUP_new(EC_GFp_nistp224_method()); | ||||
| 	if(!NISTP224) ABORT; | ||||
| 	if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001")) ABORT; | ||||
| 	NISTP = EC_GROUP_new(test->meth()); | ||||
| 	if(!NISTP) ABORT; | ||||
| 	if (!BN_hex2bn(&p, test->p)) ABORT; | ||||
| 	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT; | ||||
| 	if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")) ABORT; | ||||
| 	if (!BN_hex2bn(&b, "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4")) ABORT; | ||||
| 	if (!EC_GROUP_set_curve_GFp(NISTP224, p, a, b, ctx)) ABORT; | ||||
| 	G = EC_POINT_new(NISTP224); | ||||
| 	P = EC_POINT_new(NISTP224); | ||||
| 	Q = EC_POINT_new(NISTP224); | ||||
| 	Q_CHECK = EC_POINT_new(NISTP224); | ||||
| 	if(!BN_hex2bn(&x, "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E")) ABORT; | ||||
| 	if(!BN_hex2bn(&y, "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555")) ABORT; | ||||
| 	if(!EC_POINT_set_affine_coordinates_GFp(NISTP224, Q_CHECK, x, y, ctx)) ABORT; | ||||
| 	if (!BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21")) ABORT; | ||||
| 	if (!BN_hex2bn(&y, "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34")) ABORT; | ||||
| 	if (!EC_POINT_set_affine_coordinates_GFp(NISTP224, G, x, y, ctx)) ABORT; | ||||
| 	if (!BN_hex2bn(&order, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")) ABORT; | ||||
| 	if (!EC_GROUP_set_generator(NISTP224, G, order, BN_value_one())) ABORT; | ||||
| 	if (!BN_hex2bn(&a, test->a)) ABORT; | ||||
| 	if (!BN_hex2bn(&b, test->b)) ABORT; | ||||
| 	if (!EC_GROUP_set_curve_GFp(NISTP, p, a, b, ctx)) ABORT; | ||||
| 	G = EC_POINT_new(NISTP); | ||||
| 	P = EC_POINT_new(NISTP); | ||||
| 	Q = EC_POINT_new(NISTP); | ||||
| 	Q_CHECK = EC_POINT_new(NISTP); | ||||
| 	if(!BN_hex2bn(&x, test->Qx)) ABORT; | ||||
| 	if(!BN_hex2bn(&y, test->Qy)) ABORT; | ||||
| 	if(!EC_POINT_set_affine_coordinates_GFp(NISTP, Q_CHECK, x, y, ctx)) ABORT; | ||||
| 	if (!BN_hex2bn(&x, test->Gx)) ABORT; | ||||
| 	if (!BN_hex2bn(&y, test->Gy)) ABORT; | ||||
| 	if (!EC_POINT_set_affine_coordinates_GFp(NISTP, G, x, y, ctx)) ABORT; | ||||
| 	if (!BN_hex2bn(&order, test->order)) ABORT; | ||||
| 	if (!EC_GROUP_set_generator(NISTP, G, order, BN_value_one())) ABORT; | ||||
| 
 | ||||
| 	fprintf(stdout, "verify degree ... "); | ||||
| 	if (EC_GROUP_get_degree(NISTP224) != 224) ABORT; | ||||
| 	if (EC_GROUP_get_degree(NISTP) != test->degree) ABORT; | ||||
| 	fprintf(stdout, "ok\n"); | ||||
| 
 | ||||
| 	fprintf(stdout, "NIST test vectors ... "); | ||||
| 	if (!BN_hex2bn(&n, "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8")) ABORT; | ||||
| 	if (!BN_hex2bn(&n, test->d)) ABORT; | ||||
| 	/* fixed point multiplication */ | ||||
| 	EC_POINT_mul(NISTP224, Q, n, NULL, NULL, ctx); | ||||
| 	if (0 != EC_POINT_cmp(NISTP224, Q, Q_CHECK, ctx)) ABORT; | ||||
| 	EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx); | ||||
| 	if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT; | ||||
| 	/* random point multiplication */ | ||||
| 	EC_POINT_mul(NISTP224, Q, NULL, G, n, ctx); | ||||
| 	if (0 != EC_POINT_cmp(NISTP224, Q, Q_CHECK, ctx)) ABORT; | ||||
| 	EC_POINT_mul(NISTP, Q, NULL, G, n, ctx); | ||||
| 	if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT; | ||||
| 
 | ||||
| 	/* set generator to P = 2*G, where G is the standard generator */ | ||||
| 	if (!EC_POINT_dbl(NISTP224, P, G, ctx)) ABORT; | ||||
| 	if (!EC_GROUP_set_generator(NISTP224, P, order, BN_value_one())) ABORT; | ||||
| 	if (!EC_POINT_dbl(NISTP, P, G, ctx)) ABORT; | ||||
| 	if (!EC_GROUP_set_generator(NISTP, P, order, BN_value_one())) ABORT; | ||||
| 	/* set the scalar to m=n/2, where n is the NIST test scalar */ | ||||
| 	if (!BN_rshift(m, n, 1)) ABORT; | ||||
| 
 | ||||
| 	/* test the non-standard generator */ | ||||
| 	/* fixed point multiplication */ | ||||
| 	EC_POINT_mul(NISTP224, Q, m, NULL, NULL, ctx); | ||||
| 	if (0 != EC_POINT_cmp(NISTP224, Q, Q_CHECK, ctx)) ABORT; | ||||
| 	EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx); | ||||
| 	if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT; | ||||
| 	/* random point multiplication */ | ||||
| 	EC_POINT_mul(NISTP224, Q, NULL, P, m, ctx); | ||||
| 	if (0 != EC_POINT_cmp(NISTP224, Q, Q_CHECK, ctx)) ABORT; | ||||
| 	EC_POINT_mul(NISTP, Q, NULL, P, m, ctx); | ||||
| 	if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT; | ||||
| 
 | ||||
| 	/* now repeat all tests with precomputation */ | ||||
| 	if (!EC_GROUP_precompute_mult(NISTP224, ctx)) ABORT; | ||||
| 	if (!EC_GROUP_precompute_mult(NISTP, ctx)) ABORT; | ||||
| 
 | ||||
| 	/* fixed point multiplication */ | ||||
| 	EC_POINT_mul(NISTP224, Q, m, NULL, NULL, ctx); | ||||
| 	if (0 != EC_POINT_cmp(NISTP224, Q, Q_CHECK, ctx)) ABORT; | ||||
| 	EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx); | ||||
| 	if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT; | ||||
| 	/* random point multiplication */ | ||||
| 	EC_POINT_mul(NISTP224, Q, NULL, P, m, ctx); | ||||
| 	if (0 != EC_POINT_cmp(NISTP224, Q, Q_CHECK, ctx)) ABORT; | ||||
| 	EC_POINT_mul(NISTP, Q, NULL, P, m, ctx); | ||||
| 	if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT; | ||||
| 
 | ||||
| 	/* reset generator */ | ||||
| 	if (!EC_GROUP_set_generator(NISTP224, G, order, BN_value_one())) ABORT; | ||||
| 	if (!EC_GROUP_set_generator(NISTP, G, order, BN_value_one())) ABORT; | ||||
| 	/* fixed point multiplication */ | ||||
| 	EC_POINT_mul(NISTP224, Q, n, NULL, NULL, ctx); | ||||
| 	if (0 != EC_POINT_cmp(NISTP224, Q, Q_CHECK, ctx)) ABORT; | ||||
| 	EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx); | ||||
| 	if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT; | ||||
| 	/* random point multiplication */ | ||||
| 	EC_POINT_mul(NISTP224, Q, NULL, G, n, ctx); | ||||
| 	if (0 != EC_POINT_cmp(NISTP224, Q, Q_CHECK, ctx)) ABORT; | ||||
| 	EC_POINT_mul(NISTP, Q, NULL, G, n, ctx); | ||||
| 	if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT; | ||||
| 
 | ||||
| 	fprintf(stdout, "ok\n"); | ||||
| 	group_order_tests(NISTP224); | ||||
| 	group_order_tests(NISTP); | ||||
| #if 0 | ||||
| 	timings(NISTP224, TIMING_BASE_PT, ctx); | ||||
| 	timings(NISTP224, TIMING_RAND_PT, ctx); | ||||
| 	timings(NISTP, TIMING_BASE_PT, ctx); | ||||
| 	timings(NISTP, TIMING_RAND_PT, ctx); | ||||
| #endif | ||||
| 	EC_GROUP_free(NISTP224); | ||||
| 	EC_GROUP_free(NISTP); | ||||
| 	EC_POINT_free(G); | ||||
| 	EC_POINT_free(P); | ||||
| 	EC_POINT_free(Q); | ||||
|  | @ -1368,6 +1429,16 @@ void nistp224_test() | |||
| 	BN_free(order); | ||||
| 	BN_CTX_free(ctx); | ||||
| 	} | ||||
| 
 | ||||
| void nistp_tests() | ||||
| 	{ | ||||
| 	unsigned i; | ||||
| 
 | ||||
| 	for (i = 0; i < sizeof(nistp_tests_params) / sizeof(struct nistp_test_params); i++) | ||||
| 		{ | ||||
| 		nistp_single_test(&nistp_tests_params[i]); | ||||
| 		} | ||||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| static const char rnd_seed[] = "string to make the random number generator think it has entropy"; | ||||
|  | @ -1396,8 +1467,8 @@ int main(int argc, char *argv[]) | |||
| #ifndef OPENSSL_NO_EC2M | ||||
| 	char2_field_tests(); | ||||
| #endif | ||||
| #ifdef EC_NISTP224_64_GCC_128 | ||||
| 	nistp224_test(); | ||||
| #ifdef EC_NISTP_64_GCC_128 | ||||
| 	nistp_tests(); | ||||
| #endif | ||||
| 	/* test the internal curves */ | ||||
| 	internal_curve_test(); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue