int GOST_KEY_set_public_key_affine_coordinates(GOST_KEY *key, BIGNUM *x, BIGNUM *y) { BN_CTX *ctx = NULL; BIGNUM *tx, *ty; EC_POINT *point = NULL; int ok = 0; if (key == NULL || key->group == NULL || x == NULL || y == NULL) { GOSTerr(GOST_F_GOST_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, ERR_R_PASSED_NULL_PARAMETER); return 0; } ctx = BN_CTX_new(); if (ctx == NULL) goto err; point = EC_POINT_new(key->group); if (point == NULL) goto err; if ((tx = BN_CTX_get(ctx)) == NULL) goto err; if ((ty = BN_CTX_get(ctx)) == NULL) goto err; if (EC_POINT_set_affine_coordinates_GFp(key->group, point, x, y, ctx) == 0) goto err; if (EC_POINT_get_affine_coordinates_GFp(key->group, point, tx, ty, ctx) == 0) goto err; /* * Check if retrieved coordinates match originals: if not values are * out of range. */ if (BN_cmp(x, tx) != 0 || BN_cmp(y, ty) != 0) { GOSTerr(GOST_F_GOST_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, EC_R_COORDINATES_OUT_OF_RANGE); goto err; } if (GOST_KEY_set_public_key(key, point) != 0) goto err; if (GOST_KEY_check_key(key) == 0) goto err; ok = 1; err: BN_CTX_free(ctx); EC_POINT_free(point); return ok; }
int gost2001_compute_public(GOST_KEY *ec) { const EC_GROUP *group = GOST_KEY_get0_group(ec); EC_POINT *pub_key = NULL; const BIGNUM *priv_key = NULL; BN_CTX *ctx = NULL; int ok = 0; if (group == NULL) { GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, GOST_R_KEY_IS_NOT_INITIALIZED); return 0; } ctx = BN_CTX_new(); if (ctx == NULL) { GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_MALLOC_FAILURE); return 0; } BN_CTX_start(ctx); if ((priv_key = GOST_KEY_get0_private_key(ec)) == NULL) goto err; pub_key = EC_POINT_new(group); if (pub_key == NULL) goto err; if (EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx) == 0) goto err; if (GOST_KEY_set_public_key(ec, pub_key) == 0) goto err; ok = 1; if (ok == 0) { err: GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB); } EC_POINT_free(pub_key); if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } return ok; }