diff options
Diffstat (limited to 'crypto/ec')
-rw-r--r-- | crypto/ec/ec.h | 15 | ||||
-rw-r--r-- | crypto/ec/ec_err.c | 6 | ||||
-rw-r--r-- | crypto/ec/ec_lcl.h | 34 | ||||
-rw-r--r-- | crypto/ec/ec_lib.c | 84 | ||||
-rw-r--r-- | crypto/ec/ecp_mont.c | 6 | ||||
-rw-r--r-- | crypto/ec/ecp_nist.c | 6 | ||||
-rw-r--r-- | crypto/ec/ecp_recp.c | 6 | ||||
-rw-r--r-- | crypto/ec/ecp_smpl.c | 81 |
8 files changed, 215 insertions, 23 deletions
diff --git a/crypto/ec/ec.h b/crypto/ec/ec.h index db410c1e81..1b50a9684a 100644 --- a/crypto/ec/ec.h +++ b/crypto/ec/ec.h @@ -122,11 +122,16 @@ void EC_POINT_clear_free(EC_POINT *); int EC_POINT_copy(EC_POINT *, const EC_POINT *); int EC_POINT_set_to_infinity(const EC_GROUP *, EC_POINT *); +int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *, EC_POINT *, + const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *); +int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *, const EC_POINT *, + BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *); int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *, EC_POINT *, const BIGNUM *x, const BIGNUM *y, BN_CTX *); int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *, const EC_POINT *, BIGNUM *x, BIGNUM *y, BN_CTX *); -/* TODO: other 'set' and 'get' functions for EC_POINTs */ +int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *, EC_POINT *, + const BIGNUM *x, int y_bit, BN_CTX *); size_t EC_POINT_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form, unsigned char *buf, size_t len, BN_CTX *); @@ -135,9 +140,11 @@ int EC_POINT_oct2point(const EC_GROUP *, EC_POINT *, int EC_POINT_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *); int EC_POINT_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *); +int EC_POINT_invert(const EC_GROUP *, EC_POINT *, BN_CTX *); int EC_POINT_is_at_infinity(const EC_GROUP *, const EC_POINT *); int EC_POINT_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *); +int EC_POINT_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *); int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); @@ -155,6 +162,7 @@ int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); /* Error codes for the EC functions. */ /* Function codes. */ +#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP 127 #define EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR 100 #define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE 101 #define EC_F_EC_GFP_SIMPLE_OCT2POINT 102 @@ -167,9 +175,11 @@ int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); #define EC_F_EC_GROUP_SET_EXTRA_DATA 109 #define EC_F_EC_GROUP_SET_GENERATOR 110 #define EC_F_EC_POINT_ADD 111 +#define EC_F_EC_POINT_CMP 123 #define EC_F_EC_POINT_COPY 112 #define EC_F_EC_POINT_DBL 113 #define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP 114 +#define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP 124 #define EC_F_EC_POINT_IS_AT_INFINITY 115 #define EC_F_EC_POINT_IS_ON_CURVE 116 #define EC_F_EC_POINT_MAKE_AFFINE 117 @@ -177,12 +187,15 @@ int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); #define EC_F_EC_POINT_OCT2POINT 119 #define EC_F_EC_POINT_POINT2OCT 120 #define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP 121 +#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP 125 +#define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP 126 #define EC_F_EC_POINT_SET_TO_INFINITY 122 /* Reason codes. */ #define EC_R_BUFFER_TOO_SMALL 100 #define EC_R_INCOMPATIBLE_OBJECTS 101 #define EC_R_INVALID_ENCODING 102 +#define EC_R_INVALID_FIELD 108 #define EC_R_INVALID_FORM 103 #define EC_R_NO_SUCH_EXTRA_DATA 104 #define EC_R_POINT_AT_INFINITY 105 diff --git a/crypto/ec/ec_err.c b/crypto/ec/ec_err.c index 620dbd1131..cc00532214 100644 --- a/crypto/ec/ec_err.c +++ b/crypto/ec/ec_err.c @@ -66,6 +66,7 @@ #ifndef OPENSSL_NO_ERR static ERR_STRING_DATA EC_str_functs[]= { +{ERR_PACK(0,EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP,0), "EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP"}, {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR,0), "EC_GFP_SIMPLE_GROUP_SET_GENERATOR"}, {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_MAKE_AFFINE,0), "EC_GFP_SIMPLE_MAKE_AFFINE"}, {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_OCT2POINT,0), "EC_GFP_SIMPLE_OCT2POINT"}, @@ -78,9 +79,11 @@ static ERR_STRING_DATA EC_str_functs[]= {ERR_PACK(0,EC_F_EC_GROUP_SET_EXTRA_DATA,0), "EC_GROUP_SET_EXTRA_DATA"}, {ERR_PACK(0,EC_F_EC_GROUP_SET_GENERATOR,0), "EC_GROUP_set_generator"}, {ERR_PACK(0,EC_F_EC_POINT_ADD,0), "EC_POINT_add"}, +{ERR_PACK(0,EC_F_EC_POINT_CMP,0), "EC_POINT_cmp"}, {ERR_PACK(0,EC_F_EC_POINT_COPY,0), "EC_POINT_copy"}, {ERR_PACK(0,EC_F_EC_POINT_DBL,0), "EC_POINT_dbl"}, {ERR_PACK(0,EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP,0), "EC_POINT_get_affine_coordinates_GFp"}, +{ERR_PACK(0,EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP,0), "EC_POINT_get_Jprojective_coordinates_GFp"}, {ERR_PACK(0,EC_F_EC_POINT_IS_AT_INFINITY,0), "EC_POINT_is_at_infinity"}, {ERR_PACK(0,EC_F_EC_POINT_IS_ON_CURVE,0), "EC_POINT_is_on_curve"}, {ERR_PACK(0,EC_F_EC_POINT_MAKE_AFFINE,0), "EC_POINT_make_affine"}, @@ -88,6 +91,8 @@ static ERR_STRING_DATA EC_str_functs[]= {ERR_PACK(0,EC_F_EC_POINT_OCT2POINT,0), "EC_POINT_oct2point"}, {ERR_PACK(0,EC_F_EC_POINT_POINT2OCT,0), "EC_POINT_point2oct"}, {ERR_PACK(0,EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,0), "EC_POINT_set_affine_coordinates_GFp"}, +{ERR_PACK(0,EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP,0), "EC_POINT_set_compressed_coordinates_GFp"}, +{ERR_PACK(0,EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP,0), "EC_POINT_set_Jprojective_coordinates_GFp"}, {ERR_PACK(0,EC_F_EC_POINT_SET_TO_INFINITY,0), "EC_POINT_set_to_infinity"}, {0,NULL} }; @@ -97,6 +102,7 @@ static ERR_STRING_DATA EC_str_reasons[]= {EC_R_BUFFER_TOO_SMALL ,"buffer too small"}, {EC_R_INCOMPATIBLE_OBJECTS ,"incompatible objects"}, {EC_R_INVALID_ENCODING ,"invalid encoding"}, +{EC_R_INVALID_FIELD ,"invalid field"}, {EC_R_INVALID_FORM ,"invalid form"}, {EC_R_NO_SUCH_EXTRA_DATA ,"no such extra data"}, {EC_R_POINT_AT_INFINITY ,"point at infinity"}, diff --git a/crypto/ec/ec_lcl.h b/crypto/ec/ec_lcl.h index b3f8354e7a..15007d83c7 100644 --- a/crypto/ec/ec_lcl.h +++ b/crypto/ec/ec_lcl.h @@ -63,9 +63,8 @@ * so all this may change in future versions. */ struct ec_method_st { - /* used by EC_GROUP_new, EC_GROUP_set_curve_GFp, EC_GROUP_free, EC_GROUP_copy: */ + /* used by EC_GROUP_new, EC_GROUP_set_curve_GFp, EC_GROUP_free, EC_GROUP_clear_free, EC_GROUP_copy: */ int (*group_init)(EC_GROUP *); - /* int (*group_set)(EC_GROUP *, .....); */ int (*group_set_curve_GFp)(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); void (*group_finish)(EC_GROUP *); void (*group_clear_finish)(EC_GROUP *); @@ -78,18 +77,28 @@ struct ec_method_st { /* TODO: 'set' and 'get' functions for EC_GROUPs */ - /* used by EC_POINT_new, EC_POINT_free, EC_POINT_copy: */ + /* 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, EC_POINT_get_affine_coordinates_GFp, + * EC_POINT_set_compressed_coordinates_GFp: + */ 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_GFp)(const EC_GROUP *, EC_POINT *, const BIGNUM *x, const BIGNUM *y, BN_CTX *); int (*point_get_affine_coordinates_GFp)(const EC_GROUP *, const EC_POINT *, BIGNUM *x, BIGNUM *y, BN_CTX *); - /* TODO: other 'set' and 'get' functions for EC_POINTs */ + int (*point_set_compressed_coordinates_GFp)(const EC_GROUP *, EC_POINT *, + const BIGNUM *x, int y_bit, BN_CTX *); /* used by EC_POINT_point2oct, EC_POINT_oct2point: */ size_t (*point2oct)(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form, @@ -97,13 +106,17 @@ struct ec_method_st { int (*oct2point)(const EC_GROUP *, EC_POINT *, const unsigned char *buf, size_t len, BN_CTX *); - /* used by EC_POINT_add, EC_POINT_dbl: */ + /* 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_make_affine */ + /* 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_POINT_make_affine: */ int (*make_affine)(const EC_GROUP *, EC_POINT *, BN_CTX *); @@ -194,19 +207,26 @@ void ec_GFp_simple_point_finish(EC_POINT *); void ec_GFp_simple_point_clear_finish(EC_POINT *); int ec_GFp_simple_point_copy(EC_POINT *, const EC_POINT *); int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *); +int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *, EC_POINT *, + const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *); +int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *, const EC_POINT *, + BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *); int ec_GFp_simple_point_set_affine_coordinates_GFp(const EC_GROUP *, EC_POINT *, const BIGNUM *x, const BIGNUM *y, BN_CTX *); int ec_GFp_simple_point_get_affine_coordinates_GFp(const EC_GROUP *, const EC_POINT *, BIGNUM *x, BIGNUM *y, BN_CTX *); -/* TODO: other 'set' and 'get' functions for EC_POINTs */ +int ec_GFp_simple_set_compressed_coordinates_GFp(const EC_GROUP *, EC_POINT *, + const BIGNUM *x, int y_bit, BN_CTX *); size_t ec_GFp_simple_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form, unsigned char *buf, size_t len, BN_CTX *); int ec_GFp_simple_oct2point(const EC_GROUP *, EC_POINT *, const unsigned char *buf, size_t len, BN_CTX *); int ec_GFp_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *); int ec_GFp_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *); +int ec_GFp_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *); int ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *); int ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *); +int ec_GFp_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *); int ec_GFp_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *); int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c index d0af0d5794..8154a17eff 100644 --- a/crypto/ec/ec_lib.c +++ b/crypto/ec/ec_lib.c @@ -149,6 +149,8 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS); return 0; } + if (dest == src) + return 1; EC_GROUP_clear_free_extra_data(dest); if (src->extra_data_dup_func) @@ -334,6 +336,40 @@ int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) } +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) + { + ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) + { + ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y, z, ctx); + } + + +int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point, + BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx) + { + if (group->meth->point_get_Jprojective_coordinates_GFp == 0) + { + ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) + { + ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x, y, z, ctx); + } + + int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) { @@ -368,7 +404,21 @@ int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *p } -/* TODO: other 'set' and 'get' functions for EC_POINTs */ +int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, + const BIGNUM *x, int y_bit, BN_CTX *ctx) + { + if (group->meth->point_set_compressed_coordinates_GFp == 0) + { + ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) + { + ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->point_set_compressed_coordinates_GFp(group, point, x, y_bit, ctx); + } size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, @@ -437,6 +487,22 @@ int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX * } +int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) + { + if (group->meth->dbl == 0) + { + ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != a->meth) + { + ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->invert(group, a, ctx); + } + + int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) { if (group->meth->is_at_infinity == 0) @@ -469,6 +535,22 @@ int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *c } +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) + { + ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if ((group->meth != a->meth) || (a->meth != b->meth)) + { + ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->point_cmp(group, a, b, ctx); + } + + int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) { if (group->meth->make_affine == 0) diff --git a/crypto/ec/ecp_mont.c b/crypto/ec/ecp_mont.c index 17d9a48657..5db65ae419 100644 --- a/crypto/ec/ecp_mont.c +++ b/crypto/ec/ecp_mont.c @@ -71,15 +71,19 @@ const EC_METHOD *EC_GFp_mont_method(void) 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_GFp, ec_GFp_simple_point_get_affine_coordinates_GFp, - /* TODO: other 'set' and 'get' functions for EC_POINTs */ + ec_GFp_simple_set_compressed_coordinates_GFp, ec_GFp_simple_point2oct, ec_GFp_simple_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_make_affine, ec_GFp_mont_field_mul, ec_GFp_mont_field_sqr, diff --git a/crypto/ec/ecp_nist.c b/crypto/ec/ecp_nist.c index df2d614209..089e2c610f 100644 --- a/crypto/ec/ecp_nist.c +++ b/crypto/ec/ecp_nist.c @@ -71,15 +71,19 @@ const EC_METHOD *EC_GFp_nist_method(void) 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_GFp, ec_GFp_simple_point_get_affine_coordinates_GFp, - /* TODO: other 'set' and 'get' functions for EC_POINTs */ + ec_GFp_simple_set_compressed_coordinates_GFp, ec_GFp_simple_point2oct, ec_GFp_simple_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_make_affine, ec_GFp_nist_field_mul, ec_GFp_nist_field_sqr, diff --git a/crypto/ec/ecp_recp.c b/crypto/ec/ecp_recp.c index df7b52bce5..8afdca1fa7 100644 --- a/crypto/ec/ecp_recp.c +++ b/crypto/ec/ecp_recp.c @@ -71,15 +71,19 @@ const EC_METHOD *EC_GFp_recp_method(void) 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_GFp, ec_GFp_simple_point_get_affine_coordinates_GFp, - /* TODO: other 'set' and 'get' functions for EC_POINTs */ + ec_GFp_simple_set_compressed_coordinates_GFp, ec_GFp_simple_point2oct, ec_GFp_simple_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_make_affine, ec_GFp_recp_field_mul, ec_GFp_recp_field_sqr, diff --git a/crypto/ec/ecp_smpl.c b/crypto/ec/ecp_smpl.c index 9d9fe86352..d6c3f635e5 100644 --- a/crypto/ec/ecp_smpl.c +++ b/crypto/ec/ecp_smpl.c @@ -75,15 +75,19 @@ const EC_METHOD *EC_GFp_simple_method(void) 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_GFp, ec_GFp_simple_point_get_affine_coordinates_GFp, - /* TODO: other 'set' and 'get' functions for EC_POINTs */ + ec_GFp_simple_set_compressed_coordinates_GFp, ec_GFp_simple_point2oct, ec_GFp_simple_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_make_affine, ec_GFp_simple_field_mul, ec_GFp_simple_field_sqr, @@ -114,6 +118,13 @@ int ec_GFp_simple_group_set_curve_GFp(EC_GROUP *group, BN_CTX *new_ctx = NULL; BIGNUM *tmp_a; + /* p must be a prime > 3 */ + if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) + { + ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP, EC_R_INVALID_FIELD); + return 0; + } + if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); @@ -295,6 +306,16 @@ int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group, EC_POINT *point) } +int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, + const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx); +/* TODO */ + + +int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point, + BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx); +/* TODO */ + + int ec_GFp_simple_point_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) { @@ -376,8 +397,14 @@ int ec_GFp_simple_point_get_affine_coordinates_GFp(const EC_GROUP *group, const if (BN_is_one(Z_)) { - if (!BN_copy(x, X_)) goto err; - if (!BN_copy(y, Y_)) goto err; + if (x != NULL) + { + if (!BN_copy(x, X_)) goto err; + } + if (y != NULL) + { + if (!BN_copy(y, Y_)) goto err; + } } else { @@ -387,10 +414,17 @@ int ec_GFp_simple_point_get_affine_coordinates_GFp(const EC_GROUP *group, const goto err; } if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx)) goto err; - if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx)) goto err; - if (!BN_mod_mul(x, X_, Z_2, &group->field, ctx)) goto err; - if (!BN_mod_mul(y, Y_, Z_3, &group->field, ctx)) goto err; + if (x != NULL) + { + if (!BN_mod_mul(x, X_, Z_2, &group->field, ctx)) goto err; + } + + if (y != NULL) + { + if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx)) goto err; + if (!BN_mod_mul(y, Y_, Z_3, &group->field, ctx)) goto err; + } } ret = 1; @@ -403,7 +437,9 @@ int ec_GFp_simple_point_get_affine_coordinates_GFp(const EC_GROUP *group, const } -/* TODO: other 'set' and 'get' functions for EC_POINTs */ +int ec_GFp_simple_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, + const BIGNUM *x, int y_bit, BN_CTX *); +/* TODO */ size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, @@ -467,7 +503,7 @@ size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, poi if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) goto err; - if ((form == POINT_CONVERSION_COMPRESSED || form == POINT_CONVERSION_HYBRID) && BN_is_bit_set(y, 0)) + if ((form == POINT_CONVERSION_COMPRESSED || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y)) buf[0] = form + 1; else buf[0] = form; @@ -612,7 +648,7 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, } if (form == POINT_CONVERSION_HYBRID) { - if (y_bit != BN_is_bit_set(y, 0)) + if (y_bit != BN_is_odd(y)) { ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); goto err; @@ -659,11 +695,16 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, goto err; } - if (y_bit != BN_is_bit_set(y, 0)) + if (y_bit != BN_is_odd(y)) { + if (BN_is_zero(y)) + { + ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + goto err; + } if (!BN_usub(y, &group->field, y)) goto err; } - if (y_bit != BN_is_bit_set(y, 0)) + if (y_bit != BN_is_odd(y)) { ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, ERR_R_INTERNAL_ERROR); goto err; @@ -725,6 +766,11 @@ int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, con n6 = BN_CTX_get(ctx); if (n6 == NULL) goto end; + /* Note that in this function we must not read components of 'a' or 'b' + * once we have written the corresponding components of 'r'. + * ('r' might be one of 'a' or 'b'.) + */ + /* n1, n2 */ if (b->Z_is_one) { @@ -881,6 +927,11 @@ int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_ n3 = BN_CTX_get(ctx); if (n3 == NULL) goto err; + /* Note that in this function we must not read components of 'a' + * once we have written the corresponding components of 'r'. + * ('r' might the same as 'a'.) + */ + /* n1 */ if (a->Z_is_one) { @@ -959,6 +1010,10 @@ int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_ } +int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx); +/* TODO */ + + int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) { return BN_is_zero(&point->Z); @@ -1067,6 +1122,10 @@ int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_C } +int ec_GFp_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *); +/* TODO */ + + int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) { BN_CTX *new_ctx = NULL; |