提交 1d5bd6cf 编写于 作者: B Bodo Möller

More 'TODO' items.

上级 226cc7de
...@@ -122,11 +122,16 @@ void EC_POINT_clear_free(EC_POINT *); ...@@ -122,11 +122,16 @@ void EC_POINT_clear_free(EC_POINT *);
int EC_POINT_copy(EC_POINT *, const 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_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 *, int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *, EC_POINT *,
const BIGNUM *x, const BIGNUM *y, BN_CTX *); const BIGNUM *x, const BIGNUM *y, BN_CTX *);
int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *, const EC_POINT *, int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *, const EC_POINT *,
BIGNUM *x, BIGNUM *y, BN_CTX *); 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, size_t EC_POINT_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
unsigned char *buf, size_t len, BN_CTX *); unsigned char *buf, size_t len, BN_CTX *);
...@@ -135,9 +140,11 @@ int EC_POINT_oct2point(const EC_GROUP *, EC_POINT *, ...@@ -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_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_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_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_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 *); 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 *); ...@@ -155,6 +162,7 @@ int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
/* Error codes for the EC functions. */ /* Error codes for the EC functions. */
/* Function codes. */ /* 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_GROUP_SET_GENERATOR 100
#define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE 101 #define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE 101
#define EC_F_EC_GFP_SIMPLE_OCT2POINT 102 #define EC_F_EC_GFP_SIMPLE_OCT2POINT 102
...@@ -167,9 +175,11 @@ int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); ...@@ -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_EXTRA_DATA 109
#define EC_F_EC_GROUP_SET_GENERATOR 110 #define EC_F_EC_GROUP_SET_GENERATOR 110
#define EC_F_EC_POINT_ADD 111 #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_COPY 112
#define EC_F_EC_POINT_DBL 113 #define EC_F_EC_POINT_DBL 113
#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP 114 #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_AT_INFINITY 115
#define EC_F_EC_POINT_IS_ON_CURVE 116 #define EC_F_EC_POINT_IS_ON_CURVE 116
#define EC_F_EC_POINT_MAKE_AFFINE 117 #define EC_F_EC_POINT_MAKE_AFFINE 117
...@@ -177,12 +187,15 @@ int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); ...@@ -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_OCT2POINT 119
#define EC_F_EC_POINT_POINT2OCT 120 #define EC_F_EC_POINT_POINT2OCT 120
#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP 121 #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 #define EC_F_EC_POINT_SET_TO_INFINITY 122
/* Reason codes. */ /* Reason codes. */
#define EC_R_BUFFER_TOO_SMALL 100 #define EC_R_BUFFER_TOO_SMALL 100
#define EC_R_INCOMPATIBLE_OBJECTS 101 #define EC_R_INCOMPATIBLE_OBJECTS 101
#define EC_R_INVALID_ENCODING 102 #define EC_R_INVALID_ENCODING 102
#define EC_R_INVALID_FIELD 108
#define EC_R_INVALID_FORM 103 #define EC_R_INVALID_FORM 103
#define EC_R_NO_SUCH_EXTRA_DATA 104 #define EC_R_NO_SUCH_EXTRA_DATA 104
#define EC_R_POINT_AT_INFINITY 105 #define EC_R_POINT_AT_INFINITY 105
......
...@@ -66,6 +66,7 @@ ...@@ -66,6 +66,7 @@
#ifndef OPENSSL_NO_ERR #ifndef OPENSSL_NO_ERR
static ERR_STRING_DATA EC_str_functs[]= 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_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_MAKE_AFFINE,0), "EC_GFP_SIMPLE_MAKE_AFFINE"},
{ERR_PACK(0,EC_F_EC_GFP_SIMPLE_OCT2POINT,0), "EC_GFP_SIMPLE_OCT2POINT"}, {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[]= ...@@ -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_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_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_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_COPY,0), "EC_POINT_copy"},
{ERR_PACK(0,EC_F_EC_POINT_DBL,0), "EC_POINT_dbl"}, {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_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_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_IS_ON_CURVE,0), "EC_POINT_is_on_curve"},
{ERR_PACK(0,EC_F_EC_POINT_MAKE_AFFINE,0), "EC_POINT_make_affine"}, {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[]= ...@@ -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_OCT2POINT,0), "EC_POINT_oct2point"},
{ERR_PACK(0,EC_F_EC_POINT_POINT2OCT,0), "EC_POINT_point2oct"}, {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_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"}, {ERR_PACK(0,EC_F_EC_POINT_SET_TO_INFINITY,0), "EC_POINT_set_to_infinity"},
{0,NULL} {0,NULL}
}; };
...@@ -97,6 +102,7 @@ static ERR_STRING_DATA EC_str_reasons[]= ...@@ -97,6 +102,7 @@ static ERR_STRING_DATA EC_str_reasons[]=
{EC_R_BUFFER_TOO_SMALL ,"buffer too small"}, {EC_R_BUFFER_TOO_SMALL ,"buffer too small"},
{EC_R_INCOMPATIBLE_OBJECTS ,"incompatible objects"}, {EC_R_INCOMPATIBLE_OBJECTS ,"incompatible objects"},
{EC_R_INVALID_ENCODING ,"invalid encoding"}, {EC_R_INVALID_ENCODING ,"invalid encoding"},
{EC_R_INVALID_FIELD ,"invalid field"},
{EC_R_INVALID_FORM ,"invalid form"}, {EC_R_INVALID_FORM ,"invalid form"},
{EC_R_NO_SUCH_EXTRA_DATA ,"no such extra data"}, {EC_R_NO_SUCH_EXTRA_DATA ,"no such extra data"},
{EC_R_POINT_AT_INFINITY ,"point at infinity"}, {EC_R_POINT_AT_INFINITY ,"point at infinity"},
......
...@@ -63,9 +63,8 @@ ...@@ -63,9 +63,8 @@
* so all this may change in future versions. */ * so all this may change in future versions. */
struct ec_method_st { 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_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 *); 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_finish)(EC_GROUP *);
void (*group_clear_finish)(EC_GROUP *); void (*group_clear_finish)(EC_GROUP *);
...@@ -78,18 +77,28 @@ struct ec_method_st { ...@@ -78,18 +77,28 @@ struct ec_method_st {
/* TODO: 'set' and 'get' functions for EC_GROUPs */ /* 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 *); int (*point_init)(EC_POINT *);
void (*point_finish)(EC_POINT *); void (*point_finish)(EC_POINT *);
void (*point_clear_finish)(EC_POINT *); void (*point_clear_finish)(EC_POINT *);
int (*point_copy)(EC_POINT *, const 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_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 *, int (*point_set_affine_coordinates_GFp)(const EC_GROUP *, EC_POINT *,
const BIGNUM *x, const BIGNUM *y, BN_CTX *); const BIGNUM *x, const BIGNUM *y, BN_CTX *);
int (*point_get_affine_coordinates_GFp)(const EC_GROUP *, const EC_POINT *, int (*point_get_affine_coordinates_GFp)(const EC_GROUP *, const EC_POINT *,
BIGNUM *x, BIGNUM *y, BN_CTX *); 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: */ /* used by EC_POINT_point2oct, EC_POINT_oct2point: */
size_t (*point2oct)(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form, size_t (*point2oct)(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
...@@ -97,13 +106,17 @@ struct ec_method_st { ...@@ -97,13 +106,17 @@ struct ec_method_st {
int (*oct2point)(const EC_GROUP *, EC_POINT *, int (*oct2point)(const EC_GROUP *, EC_POINT *,
const unsigned char *buf, size_t len, BN_CTX *); 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 (*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 (*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_at_infinity)(const EC_GROUP *, const EC_POINT *);
int (*is_on_curve)(const EC_GROUP *, const EC_POINT *, BN_CTX *); 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 *); int (*make_affine)(const EC_GROUP *, EC_POINT *, BN_CTX *);
...@@ -194,19 +207,26 @@ void ec_GFp_simple_point_finish(EC_POINT *); ...@@ -194,19 +207,26 @@ void ec_GFp_simple_point_finish(EC_POINT *);
void ec_GFp_simple_point_clear_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_copy(EC_POINT *, const EC_POINT *);
int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, 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 *, int ec_GFp_simple_point_set_affine_coordinates_GFp(const EC_GROUP *, EC_POINT *,
const BIGNUM *x, const BIGNUM *y, BN_CTX *); const BIGNUM *x, const BIGNUM *y, BN_CTX *);
int ec_GFp_simple_point_get_affine_coordinates_GFp(const EC_GROUP *, const EC_POINT *, int ec_GFp_simple_point_get_affine_coordinates_GFp(const EC_GROUP *, const EC_POINT *,
BIGNUM *x, BIGNUM *y, BN_CTX *); 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, 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 *); unsigned char *buf, size_t len, BN_CTX *);
int ec_GFp_simple_oct2point(const EC_GROUP *, EC_POINT *, int ec_GFp_simple_oct2point(const EC_GROUP *, EC_POINT *,
const unsigned char *buf, size_t len, BN_CTX *); 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_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_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_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_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_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_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 *); int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
......
...@@ -149,6 +149,8 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) ...@@ -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); ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS);
return 0; return 0;
} }
if (dest == src)
return 1;
EC_GROUP_clear_free_extra_data(dest); EC_GROUP_clear_free_extra_data(dest);
if (src->extra_data_dup_func) if (src->extra_data_dup_func)
...@@ -334,6 +336,40 @@ int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) ...@@ -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, int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) 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 ...@@ -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, 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 * ...@@ -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) int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
{ {
if (group->meth->is_at_infinity == 0) 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 ...@@ -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) int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
{ {
if (group->meth->make_affine == 0) if (group->meth->make_affine == 0)
......
...@@ -71,15 +71,19 @@ const EC_METHOD *EC_GFp_mont_method(void) ...@@ -71,15 +71,19 @@ const EC_METHOD *EC_GFp_mont_method(void)
ec_GFp_simple_point_clear_finish, ec_GFp_simple_point_clear_finish,
ec_GFp_simple_point_copy, ec_GFp_simple_point_copy,
ec_GFp_simple_point_set_to_infinity, 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_set_affine_coordinates_GFp,
ec_GFp_simple_point_get_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_point2oct,
ec_GFp_simple_oct2point, ec_GFp_simple_oct2point,
ec_GFp_simple_add, ec_GFp_simple_add,
ec_GFp_simple_dbl, ec_GFp_simple_dbl,
ec_GFp_simple_invert,
ec_GFp_simple_is_at_infinity, ec_GFp_simple_is_at_infinity,
ec_GFp_simple_is_on_curve, ec_GFp_simple_is_on_curve,
ec_GFp_simple_cmp,
ec_GFp_simple_make_affine, ec_GFp_simple_make_affine,
ec_GFp_mont_field_mul, ec_GFp_mont_field_mul,
ec_GFp_mont_field_sqr, ec_GFp_mont_field_sqr,
......
...@@ -71,15 +71,19 @@ const EC_METHOD *EC_GFp_nist_method(void) ...@@ -71,15 +71,19 @@ const EC_METHOD *EC_GFp_nist_method(void)
ec_GFp_simple_point_clear_finish, ec_GFp_simple_point_clear_finish,
ec_GFp_simple_point_copy, ec_GFp_simple_point_copy,
ec_GFp_simple_point_set_to_infinity, 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_set_affine_coordinates_GFp,
ec_GFp_simple_point_get_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_point2oct,
ec_GFp_simple_oct2point, ec_GFp_simple_oct2point,
ec_GFp_simple_add, ec_GFp_simple_add,
ec_GFp_simple_dbl, ec_GFp_simple_dbl,
ec_GFp_simple_invert,
ec_GFp_simple_is_at_infinity, ec_GFp_simple_is_at_infinity,
ec_GFp_simple_is_on_curve, ec_GFp_simple_is_on_curve,
ec_GFp_simple_cmp,
ec_GFp_simple_make_affine, ec_GFp_simple_make_affine,
ec_GFp_nist_field_mul, ec_GFp_nist_field_mul,
ec_GFp_nist_field_sqr, ec_GFp_nist_field_sqr,
......
...@@ -71,15 +71,19 @@ const EC_METHOD *EC_GFp_recp_method(void) ...@@ -71,15 +71,19 @@ const EC_METHOD *EC_GFp_recp_method(void)
ec_GFp_simple_point_clear_finish, ec_GFp_simple_point_clear_finish,
ec_GFp_simple_point_copy, ec_GFp_simple_point_copy,
ec_GFp_simple_point_set_to_infinity, 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_set_affine_coordinates_GFp,
ec_GFp_simple_point_get_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_point2oct,
ec_GFp_simple_oct2point, ec_GFp_simple_oct2point,
ec_GFp_simple_add, ec_GFp_simple_add,
ec_GFp_simple_dbl, ec_GFp_simple_dbl,
ec_GFp_simple_invert,
ec_GFp_simple_is_at_infinity, ec_GFp_simple_is_at_infinity,
ec_GFp_simple_is_on_curve, ec_GFp_simple_is_on_curve,
ec_GFp_simple_cmp,
ec_GFp_simple_make_affine, ec_GFp_simple_make_affine,
ec_GFp_recp_field_mul, ec_GFp_recp_field_mul,
ec_GFp_recp_field_sqr, ec_GFp_recp_field_sqr,
......
...@@ -75,15 +75,19 @@ const EC_METHOD *EC_GFp_simple_method(void) ...@@ -75,15 +75,19 @@ const EC_METHOD *EC_GFp_simple_method(void)
ec_GFp_simple_point_clear_finish, ec_GFp_simple_point_clear_finish,
ec_GFp_simple_point_copy, ec_GFp_simple_point_copy,
ec_GFp_simple_point_set_to_infinity, 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_set_affine_coordinates_GFp,
ec_GFp_simple_point_get_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_point2oct,
ec_GFp_simple_oct2point, ec_GFp_simple_oct2point,
ec_GFp_simple_add, ec_GFp_simple_add,
ec_GFp_simple_dbl, ec_GFp_simple_dbl,
ec_GFp_simple_invert,
ec_GFp_simple_is_at_infinity, ec_GFp_simple_is_at_infinity,
ec_GFp_simple_is_on_curve, ec_GFp_simple_is_on_curve,
ec_GFp_simple_cmp,
ec_GFp_simple_make_affine, ec_GFp_simple_make_affine,
ec_GFp_simple_field_mul, ec_GFp_simple_field_mul,
ec_GFp_simple_field_sqr, ec_GFp_simple_field_sqr,
...@@ -114,6 +118,13 @@ int ec_GFp_simple_group_set_curve_GFp(EC_GROUP *group, ...@@ -114,6 +118,13 @@ int ec_GFp_simple_group_set_curve_GFp(EC_GROUP *group,
BN_CTX *new_ctx = NULL; BN_CTX *new_ctx = NULL;
BIGNUM *tmp_a; 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) if (ctx == NULL)
{ {
ctx = new_ctx = BN_CTX_new(); 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) ...@@ -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, 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) 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 ...@@ -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_is_one(Z_))
{ {
if (!BN_copy(x, X_)) goto err; if (x != NULL)
if (!BN_copy(y, Y_)) goto err; {
if (!BN_copy(x, X_)) goto err;
}
if (y != NULL)
{
if (!BN_copy(y, Y_)) goto err;
}
} }
else else
{ {
...@@ -387,10 +414,17 @@ int ec_GFp_simple_point_get_affine_coordinates_GFp(const EC_GROUP *group, const ...@@ -387,10 +414,17 @@ int ec_GFp_simple_point_get_affine_coordinates_GFp(const EC_GROUP *group, const
goto err; goto err;
} }
if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx)) 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 (x != NULL)
if (!BN_mod_mul(y, Y_, Z_3, &group->field, ctx)) goto err; {
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; ret = 1;
...@@ -403,7 +437,9 @@ int ec_GFp_simple_point_get_affine_coordinates_GFp(const EC_GROUP *group, const ...@@ -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, 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 ...@@ -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 (!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; buf[0] = form + 1;
else else
buf[0] = form; buf[0] = form;
...@@ -612,7 +648,7 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, ...@@ -612,7 +648,7 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
} }
if (form == POINT_CONVERSION_HYBRID) 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); ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
goto err; goto err;
...@@ -659,11 +695,16 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, ...@@ -659,11 +695,16 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
goto err; 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 (!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); ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, ERR_R_INTERNAL_ERROR);
goto err; goto err;
...@@ -725,6 +766,11 @@ int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, con ...@@ -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); n6 = BN_CTX_get(ctx);
if (n6 == NULL) goto end; 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 */ /* n1, n2 */
if (b->Z_is_one) 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_ ...@@ -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); n3 = BN_CTX_get(ctx);
if (n3 == NULL) goto err; 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 */ /* n1 */
if (a->Z_is_one) 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_ ...@@ -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) int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
{ {
return BN_is_zero(&point->Z); 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 ...@@ -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) int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
{ {
BN_CTX *new_ctx = NULL; BN_CTX *new_ctx = NULL;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册