ec: 56-bit Limb Solinas' Strategy for secp384r1

Adopt a 56-bit redundant-limb Solinas' reduction approach for efficient
modular multiplication in P384. This has the affect of accelerating
digital signing by 446% and verification by 106%. The implementation
strategy and names of methods are the same as that provided in
ecp_nistp224 and ecp_nistp521.

As in Commit 1036749883 ("ec: Add run time code selection for p521
field operations"), allow for run time selection of implementation for
felem_{square,mul}, where an assembly implementation is proclaimed to
be present when ECP_NISTP384_ASM is present.

Signed-off-by: Rohan McLure <rohanmclure@linux.ibm.com>

Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Todd Short <todd.short@me.com>
(Merged from https://github.com/openssl/openssl/pull/21471)
This commit is contained in:
Rohan McLure 2023-07-12 12:25:22 +10:00 committed by Todd Short
parent 3e47a286dc
commit 01d901e470
5 changed files with 2027 additions and 2 deletions

View File

@ -74,7 +74,7 @@ IF[{- !$disabled{'ecx'} -}]
ENDIF
IF[{- !$disabled{'ec_nistp_64_gcc_128'} -}]
$COMMON=$COMMON ecp_nistp224.c ecp_nistp256.c ecp_nistp521.c ecp_nistputil.c
$COMMON=$COMMON ecp_nistp224.c ecp_nistp256.c ecp_nistp384.c ecp_nistp521.c ecp_nistputil.c
ENDIF
SOURCE[../../libcrypto]=$COMMON ec_ameth.c ec_pmeth.c \

View File

@ -2838,6 +2838,8 @@ static const ec_list_element curve_list[] = {
{NID_secp384r1, &_EC_NIST_PRIME_384.h,
# if defined(S390X_EC_ASM)
EC_GFp_s390x_nistp384_method,
# elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128)
ossl_ec_GFp_nistp384_method,
# else
0,
# endif
@ -2931,6 +2933,8 @@ static const ec_list_element curve_list[] = {
{NID_secp384r1, &_EC_NIST_PRIME_384.h,
# if defined(S390X_EC_ASM)
EC_GFp_s390x_nistp384_method,
# elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128)
ossl_ec_GFp_nistp384_method,
# else
0,
# endif

View File

@ -99,12 +99,16 @@ void EC_pre_comp_free(EC_GROUP *group)
case PCT_nistp256:
EC_nistp256_pre_comp_free(group->pre_comp.nistp256);
break;
case PCT_nistp384:
ossl_ec_nistp384_pre_comp_free(group->pre_comp.nistp384);
break;
case PCT_nistp521:
EC_nistp521_pre_comp_free(group->pre_comp.nistp521);
break;
#else
case PCT_nistp224:
case PCT_nistp256:
case PCT_nistp384:
case PCT_nistp521:
break;
#endif
@ -188,12 +192,16 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
case PCT_nistp256:
dest->pre_comp.nistp256 = EC_nistp256_pre_comp_dup(src->pre_comp.nistp256);
break;
case PCT_nistp384:
dest->pre_comp.nistp384 = ossl_ec_nistp384_pre_comp_dup(src->pre_comp.nistp384);
break;
case PCT_nistp521:
dest->pre_comp.nistp521 = EC_nistp521_pre_comp_dup(src->pre_comp.nistp521);
break;
#else
case PCT_nistp224:
case PCT_nistp256:
case PCT_nistp384:
case PCT_nistp521:
break;
#endif

View File

@ -203,6 +203,7 @@ struct ec_method_st {
*/
typedef struct nistp224_pre_comp_st NISTP224_PRE_COMP;
typedef struct nistp256_pre_comp_st NISTP256_PRE_COMP;
typedef struct nistp384_pre_comp_st NISTP384_PRE_COMP;
typedef struct nistp521_pre_comp_st NISTP521_PRE_COMP;
typedef struct nistz256_pre_comp_st NISTZ256_PRE_COMP;
typedef struct ec_pre_comp_st EC_PRE_COMP;
@ -264,12 +265,13 @@ struct ec_group_st {
*/
enum {
PCT_none,
PCT_nistp224, PCT_nistp256, PCT_nistp521, PCT_nistz256,
PCT_nistp224, PCT_nistp256, PCT_nistp384, PCT_nistp521, PCT_nistz256,
PCT_ec
} pre_comp_type;
union {
NISTP224_PRE_COMP *nistp224;
NISTP256_PRE_COMP *nistp256;
NISTP384_PRE_COMP *nistp384;
NISTP521_PRE_COMP *nistp521;
NISTZ256_PRE_COMP *nistz256;
EC_PRE_COMP *ec;
@ -332,6 +334,7 @@ static ossl_inline int ec_point_is_compat(const EC_POINT *point,
NISTP224_PRE_COMP *EC_nistp224_pre_comp_dup(NISTP224_PRE_COMP *);
NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *);
NISTP384_PRE_COMP *ossl_ec_nistp384_pre_comp_dup(NISTP384_PRE_COMP *);
NISTP521_PRE_COMP *EC_nistp521_pre_comp_dup(NISTP521_PRE_COMP *);
NISTZ256_PRE_COMP *EC_nistz256_pre_comp_dup(NISTZ256_PRE_COMP *);
NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *);
@ -340,6 +343,7 @@ EC_PRE_COMP *EC_ec_pre_comp_dup(EC_PRE_COMP *);
void EC_pre_comp_free(EC_GROUP *group);
void EC_nistp224_pre_comp_free(NISTP224_PRE_COMP *);
void EC_nistp256_pre_comp_free(NISTP256_PRE_COMP *);
void ossl_ec_nistp384_pre_comp_free(NISTP384_PRE_COMP *);
void EC_nistp521_pre_comp_free(NISTP521_PRE_COMP *);
void EC_nistz256_pre_comp_free(NISTZ256_PRE_COMP *);
void EC_ec_pre_comp_free(EC_PRE_COMP *);
@ -551,6 +555,27 @@ int ossl_ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
int ossl_ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
int ossl_ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group);
/* method functions in ecp_nistp384.c */
int ossl_ec_GFp_nistp384_group_init(EC_GROUP *group);
int ossl_ec_GFp_nistp384_group_set_curve(EC_GROUP *group, const BIGNUM *p,
const BIGNUM *a, const BIGNUM *n,
BN_CTX *);
int ossl_ec_GFp_nistp384_point_get_affine_coordinates(const EC_GROUP *group,
const EC_POINT *point,
BIGNUM *x, BIGNUM *y,
BN_CTX *ctx);
int ossl_ec_GFp_nistp384_mul(const EC_GROUP *group, EC_POINT *r,
const BIGNUM *scalar, size_t num,
const EC_POINT *points[], const BIGNUM *scalars[],
BN_CTX *);
int ossl_ec_GFp_nistp384_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 ossl_ec_GFp_nistp384_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
int ossl_ec_GFp_nistp384_have_precompute_mult(const EC_GROUP *group);
const EC_METHOD *ossl_ec_GFp_nistp384_method(void);
/* method functions in ecp_nistp521.c */
int ossl_ec_GFp_nistp521_group_init(EC_GROUP *group);
int ossl_ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p,

1988
crypto/ec/ecp_nistp384.c Normal file

File diff suppressed because it is too large Load Diff