Simplify |EC_METHOD| by removing invariant methods.

None of these methods vary per group. Factoring these out of
|EC_METHOD| should help some toolchains to do a better job optimizing
the code for size.
This commit is contained in:
Brian Smith 2015-10-07 18:02:01 -10:00
parent dff8a15447
commit 3ed0b17d16
6 changed files with 33 additions and 230 deletions

View File

@ -415,11 +415,7 @@ int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) {
int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; }
unsigned EC_GROUP_get_degree(const EC_GROUP *group) {
if (group->meth->group_get_degree == 0) {
OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
return group->meth->group_get_degree(group);
return ec_GFp_simple_group_get_degree(group);
}
int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) {
@ -455,10 +451,6 @@ EC_POINT *EC_POINT_new(const EC_GROUP *group) {
OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
if (group->meth->point_init == 0) {
OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return NULL;
}
ret = OPENSSL_malloc(sizeof *ret);
if (ret == NULL) {
@ -468,7 +460,7 @@ EC_POINT *EC_POINT_new(const EC_GROUP *group) {
ret->meth = group->meth;
if (!ret->meth->point_init(ret)) {
if (!ec_GFp_simple_point_init(ret)) {
OPENSSL_free(ret);
return NULL;
}
@ -481,9 +473,8 @@ void EC_POINT_free(EC_POINT *point) {
return;
}
if (point->meth->point_finish != 0) {
point->meth->point_finish(point);
}
ec_GFp_simple_point_finish(point);
OPENSSL_free(point);
}
@ -492,20 +483,13 @@ void EC_POINT_clear_free(EC_POINT *point) {
return;
}
if (point->meth->point_clear_finish != 0) {
point->meth->point_clear_finish(point);
} else if (point->meth->point_finish != 0) {
point->meth->point_finish(point);
}
ec_GFp_simple_point_clear_finish(point);
OPENSSL_cleanse(point, sizeof *point);
OPENSSL_free(point);
}
int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) {
if (dest->meth->point_copy == 0) {
OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (dest->meth != src->meth) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
@ -513,7 +497,7 @@ int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) {
if (dest == src) {
return 1;
}
return dest->meth->point_copy(dest, src);
return ec_GFp_simple_point_copy(dest, src);
}
EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
@ -539,70 +523,50 @@ EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
}
int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) {
if (group->meth->point_set_to_infinity == 0) {
OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (group->meth != point->meth) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->point_set_to_infinity(group, point);
return ec_GFp_simple_point_set_to_infinity(group, point);
}
int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
if (group->meth->is_at_infinity == 0) {
OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (group->meth != point->meth) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->is_at_infinity(group, point);
return ec_GFp_simple_is_at_infinity(group, point);
}
int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
BN_CTX *ctx) {
if (group->meth->is_on_curve == 0) {
OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (group->meth != point->meth) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->is_on_curve(group, point, ctx);
return ec_GFp_simple_is_on_curve(group, point, ctx);
}
int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
BN_CTX *ctx) {
if (group->meth->point_cmp == 0) {
OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return -1;
}
if ((group->meth != a->meth) || (a->meth != b->meth)) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return -1;
}
return group->meth->point_cmp(group, a, b, ctx);
return ec_GFp_simple_cmp(group, a, b, ctx);
}
int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
BN_CTX *ctx) {
size_t i;
if (group->meth->points_make_affine == 0) {
OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
for (i = 0; i < num; i++) {
if (group->meth != points[i]->meth) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
}
return group->meth->points_make_affine(group, num, points, ctx);
return ec_GFp_simple_points_make_affine(group, num, points, ctx);
}
int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
@ -622,56 +586,40 @@ int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
const BIGNUM *x, const BIGNUM *y,
BN_CTX *ctx) {
if (group->meth->point_set_affine_coordinates == 0) {
OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (group->meth != point->meth) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
return ec_GFp_simple_point_set_affine_coordinates(group, point, x, y, ctx);
}
int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
const EC_POINT *b, BN_CTX *ctx) {
if (group->meth->add == 0) {
OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if ((group->meth != r->meth) || (r->meth != a->meth) ||
(a->meth != b->meth)) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->add(group, r, a, b, ctx);
return ec_GFp_simple_add(group, r, a, b, ctx);
}
int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
BN_CTX *ctx) {
if (group->meth->dbl == 0) {
OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if ((group->meth != r->meth) || (r->meth != a->meth)) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->dbl(group, r, a, ctx);
return ec_GFp_simple_dbl(group, r, a, ctx);
}
int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) {
if (group->meth->invert == 0) {
OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (group->meth != a->meth) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->invert(group, a, ctx);
return ec_GFp_simple_invert(group, a, ctx);
}
int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
@ -702,14 +650,10 @@ int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
int ec_point_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
const BIGNUM *x, const BIGNUM *y,
const BIGNUM *z, BN_CTX *ctx) {
if (group->meth->point_set_Jprojective_coordinates_GFp == 0) {
OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (group->meth != point->meth) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y,
z, ctx);
return ec_GFp_simple_set_Jprojective_coordinates_GFp(group, point, x, y, z,
ctx);
}

