static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data) { EC_GROUP *group=NULL; EC_POINT *P=NULL; BN_CTX *ctx=NULL; BIGNUM *p=NULL, *a=NULL, *b=NULL, *x=NULL, *y=NULL, *order=NULL; int ok=0; if ((ctx = BN_CTX_new()) == NULL) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE); goto err; } if ((p = BN_new()) == NULL || (a = BN_new()) == NULL || (b = BN_new()) == NULL || (x = BN_new()) == NULL || (y = BN_new()) == NULL || (order = BN_new()) == NULL) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE); goto err; } if (!BN_hex2bn(&p, data->p) || !BN_hex2bn(&a, data->a) || !BN_hex2bn(&b, data->b)) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); goto err; } if (data->field_type == NID_X9_62_prime_field) { if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } } else { /* field_type == NID_X9_62_characteristic_two_field */ if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } } if ((P = EC_POINT_new(group)) == NULL) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } if (!BN_hex2bn(&x, data->x) || !BN_hex2bn(&y, data->y)) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); goto err; } if (!EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx)) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } if (!BN_hex2bn(&order, data->order) || !BN_set_word(x, data->cofactor)) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); goto err; } if (!EC_GROUP_set_generator(group, P, order, x)) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } if (data->seed) { if (!EC_GROUP_set_seed(group, data->seed, data->seed_len)) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } } ok=1; err: if (!ok) { EC_GROUP_free(group); group = NULL; } if (P) EC_POINT_free(P); if (ctx) BN_CTX_free(ctx); if (p) BN_free(p); if (a) BN_free(a); if (b) BN_free(b); if (order) BN_free(order); if (x) BN_free(x); if (y) BN_free(y); return group; }
static EC_GROUP *ec_group_new_from_data(const ec_list_element curve) { EC_GROUP *group=NULL; EC_POINT *P=NULL; BN_CTX *ctx=NULL; BIGNUM *p=NULL, *a=NULL, *b=NULL, *x=NULL, *y=NULL, *order=NULL; int ok=0; int seed_len,param_len; const EC_METHOD *meth; const EC_CURVE_DATA *data; const unsigned char *params; if ((ctx = BN_CTX_new()) == NULL) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE); goto err; } data = curve.data; seed_len = data->seed_len; param_len = data->param_len; params = (const unsigned char *)(data+1); /* skip header */ params += seed_len; /* skip seed */ if (!(p = BN_bin2bn(params+0*param_len, param_len, NULL)) || !(a = BN_bin2bn(params+1*param_len, param_len, NULL)) || !(b = BN_bin2bn(params+2*param_len, param_len, NULL))) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); goto err; } if (curve.meth != 0) { meth = curve.meth(); if (((group = EC_GROUP_new(meth)) == NULL) || (!(group->meth->group_set_curve(group, p, a, b, ctx)))) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } } else if (data->field_type == NID_X9_62_prime_field) { if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } } #ifndef OPENSSL_NO_EC2M else /* field_type == NID_X9_62_characteristic_two_field */ { if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } } #endif if ((P = EC_POINT_new(group)) == NULL) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } if (!(x = BN_bin2bn(params+3*param_len, param_len, NULL)) || !(y = BN_bin2bn(params+4*param_len, param_len, NULL))) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); goto err; } if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } if (!(order = BN_bin2bn(params+5*param_len, param_len, NULL)) || !BN_set_word(x, (BN_ULONG)data->cofactor)) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); goto err; } if (!EC_GROUP_set_generator(group, P, order, x)) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } if (seed_len) { if (!EC_GROUP_set_seed(group, params-seed_len, seed_len)) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; } } ok=1; err: if (!ok) { EC_GROUP_free(group); group = NULL; } if (P) EC_POINT_free(P); if (ctx) BN_CTX_free(ctx); if (p) BN_free(p); if (a) BN_free(a); if (b) BN_free(b); if (order) BN_free(order); if (x) BN_free(x); if (y) BN_free(y); return group; }
int MKEMParams_init(MKEMParams *params) { const mk_curve_params *p = &mk_curves[MK_CURVE_163_0]; BIGNUM *maxu = 0; size_t bitsize, bytesize, bitcap, k; memset(params, 0, sizeof(MKEMParams)); FAILZ(params->ctx = BN_CTX_new()); FAILZ(params->m = BN_bin2bn(p->m, p->L_m, 0)); FAILZ(params->b = BN_bin2bn(p->b, p->L_b, 0)); FAILZ(params->a0 = BN_new()); FAILZ(BN_zero((BIGNUM *)params->a0)); FAILZ(params->a1 = BN_value_one()); FAILZ(params->p0 = BN_bin2bn(p->p0, p->L_p0, 0)); FAILZ(params->p1 = BN_bin2bn(p->p1, p->L_p1, 0)); FAILZ(params->n0 = BN_bin2bn(p->n0, p->L_n0, 0)); FAILZ(params->n1 = BN_bin2bn(p->n1, p->L_n1, 0)); FAILZ(params->c0 = EC_GROUP_new_curve_GF2m(params->m, params->a0, params->b, params->ctx)); FAILZ(params->c1 = EC_GROUP_new_curve_GF2m(params->m, params->a1, params->b, params->ctx)); FAILZ(params->g0 = EC_POINT_new(params->c0)); FAILZ(EC_POINT_oct2point(params->c0, (EC_POINT *)params->g0, p->g0, p->L_g0, params->ctx)); FAILZ(params->g1 = EC_POINT_new(params->c1)); FAILZ(EC_POINT_oct2point(params->c1, (EC_POINT *)params->g1, p->g1, p->L_g1, params->ctx)); /* Calculate the upper limit for the random integer U input to MKEM_generate_message_u. The paper calls for us to choose between curve 0 and curve 1 with probability proportional to the number of points on that curve, and then choose a random integer in the range 0 < u < n{curve}. The easiest way to do this accurately is to choose a random integer in the range [1, n0 + n1 - 2]. If it is less than n0, MKEM_generate_message_u will use it unmodified with curve 0. If it is greater than or equal to n0, MKEM_generate_message_u will subtract n0-1, leaving a number in the range [1, n1-1], and use that with curve 1. */ FAILZ(maxu = BN_dup(params->n0)); FAILZ(BN_add(maxu, maxu, params->n1)); FAILZ(BN_sub(maxu, maxu, BN_value_one())); FAILZ(BN_sub(maxu, maxu, BN_value_one())); params->maxu = maxu; maxu = 0; /* Calculate the maximum size of a message and the padding mask applied to the high byte of each message. See MKEM_generate_message_u for further exposition. */ bitsize = EC_GROUP_get_degree(params->c0); if ((size_t)EC_GROUP_get_degree(params->c1) != bitsize) goto fail; bytesize = (bitsize + 7) / 8; bitcap = bytesize * 8; k = bitcap - bitsize; if (k == 0) goto fail; params->msgsize = bytesize; params->pad_bits = k - 1; params->pad_mask = ~((1 << (8 - params->pad_bits)) - 1); params->curve_bit = 1 << (8 - k); return 0; fail: if (maxu) BN_free(maxu); MKEMParams_teardown(params); return -1; }