View File

@ -75,36 +75,16 @@
const EC_METHOD *EC_GFp_mont_method(void) {
static const EC_METHOD ret = {EC_FLAGS_DEFAULT_OCT,
ec_GFp_mont_group_init,
static const EC_METHOD ret = {ec_GFp_mont_group_init,
ec_GFp_mont_group_finish,
ec_GFp_mont_group_clear_finish,
ec_GFp_mont_group_set_curve,
ec_GFp_simple_group_get_degree,
ec_GFp_simple_point_init,
ec_GFp_simple_point_finish,
ec_GFp_simple_point_clear_finish,
ec_GFp_simple_point_copy,
ec_GFp_simple_point_set_to_infinity,
ec_GFp_simple_set_Jprojective_coordinates_GFp,
ec_GFp_simple_get_Jprojective_coordinates_GFp,
ec_GFp_simple_point_set_affine_coordinates,
ec_GFp_simple_point_get_affine_coordinates,
0,
0,
ec_GFp_simple_add,
ec_GFp_simple_dbl,
ec_GFp_simple_invert,
ec_GFp_simple_is_at_infinity,
ec_GFp_simple_is_on_curve,
ec_GFp_simple_cmp,
ec_GFp_simple_points_make_affine,
0 /* mul */,
0 /* precompute_mult */,
0 /* have_precompute_mult */,
ec_GFp_mont_field_mul,
ec_GFp_mont_field_sqr,
0 /* field_div */,
ec_GFp_mont_field_encode,
ec_GFp_mont_field_decode,
ec_GFp_mont_field_set_to_one};

View File

@ -78,13 +78,7 @@ extern "C" {
#endif
/* Use default functions for poin2oct, oct2point and compressed coordinates */
#define EC_FLAGS_DEFAULT_OCT 0x1
typedef struct ec_method_st {
/* Various method flags */
int flags;
/* used by EC_GROUP_new, EC_GROUP_free, EC_GROUP_clear_free, EC_GROUP_copy: */
int (*group_init)(EC_GROUP *);
void (*group_finish)(EC_GROUP *);
@ -94,57 +88,10 @@ typedef struct ec_method_st {
int (*group_set_curve)(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
const BIGNUM *b, BN_CTX *);
/* used by EC_GROUP_get_degree: */
unsigned (*group_get_degree)(const EC_GROUP *);
/* used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free, EC_POINT_copy: */
int (*point_init)(EC_POINT *);
void (*point_finish)(EC_POINT *);
void (*point_clear_finish)(EC_POINT *);
int (*point_copy)(EC_POINT *, const EC_POINT *);
/* used by EC_POINT_set_to_infinity,
* EC_POINT_set_Jprojective_coordinates_GFp,
* EC_POINT_get_Jprojective_coordinates_GFp,
* EC_POINT_set_affine_coordinates_GFp, ..._GF2m,
* EC_POINT_get_affine_coordinates_GFp, ..._GF2m,
*/
int (*point_set_to_infinity)(const EC_GROUP *, EC_POINT *);
int (*point_set_Jprojective_coordinates_GFp)(const EC_GROUP *, EC_POINT *,
const BIGNUM *x, const BIGNUM *y,
const BIGNUM *z, BN_CTX *);
int (*point_get_Jprojective_coordinates_GFp)(const EC_GROUP *,
const EC_POINT *, BIGNUM *x,
BIGNUM *y, BIGNUM *z, BN_CTX *);
int (*point_set_affine_coordinates)(const EC_GROUP *, EC_POINT *,
const BIGNUM *x, const BIGNUM *y,
BN_CTX *);
/* used by EC_POINT_get_affine_coordinates_GFp: */
int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *,
BIGNUM *x, BIGNUM *y, BN_CTX *);
/* used by EC_POINT_point2oct, EC_POINT_oct2point: */
size_t (*point2oct)(const EC_GROUP *, const EC_POINT *,
point_conversion_form_t form, unsigned char *buf,
size_t len, BN_CTX *);
int (*oct2point)(const EC_GROUP *, EC_POINT *, const unsigned char *buf,
size_t len, BN_CTX *);
/* used by EC_POINT_add, EC_POINT_dbl, ECP_POINT_invert: */
int (*add)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
const EC_POINT *b, BN_CTX *);
int (*dbl)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
int (*invert)(const EC_GROUP *, EC_POINT *, BN_CTX *);
/* used by EC_POINT_is_at_infinity, EC_POINT_is_on_curve, EC_POINT_cmp: */
int (*is_at_infinity)(const EC_GROUP *, const EC_POINT *);
int (*is_on_curve)(const EC_GROUP *, const EC_POINT *, BN_CTX *);
int (*point_cmp)(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
BN_CTX *);
/* used by EC_POINTs_make_affine: */
int (*points_make_affine)(const EC_GROUP *, size_t num, EC_POINT * [],
BN_CTX *);
/* used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult,
* EC_POINT_have_precompute_mult
* (default implementations are used if the 'mul' pointer is 0): */
@ -157,14 +104,12 @@ typedef struct ec_method_st {
/* internal functions */
/* 'field_mul', 'field_sqr', and 'field_div' can be used by 'add' and 'dbl'
* so that the same implementations of point operations can be used with
* different optimized implementations of expensive field operations: */
/* 'field_mul' and 'field_sqr' can be used by 'add' and 'dbl' so that the
* same implementations of point operations can be used with different
* optimized implementations of expensive field operations: */
int (*field_mul)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
const BIGNUM *b, BN_CTX *);
int (*field_sqr)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
int (*field_div)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
const BIGNUM *b, BN_CTX *);
int (*field_encode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
BN_CTX *); /* e.g. to Montgomery */

View File

@ -262,37 +262,19 @@ err:
int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
const uint8_t *buf, size_t len, BN_CTX *ctx) {
if (group->meth->oct2point == 0 &&
!(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (group->meth != point->meth) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
return ec_GFp_simple_oct2point(group, point, buf, len, ctx);
}
return group->meth->oct2point(group, point, buf, len, ctx);
return ec_GFp_simple_oct2point(group, point, buf, len, ctx);
}
size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point,
point_conversion_form_t form, uint8_t *buf,
size_t len, BN_CTX *ctx) {
if (group->meth->point2oct == 0 &&
!(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (group->meth != point->meth) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
return ec_GFp_simple_point2oct(group, point, form, buf, len, ctx);
}
return group->meth->point2oct(group, point, form, buf, len, ctx);
return ec_GFp_simple_point2oct(group, point, form, buf, len, ctx);
}

View File

@ -1902,27 +1902,19 @@ err:
const EC_METHOD *EC_GFp_nistp256_method(void) {
static const EC_METHOD ret = {
EC_FLAGS_DEFAULT_OCT,
ec_GFp_nistp256_group_init,
ec_GFp_simple_group_finish,
ec_GFp_simple_group_clear_finish,
ec_GFp_nistp256_group_set_curve,
ec_GFp_simple_group_get_degree,
ec_GFp_simple_point_init,
ec_GFp_simple_point_finish, ec_GFp_simple_point_clear_finish,
ec_GFp_simple_point_copy, ec_GFp_simple_point_set_to_infinity,
ec_GFp_simple_set_Jprojective_coordinates_GFp,
ec_GFp_simple_get_Jprojective_coordinates_GFp,
ec_GFp_simple_point_set_affine_coordinates,
ec_GFp_nistp256_point_get_affine_coordinates,
0 /* point2oct */,
0 /* oct2point */, ec_GFp_simple_add, ec_GFp_simple_dbl,
ec_GFp_simple_invert, ec_GFp_simple_is_at_infinity,
ec_GFp_simple_is_on_curve, ec_GFp_simple_cmp,
ec_GFp_simple_points_make_affine, ec_GFp_nistp256_points_mul,
0 /* precompute_mult */, 0 /* have_precompute_mult */,
ec_GFp_simple_field_mul, ec_GFp_simple_field_sqr, 0 /* field_div */,
0 /* field_encode */, 0 /* field_decode */, 0 /* field_set_to_one */
ec_GFp_nistp256_points_mul,
0 /* precompute_mult */,
0 /* have_precompute_mult */,
ec_GFp_simple_field_mul,
ec_GFp_simple_field_sqr,
0 /* field_encode */,
0 /* field_decode */,
0 /* field_set_to_one */,
};
return &ret;

View File

@ -76,46 +76,6 @@
#include "internal.h"
const EC_METHOD *EC_GFp_simple_method(void) {
static const EC_METHOD ret = {EC_FLAGS_DEFAULT_OCT,
ec_GFp_simple_group_init,
ec_GFp_simple_group_finish,
ec_GFp_simple_group_clear_finish,
ec_GFp_simple_group_copy,
ec_GFp_simple_group_set_curve,
ec_GFp_simple_group_get_degree,
ec_GFp_simple_point_init,
ec_GFp_simple_point_finish,
ec_GFp_simple_point_clear_finish,
ec_GFp_simple_point_copy,
ec_GFp_simple_point_set_to_infinity,
ec_GFp_simple_set_Jprojective_coordinates_GFp,
ec_GFp_simple_get_Jprojective_coordinates_GFp,
ec_GFp_simple_point_set_affine_coordinates,
ec_GFp_simple_point_get_affine_coordinates,
0,
0,
ec_GFp_simple_add,
ec_GFp_simple_dbl,
ec_GFp_simple_invert,
ec_GFp_simple_is_at_infinity,
ec_GFp_simple_is_on_curve,
ec_GFp_simple_cmp,
ec_GFp_simple_points_make_affine,
0 /* mul */,
0 /* precompute_mult */,
0 /* have_precompute_mult */,
ec_GFp_simple_field_mul,
ec_GFp_simple_field_sqr,
0 /* field_div */,
0 /* field_encode */,
0 /* field_decode */,
0 /* field_set_to_one */};
return &ret;
}
/* Most method functions in this file are designed to work with non-trivial
* representations of field elements if necessary (see ecp_mont.c): while
* standard modular addition and subtraction are used, the field_mul and