Don't store a redundant copy of the EC_GROUP field modulus
One less value to initialize statically. Also this simplifies EC_GROUP initialization. While I'm here, reorder EC_GROUP to pad better. This lets us simplify the init bits slightly. It does mean p224-64.c, the one EC_GROUP that doesn't use Montgomery reduction, carries around a wasted Montgomery context, but it'll make generating the tables statically much easier. Also once the data is pre-generated, the cost is minimal. Bug: 20 Change-Id: Ib66e655ce5a0902ab3ed6695fcbb46aa87683885 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/60928 Reviewed-by: Adam Langley <agl@google.com> Commit-Queue: David Benjamin <davidben@google.com>
This commit is contained in:
parent
1e2f169663
commit
8e8f87ea94
@ -179,12 +179,12 @@ static int hash_to_field2(const EC_GROUP *group, const EVP_MD *md,
|
||||
size_t msg_len) {
|
||||
size_t L;
|
||||
uint8_t buf[4 * EC_MAX_BYTES];
|
||||
if (!num_bytes_to_derive(&L, &group->field, k) ||
|
||||
if (!num_bytes_to_derive(&L, &group->field->N, k) ||
|
||||
!expand_message_xmd(md, buf, 2 * L, msg, msg_len, dst, dst_len)) {
|
||||
return 0;
|
||||
}
|
||||
BN_ULONG words[2 * EC_MAX_WORDS];
|
||||
size_t num_words = 2 * group->field.width;
|
||||
size_t num_words = 2 * group->field->N.width;
|
||||
big_endian_to_words(words, num_words, buf, L);
|
||||
group->meth->felem_reduce(group, out1, words, num_words);
|
||||
big_endian_to_words(words, num_words, buf + L, L);
|
||||
@ -231,7 +231,7 @@ static BN_ULONG sgn0(const EC_GROUP *group, const EC_FELEM *a) {
|
||||
}
|
||||
|
||||
OPENSSL_UNUSED static int is_3mod4(const EC_GROUP *group) {
|
||||
return group->field.width > 0 && (group->field.d[0] & 3) == 3;
|
||||
return group->field->N.width > 0 && (group->field->N.d[0] & 3) == 3;
|
||||
}
|
||||
|
||||
// sqrt_ratio_3mod4 implements the operation described in appendix F.2.1.2
|
||||
@ -354,8 +354,8 @@ static int hash_to_curve(const EC_GROUP *group, const EVP_MD *md,
|
||||
|
||||
// Compute |c1| = (p - 3) / 4.
|
||||
BN_ULONG c1[EC_MAX_WORDS];
|
||||
size_t num_c1 = group->field.width;
|
||||
if (!bn_copy_words(c1, num_c1, &group->field)) {
|
||||
size_t num_c1 = group->field->N.width;
|
||||
if (!bn_copy_words(c1, num_c1, &group->field->N)) {
|
||||
return 0;
|
||||
}
|
||||
bn_rshift_words(c1, c1, /*shift=*/2, /*num=*/num_c1);
|
||||
@ -371,7 +371,7 @@ static int hash_to_curve(const EC_GROUP *group, const EVP_MD *md,
|
||||
|
||||
static int felem_from_u8(const EC_GROUP *group, EC_FELEM *out, uint8_t a) {
|
||||
uint8_t bytes[EC_MAX_BYTES] = {0};
|
||||
size_t len = BN_num_bytes(&group->field);
|
||||
size_t len = BN_num_bytes(&group->field->N);
|
||||
bytes[len - 1] = a;
|
||||
return ec_felem_from_bytes(group, out, bytes, len);
|
||||
}
|
||||
|
@ -270,20 +270,9 @@ DEFINE_METHOD_FUNCTION(struct built_in_curves, OPENSSL_built_in_curves) {
|
||||
#endif
|
||||
}
|
||||
|
||||
EC_GROUP *ec_group_new(const EC_METHOD *meth) {
|
||||
EC_GROUP *ret;
|
||||
|
||||
if (meth == NULL) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_SLOT_FULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (meth->group_init == 0) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = OPENSSL_malloc(sizeof(EC_GROUP));
|
||||
EC_GROUP *ec_group_new(const EC_METHOD *meth, const BIGNUM *p, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *ctx) {
|
||||
EC_GROUP *ret = OPENSSL_malloc(sizeof(EC_GROUP));
|
||||
if (ret == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@ -292,8 +281,8 @@ EC_GROUP *ec_group_new(const EC_METHOD *meth) {
|
||||
ret->references = 1;
|
||||
ret->meth = meth;
|
||||
|
||||
if (!meth->group_init(ret)) {
|
||||
OPENSSL_free(ret);
|
||||
if (!ec_GFp_simple_group_set_curve(ret, p, a, b, ctx)) {
|
||||
EC_GROUP_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -310,7 +299,7 @@ static int ec_group_set_generator(EC_GROUP *group, const EC_AFFINE *generator,
|
||||
return 0;
|
||||
}
|
||||
|
||||
group->field_greater_than_order = BN_cmp(&group->field, order) > 0;
|
||||
group->field_greater_than_order = BN_cmp(&group->field->N, order) > 0;
|
||||
|
||||
group->generator = EC_POINT_new(group);
|
||||
if (group->generator == NULL) {
|
||||
@ -355,11 +344,8 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = ec_group_new(EC_GFp_mont_method());
|
||||
if (ret == NULL ||
|
||||
!ret->meth->group_set_curve(ret, p, a_reduced, b_reduced, ctx)) {
|
||||
EC_GROUP_free(ret);
|
||||
ret = NULL;
|
||||
ret = ec_group_new(EC_GFp_mont_method(), p, a_reduced, b_reduced, ctx);
|
||||
if (ret == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -403,7 +389,7 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
|
||||
!BN_lshift1(tmp, order)) {
|
||||
goto err;
|
||||
}
|
||||
if (BN_cmp(tmp, &group->field) <= 0) {
|
||||
if (BN_cmp(tmp, &group->field->N) <= 0) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER);
|
||||
goto err;
|
||||
}
|
||||
@ -442,9 +428,8 @@ static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
group = ec_group_new(curve->method);
|
||||
if (group == NULL ||
|
||||
!group->meth->group_set_curve(group, p, a, b, ctx)) {
|
||||
group = ec_group_new(curve->method, p, a, b, ctx);
|
||||
if (group == NULL) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
@ -453,11 +438,8 @@ static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) {
|
||||
EC_FELEM x, y;
|
||||
if (!ec_felem_from_bytes(group, &x, params + 3 * param_len, param_len) ||
|
||||
!ec_felem_from_bytes(group, &y, params + 4 * param_len, param_len) ||
|
||||
!ec_point_set_affine_coordinates(group, &G, &x, &y)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!ec_group_set_generator(group, &G, order)) {
|
||||
!ec_point_set_affine_coordinates(group, &G, &x, &y) ||
|
||||
!ec_group_set_generator(group, &G, order)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -539,13 +521,9 @@ void EC_GROUP_free(EC_GROUP *group) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (group->meth->group_finish != NULL) {
|
||||
group->meth->group_finish(group);
|
||||
}
|
||||
|
||||
ec_point_free(group->generator, 0 /* don't free group */);
|
||||
BN_MONT_CTX_free(group->order);
|
||||
|
||||
BN_MONT_CTX_free(group->field);
|
||||
OPENSSL_free(group);
|
||||
}
|
||||
|
||||
@ -584,7 +562,7 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) {
|
||||
a->generator == NULL ||
|
||||
b->generator == NULL ||
|
||||
BN_cmp(&a->order->N, &b->order->N) != 0 ||
|
||||
BN_cmp(&a->field, &b->field) != 0 ||
|
||||
BN_cmp(&a->field->N, &b->field->N) != 0 ||
|
||||
!ec_felem_equal(a, &a->a, &b->a) ||
|
||||
!ec_felem_equal(a, &a->b, &b->b) ||
|
||||
!ec_GFp_simple_points_equal(a, &a->generator->raw, &b->generator->raw);
|
||||
@ -624,7 +602,7 @@ int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a,
|
||||
int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; }
|
||||
|
||||
unsigned EC_GROUP_get_degree(const EC_GROUP *group) {
|
||||
return BN_num_bits(&group->field);
|
||||
return BN_num_bits(&group->field->N);
|
||||
}
|
||||
|
||||
const char *EC_curve_nid2nist(int nid) {
|
||||
@ -1184,7 +1162,7 @@ int ec_get_x_coordinate_as_scalar(const EC_GROUP *group, EC_SCALAR *out,
|
||||
int ec_get_x_coordinate_as_bytes(const EC_GROUP *group, uint8_t *out,
|
||||
size_t *out_len, size_t max_out,
|
||||
const EC_JACOBIAN *p) {
|
||||
size_t len = BN_num_bytes(&group->field);
|
||||
size_t len = BN_num_bytes(&group->field->N);
|
||||
assert(len <= EC_MAX_BYTES);
|
||||
if (max_out < len) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL);
|
||||
|
@ -76,67 +76,35 @@
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
int ec_GFp_mont_group_init(EC_GROUP *group) {
|
||||
int ok;
|
||||
|
||||
ok = ec_GFp_simple_group_init(group);
|
||||
group->mont = NULL;
|
||||
return ok;
|
||||
}
|
||||
|
||||
void ec_GFp_mont_group_finish(EC_GROUP *group) {
|
||||
BN_MONT_CTX_free(group->mont);
|
||||
group->mont = NULL;
|
||||
ec_GFp_simple_group_finish(group);
|
||||
}
|
||||
|
||||
int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p,
|
||||
const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) {
|
||||
BN_MONT_CTX_free(group->mont);
|
||||
group->mont = BN_MONT_CTX_new_for_modulus(p, ctx);
|
||||
if (group->mont == NULL) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ec_GFp_simple_group_set_curve(group, p, a, b, ctx)) {
|
||||
BN_MONT_CTX_free(group->mont);
|
||||
group->mont = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void ec_GFp_mont_felem_to_montgomery(const EC_GROUP *group,
|
||||
EC_FELEM *out, const EC_FELEM *in) {
|
||||
bn_to_montgomery_small(out->words, in->words, group->field.width,
|
||||
group->mont);
|
||||
bn_to_montgomery_small(out->words, in->words, group->field->N.width,
|
||||
group->field);
|
||||
}
|
||||
|
||||
static void ec_GFp_mont_felem_from_montgomery(const EC_GROUP *group,
|
||||
EC_FELEM *out,
|
||||
const EC_FELEM *in) {
|
||||
bn_from_montgomery_small(out->words, group->field.width, in->words,
|
||||
group->field.width, group->mont);
|
||||
bn_from_montgomery_small(out->words, group->field->N.width, in->words,
|
||||
group->field->N.width, group->field);
|
||||
}
|
||||
|
||||
static void ec_GFp_mont_felem_inv0(const EC_GROUP *group, EC_FELEM *out,
|
||||
const EC_FELEM *a) {
|
||||
bn_mod_inverse0_prime_mont_small(out->words, a->words, group->field.width,
|
||||
group->mont);
|
||||
bn_mod_inverse0_prime_mont_small(out->words, a->words, group->field->N.width,
|
||||
group->field);
|
||||
}
|
||||
|
||||
void ec_GFp_mont_felem_mul(const EC_GROUP *group, EC_FELEM *r,
|
||||
const EC_FELEM *a, const EC_FELEM *b) {
|
||||
bn_mod_mul_montgomery_small(r->words, a->words, b->words, group->field.width,
|
||||
group->mont);
|
||||
bn_mod_mul_montgomery_small(r->words, a->words, b->words,
|
||||
group->field->N.width, group->field);
|
||||
}
|
||||
|
||||
void ec_GFp_mont_felem_sqr(const EC_GROUP *group, EC_FELEM *r,
|
||||
const EC_FELEM *a) {
|
||||
bn_mod_mul_montgomery_small(r->words, a->words, a->words, group->field.width,
|
||||
group->mont);
|
||||
bn_mod_mul_montgomery_small(r->words, a->words, a->words,
|
||||
group->field->N.width, group->field);
|
||||
}
|
||||
|
||||
void ec_GFp_mont_felem_to_bytes(const EC_GROUP *group, uint8_t *out,
|
||||
@ -159,8 +127,8 @@ int ec_GFp_mont_felem_from_bytes(const EC_GROUP *group, EC_FELEM *out,
|
||||
void ec_GFp_mont_felem_reduce(const EC_GROUP *group, EC_FELEM *out,
|
||||
const BN_ULONG *words, size_t num) {
|
||||
// Convert "from" Montgomery form so the value is reduced mod p.
|
||||
bn_from_montgomery_small(out->words, group->field.width, words, num,
|
||||
group->mont);
|
||||
bn_from_montgomery_small(out->words, group->field->N.width, words, num,
|
||||
group->field);
|
||||
// Convert "to" Montgomery form to remove the R^-1 factor added.
|
||||
ec_GFp_mont_felem_to_montgomery(group, out, out);
|
||||
// Convert to Montgomery form to match this implementation's representation.
|
||||
@ -170,8 +138,8 @@ void ec_GFp_mont_felem_reduce(const EC_GROUP *group, EC_FELEM *out,
|
||||
void ec_GFp_mont_felem_exp(const EC_GROUP *group, EC_FELEM *out,
|
||||
const EC_FELEM *a, const BN_ULONG *exp,
|
||||
size_t num_exp) {
|
||||
bn_mod_exp_mont_small(out->words, a->words, group->field.width, exp, num_exp,
|
||||
group->mont);
|
||||
bn_mod_exp_mont_small(out->words, a->words, group->field->N.width, exp,
|
||||
num_exp, group->field);
|
||||
}
|
||||
|
||||
static int ec_GFp_mont_point_get_affine_coordinates(const EC_GROUP *group,
|
||||
@ -457,7 +425,7 @@ static int ec_GFp_mont_cmp_x_coordinate(const EC_GROUP *group,
|
||||
const EC_JACOBIAN *p,
|
||||
const EC_SCALAR *r) {
|
||||
if (!group->field_greater_than_order ||
|
||||
group->field.width != group->order->N.width) {
|
||||
group->field->N.width != group->order->N.width) {
|
||||
// Do not bother optimizing this case. p > order in all commonly-used
|
||||
// curves.
|
||||
return ec_GFp_simple_cmp_x_coordinate(group, p, r);
|
||||
@ -473,7 +441,8 @@ static int ec_GFp_mont_cmp_x_coordinate(const EC_GROUP *group,
|
||||
EC_FELEM r_Z2, Z2_mont, X;
|
||||
ec_GFp_mont_felem_mul(group, &Z2_mont, &p->Z, &p->Z);
|
||||
// r < order < p, so this is valid.
|
||||
OPENSSL_memcpy(r_Z2.words, r->words, group->field.width * sizeof(BN_ULONG));
|
||||
OPENSSL_memcpy(r_Z2.words, r->words,
|
||||
group->field->N.width * sizeof(BN_ULONG));
|
||||
ec_GFp_mont_felem_mul(group, &r_Z2, &r_Z2, &Z2_mont);
|
||||
ec_GFp_mont_felem_from_montgomery(group, &X, &p->X);
|
||||
|
||||
@ -485,10 +454,10 @@ static int ec_GFp_mont_cmp_x_coordinate(const EC_GROUP *group,
|
||||
// Therefore there is a small possibility, less than 1/2^128, that group_order
|
||||
// < p.x < P. in that case we need not only to compare against |r| but also to
|
||||
// compare against r+group_order.
|
||||
BN_ULONG carry =
|
||||
bn_add_words(r_Z2.words, r->words, group->order->N.d, group->field.width);
|
||||
if (carry == 0 &&
|
||||
bn_less_than_words(r_Z2.words, group->field.d, group->field.width)) {
|
||||
BN_ULONG carry = bn_add_words(r_Z2.words, r->words, group->order->N.d,
|
||||
group->field->N.width);
|
||||
if (carry == 0 && bn_less_than_words(r_Z2.words, group->field->N.d,
|
||||
group->field->N.width)) {
|
||||
// r + group_order < p, so compare (r + group_order) * Z^2 against X.
|
||||
ec_GFp_mont_felem_mul(group, &r_Z2, &r_Z2, &Z2_mont);
|
||||
if (ec_felem_equal(group, &r_Z2, &X)) {
|
||||
@ -500,9 +469,6 @@ static int ec_GFp_mont_cmp_x_coordinate(const EC_GROUP *group,
|
||||
}
|
||||
|
||||
DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_mont_method) {
|
||||
out->group_init = ec_GFp_mont_group_init;
|
||||
out->group_finish = ec_GFp_mont_group_finish;
|
||||
out->group_set_curve = ec_GFp_mont_group_set_curve;
|
||||
out->point_get_affine_coordinates = ec_GFp_mont_point_get_affine_coordinates;
|
||||
out->jacobian_to_affine_batch = ec_GFp_mont_jacobian_to_affine_batch;
|
||||
out->add = ec_GFp_mont_add;
|
||||
|
@ -25,10 +25,10 @@
|
||||
|
||||
int ec_bignum_to_felem(const EC_GROUP *group, EC_FELEM *out, const BIGNUM *in) {
|
||||
uint8_t bytes[EC_MAX_BYTES];
|
||||
size_t len = BN_num_bytes(&group->field);
|
||||
size_t len = BN_num_bytes(&group->field->N);
|
||||
assert(sizeof(bytes) >= len);
|
||||
if (BN_is_negative(in) ||
|
||||
BN_cmp(in, &group->field) >= 0 ||
|
||||
BN_cmp(in, &group->field->N) >= 0 ||
|
||||
!BN_bn2bin_padded(bytes, len, in)) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE);
|
||||
return 0;
|
||||
@ -57,11 +57,11 @@ int ec_felem_from_bytes(const EC_GROUP *group, EC_FELEM *out, const uint8_t *in,
|
||||
void ec_felem_neg(const EC_GROUP *group, EC_FELEM *out, const EC_FELEM *a) {
|
||||
// -a is zero if a is zero and p-a otherwise.
|
||||
BN_ULONG mask = ec_felem_non_zero_mask(group, a);
|
||||
BN_ULONG borrow =
|
||||
bn_sub_words(out->words, group->field.d, a->words, group->field.width);
|
||||
BN_ULONG borrow = bn_sub_words(out->words, group->field->N.d, a->words,
|
||||
group->field->N.width);
|
||||
assert(borrow == 0);
|
||||
(void)borrow;
|
||||
for (int i = 0; i < group->field.width; i++) {
|
||||
for (int i = 0; i < group->field->N.width; i++) {
|
||||
out->words[i] &= mask;
|
||||
}
|
||||
}
|
||||
@ -69,20 +69,20 @@ void ec_felem_neg(const EC_GROUP *group, EC_FELEM *out, const EC_FELEM *a) {
|
||||
void ec_felem_add(const EC_GROUP *group, EC_FELEM *out, const EC_FELEM *a,
|
||||
const EC_FELEM *b) {
|
||||
EC_FELEM tmp;
|
||||
bn_mod_add_words(out->words, a->words, b->words, group->field.d, tmp.words,
|
||||
group->field.width);
|
||||
bn_mod_add_words(out->words, a->words, b->words, group->field->N.d, tmp.words,
|
||||
group->field->N.width);
|
||||
}
|
||||
|
||||
void ec_felem_sub(const EC_GROUP *group, EC_FELEM *out, const EC_FELEM *a,
|
||||
const EC_FELEM *b) {
|
||||
EC_FELEM tmp;
|
||||
bn_mod_sub_words(out->words, a->words, b->words, group->field.d, tmp.words,
|
||||
group->field.width);
|
||||
bn_mod_sub_words(out->words, a->words, b->words, group->field->N.d, tmp.words,
|
||||
group->field->N.width);
|
||||
}
|
||||
|
||||
BN_ULONG ec_felem_non_zero_mask(const EC_GROUP *group, const EC_FELEM *a) {
|
||||
BN_ULONG mask = 0;
|
||||
for (int i = 0; i < group->field.width; i++) {
|
||||
for (int i = 0; i < group->field->N.width; i++) {
|
||||
mask |= a->words[i];
|
||||
}
|
||||
return ~constant_time_is_zero_w(mask);
|
||||
@ -90,11 +90,11 @@ BN_ULONG ec_felem_non_zero_mask(const EC_GROUP *group, const EC_FELEM *a) {
|
||||
|
||||
void ec_felem_select(const EC_GROUP *group, EC_FELEM *out, BN_ULONG mask,
|
||||
const EC_FELEM *a, const EC_FELEM *b) {
|
||||
bn_select_words(out->words, mask, a->words, b->words, group->field.width);
|
||||
bn_select_words(out->words, mask, a->words, b->words, group->field->N.width);
|
||||
}
|
||||
|
||||
int ec_felem_equal(const EC_GROUP *group, const EC_FELEM *a,
|
||||
const EC_FELEM *b) {
|
||||
return CRYPTO_memcmp(a->words, b->words,
|
||||
group->field.width * sizeof(BN_ULONG)) == 0;
|
||||
group->field->N.width * sizeof(BN_ULONG)) == 0;
|
||||
}
|
||||
|
@ -472,11 +472,6 @@ int ec_affine_jacobian_equal(const EC_GROUP *group, const EC_AFFINE *a,
|
||||
// Implementation details.
|
||||
|
||||
struct ec_method_st {
|
||||
int (*group_init)(EC_GROUP *);
|
||||
void (*group_finish)(EC_GROUP *);
|
||||
int (*group_set_curve)(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *);
|
||||
|
||||
// point_get_affine_coordinates sets |*x| and |*y| to the affine coordinates
|
||||
// of |p|. Either |x| or |y| may be NULL to omit it. It returns one on success
|
||||
// and zero if |p| is the point at infinity. It leaks whether |p| was the
|
||||
@ -596,16 +591,13 @@ struct ec_group_st {
|
||||
// and Y are suitable for use as an |EC_AFFINE|.
|
||||
EC_POINT *generator;
|
||||
|
||||
int curve_name; // optional NID for named curve
|
||||
|
||||
BN_MONT_CTX *order;
|
||||
|
||||
// The following members are handled by the method functions,
|
||||
// even if they appear generic
|
||||
|
||||
BIGNUM field; // For curves over GF(p), this is the modulus.
|
||||
BN_MONT_CTX *field;
|
||||
|
||||
EC_FELEM a, b; // Curve coefficients.
|
||||
EC_FELEM one; // The value one.
|
||||
|
||||
int curve_name; // optional NID for named curve
|
||||
|
||||
// a_is_minus3 is one if |a| is -3 mod |field| and zero otherwise. Point
|
||||
// arithmetic is optimized for -3.
|
||||
@ -616,10 +608,6 @@ struct ec_group_st {
|
||||
int field_greater_than_order;
|
||||
|
||||
CRYPTO_refcount_t references;
|
||||
|
||||
BN_MONT_CTX *mont; // Montgomery structure.
|
||||
|
||||
EC_FELEM one; // The value one.
|
||||
} /* EC_GROUP */;
|
||||
|
||||
struct ec_point_st {
|
||||
@ -633,7 +621,8 @@ struct ec_point_st {
|
||||
EC_JACOBIAN raw;
|
||||
} /* EC_POINT */;
|
||||
|
||||
EC_GROUP *ec_group_new(const EC_METHOD *meth);
|
||||
EC_GROUP *ec_group_new(const EC_METHOD *meth, const BIGNUM *p, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *ctx);
|
||||
|
||||
void ec_GFp_mont_mul(const EC_GROUP *group, EC_JACOBIAN *r,
|
||||
const EC_JACOBIAN *p, const EC_SCALAR *scalar);
|
||||
@ -672,8 +661,6 @@ int ec_GFp_mont_mul_public_batch(const EC_GROUP *group, EC_JACOBIAN *r,
|
||||
const EC_SCALAR *scalars, size_t num);
|
||||
|
||||
// method functions in simple.c
|
||||
int ec_GFp_simple_group_init(EC_GROUP *);
|
||||
void ec_GFp_simple_group_finish(EC_GROUP *);
|
||||
int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *);
|
||||
int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
|
||||
@ -705,10 +692,6 @@ int ec_GFp_simple_felem_from_bytes(const EC_GROUP *group, EC_FELEM *out,
|
||||
const uint8_t *in, size_t len);
|
||||
|
||||
// method functions in montgomery.c
|
||||
int ec_GFp_mont_group_init(EC_GROUP *);
|
||||
int ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *);
|
||||
void ec_GFp_mont_group_finish(EC_GROUP *);
|
||||
void ec_GFp_mont_felem_mul(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a,
|
||||
const EC_FELEM *b);
|
||||
void ec_GFp_mont_felem_sqr(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a);
|
||||
|
@ -80,7 +80,7 @@ size_t ec_point_byte_len(const EC_GROUP *group, point_conversion_form_t form) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const size_t field_len = BN_num_bytes(&group->field);
|
||||
const size_t field_len = BN_num_bytes(&group->field->N);
|
||||
size_t output_len = 1 /* type byte */ + field_len;
|
||||
if (form == POINT_CONVERSION_UNCOMPRESSED) {
|
||||
// Uncompressed points have a second coordinate.
|
||||
@ -100,11 +100,11 @@ size_t ec_point_to_bytes(const EC_GROUP *group, const EC_AFFINE *point,
|
||||
|
||||
size_t field_len;
|
||||
ec_felem_to_bytes(group, buf + 1, &field_len, &point->X);
|
||||
assert(field_len == BN_num_bytes(&group->field));
|
||||
assert(field_len == BN_num_bytes(&group->field->N));
|
||||
|
||||
if (form == POINT_CONVERSION_UNCOMPRESSED) {
|
||||
ec_felem_to_bytes(group, buf + 1 + field_len, &field_len, &point->Y);
|
||||
assert(field_len == BN_num_bytes(&group->field));
|
||||
assert(field_len == BN_num_bytes(&group->field->N));
|
||||
buf[0] = form;
|
||||
} else {
|
||||
uint8_t y_buf[EC_MAX_BYTES];
|
||||
@ -117,7 +117,7 @@ size_t ec_point_to_bytes(const EC_GROUP *group, const EC_AFFINE *point,
|
||||
|
||||
int ec_point_from_uncompressed(const EC_GROUP *group, EC_AFFINE *out,
|
||||
const uint8_t *in, size_t len) {
|
||||
const size_t field_len = BN_num_bytes(&group->field);
|
||||
const size_t field_len = BN_num_bytes(&group->field->N);
|
||||
if (len != 1 + 2 * field_len || in[0] != POINT_CONVERSION_UNCOMPRESSED) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
|
||||
return 0;
|
||||
@ -155,7 +155,7 @@ static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
|
||||
}
|
||||
|
||||
const int y_bit = form & 1;
|
||||
const size_t field_len = BN_num_bytes(&group->field);
|
||||
const size_t field_len = BN_num_bytes(&group->field->N);
|
||||
form = form & ~1u;
|
||||
if (form != POINT_CONVERSION_COMPRESSED ||
|
||||
len != 1 /* type byte */ + field_len) {
|
||||
@ -182,7 +182,7 @@ static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
|
||||
if (x == NULL || !BN_bin2bn(buf + 1, field_len, x)) {
|
||||
goto err;
|
||||
}
|
||||
if (BN_ucmp(x, &group->field) >= 0) {
|
||||
if (BN_ucmp(x, &group->field->N) >= 0) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
|
||||
goto err;
|
||||
}
|
||||
@ -260,7 +260,8 @@ int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (BN_is_negative(x) || BN_cmp(x, &group->field) >= 0) {
|
||||
const BIGNUM *field = &group->field->N;
|
||||
if (BN_is_negative(x) || BN_cmp(x, field) >= 0) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSED_POINT);
|
||||
return 0;
|
||||
}
|
||||
@ -295,31 +296,31 @@ int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group,
|
||||
// so y is one of the square roots of x^3 + a*x + b.
|
||||
|
||||
// tmp1 := x^3
|
||||
if (!BN_mod_sqr(tmp2, x, &group->field, ctx) ||
|
||||
!BN_mod_mul(tmp1, tmp2, x, &group->field, ctx)) {
|
||||
if (!BN_mod_sqr(tmp2, x, field, ctx) ||
|
||||
!BN_mod_mul(tmp1, tmp2, x, field, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
// tmp1 := tmp1 + a*x
|
||||
if (group->a_is_minus3) {
|
||||
if (!bn_mod_lshift1_consttime(tmp2, x, &group->field, ctx) ||
|
||||
!bn_mod_add_consttime(tmp2, tmp2, x, &group->field, ctx) ||
|
||||
!bn_mod_sub_consttime(tmp1, tmp1, tmp2, &group->field, ctx)) {
|
||||
if (!bn_mod_lshift1_consttime(tmp2, x, field, ctx) ||
|
||||
!bn_mod_add_consttime(tmp2, tmp2, x, field, ctx) ||
|
||||
!bn_mod_sub_consttime(tmp1, tmp1, tmp2, field, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
if (!BN_mod_mul(tmp2, a, x, &group->field, ctx) ||
|
||||
!bn_mod_add_consttime(tmp1, tmp1, tmp2, &group->field, ctx)) {
|
||||
if (!BN_mod_mul(tmp2, a, x, field, ctx) ||
|
||||
!bn_mod_add_consttime(tmp1, tmp1, tmp2, field, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
// tmp1 := tmp1 + b
|
||||
if (!bn_mod_add_consttime(tmp1, tmp1, b, &group->field, ctx)) {
|
||||
if (!bn_mod_add_consttime(tmp1, tmp1, b, field, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BN_mod_sqrt(y, tmp1, &group->field, ctx)) {
|
||||
if (!BN_mod_sqrt(y, tmp1, field, ctx)) {
|
||||
uint32_t err = ERR_peek_last_error();
|
||||
if (ERR_GET_LIB(err) == ERR_LIB_BN &&
|
||||
ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) {
|
||||
@ -336,7 +337,7 @@ int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group,
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSION_BIT);
|
||||
goto err;
|
||||
}
|
||||
if (!BN_usub(y, &group->field, y)) {
|
||||
if (!BN_usub(y, field, y)) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
@ -1142,9 +1142,6 @@ static void ec_GFp_nistp224_felem_sqr(const EC_GROUP *group, EC_FELEM *r,
|
||||
}
|
||||
|
||||
DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistp224_method) {
|
||||
out->group_init = ec_GFp_simple_group_init;
|
||||
out->group_finish = ec_GFp_simple_group_finish;
|
||||
out->group_set_curve = ec_GFp_simple_group_set_curve;
|
||||
out->point_get_affine_coordinates =
|
||||
ec_GFp_nistp224_point_get_affine_coordinates;
|
||||
out->add = ec_GFp_nistp224_add;
|
||||
|
@ -191,7 +191,7 @@ static void ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r,
|
||||
const EC_SCALAR *p_scalar) {
|
||||
assert(p != NULL);
|
||||
assert(p_scalar != NULL);
|
||||
assert(group->field.width == P256_LIMBS);
|
||||
assert(group->field->N.width == P256_LIMBS);
|
||||
|
||||
static const size_t kWindowSize = 5;
|
||||
static const crypto_word_t kMask = (1 << (5 /* kWindowSize */ + 1)) - 1;
|
||||
@ -208,7 +208,7 @@ static void ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r,
|
||||
// not stored. All other values are actually stored with an offset of -1 in
|
||||
// table.
|
||||
P256_POINT *row = table;
|
||||
assert(group->field.width == P256_LIMBS);
|
||||
assert(group->field->N.width == P256_LIMBS);
|
||||
OPENSSL_memcpy(row[1 - 1].X, p->X.words, P256_LIMBS * sizeof(BN_ULONG));
|
||||
OPENSSL_memcpy(row[1 - 1].Y, p->Y.words, P256_LIMBS * sizeof(BN_ULONG));
|
||||
OPENSSL_memcpy(row[1 - 1].Z, p->Z.words, P256_LIMBS * sizeof(BN_ULONG));
|
||||
@ -305,7 +305,7 @@ static void ecp_nistz256_point_mul(const EC_GROUP *group, EC_JACOBIAN *r,
|
||||
alignas(32) P256_POINT out;
|
||||
ecp_nistz256_windowed_mul(group, &out, p, scalar);
|
||||
|
||||
assert(group->field.width == P256_LIMBS);
|
||||
assert(group->field->N.width == P256_LIMBS);
|
||||
OPENSSL_memcpy(r->X.words, out.X, P256_LIMBS * sizeof(BN_ULONG));
|
||||
OPENSSL_memcpy(r->Y.words, out.Y, P256_LIMBS * sizeof(BN_ULONG));
|
||||
OPENSSL_memcpy(r->Z.words, out.Z, P256_LIMBS * sizeof(BN_ULONG));
|
||||
@ -349,7 +349,7 @@ static void ecp_nistz256_point_mul_base(const EC_GROUP *group, EC_JACOBIAN *r,
|
||||
ecp_nistz256_point_add_affine(&p, &p, &t);
|
||||
}
|
||||
|
||||
assert(group->field.width == P256_LIMBS);
|
||||
assert(group->field->N.width == P256_LIMBS);
|
||||
OPENSSL_memcpy(r->X.words, p.X, P256_LIMBS * sizeof(BN_ULONG));
|
||||
OPENSSL_memcpy(r->Y.words, p.Y, P256_LIMBS * sizeof(BN_ULONG));
|
||||
OPENSSL_memcpy(r->Z.words, p.Z, P256_LIMBS * sizeof(BN_ULONG));
|
||||
@ -413,7 +413,7 @@ static void ecp_nistz256_points_mul_public(const EC_GROUP *group,
|
||||
ecp_nistz256_windowed_mul(group, &tmp, p_, p_scalar);
|
||||
ecp_nistz256_point_add(&p, &p, &tmp);
|
||||
|
||||
assert(group->field.width == P256_LIMBS);
|
||||
assert(group->field->N.width == P256_LIMBS);
|
||||
OPENSSL_memcpy(r->X.words, p.X, P256_LIMBS * sizeof(BN_ULONG));
|
||||
OPENSSL_memcpy(r->Y.words, p.Y, P256_LIMBS * sizeof(BN_ULONG));
|
||||
OPENSSL_memcpy(r->Z.words, p.Z, P256_LIMBS * sizeof(BN_ULONG));
|
||||
@ -429,7 +429,7 @@ static int ecp_nistz256_get_affine(const EC_GROUP *group,
|
||||
}
|
||||
|
||||
BN_ULONG z_inv2[P256_LIMBS];
|
||||
assert(group->field.width == P256_LIMBS);
|
||||
assert(group->field->N.width == P256_LIMBS);
|
||||
ecp_nistz256_mod_inverse_sqr_mont(z_inv2, point->Z.words);
|
||||
|
||||
if (x != NULL) {
|
||||
@ -581,7 +581,7 @@ static int ecp_nistz256_cmp_x_coordinate(const EC_GROUP *group,
|
||||
}
|
||||
|
||||
assert(group->order->N.width == P256_LIMBS);
|
||||
assert(group->field.width == P256_LIMBS);
|
||||
assert(group->field->N.width == P256_LIMBS);
|
||||
|
||||
// We wish to compare X/Z^2 with r. This is equivalent to comparing X with
|
||||
// r*Z^2. Note that X and Z are represented in Montgomery form, while r is
|
||||
@ -600,7 +600,7 @@ static int ecp_nistz256_cmp_x_coordinate(const EC_GROUP *group,
|
||||
// < p.x < P. in that case we need not only to compare against |r| but also to
|
||||
// compare against r+group_order.
|
||||
BN_ULONG carry = bn_add_words(r_Z2, r->words, group->order->N.d, P256_LIMBS);
|
||||
if (carry == 0 && bn_less_than_words(r_Z2, group->field.d, P256_LIMBS)) {
|
||||
if (carry == 0 && bn_less_than_words(r_Z2, group->field->N.d, P256_LIMBS)) {
|
||||
// r + group_order < p, so compare (r + group_order) * Z^2 against X.
|
||||
ecp_nistz256_mul_mont(r_Z2, r_Z2, Z2_mont);
|
||||
if (OPENSSL_memcmp(r_Z2, X, sizeof(r_Z2)) == 0) {
|
||||
@ -612,9 +612,6 @@ static int ecp_nistz256_cmp_x_coordinate(const EC_GROUP *group,
|
||||
}
|
||||
|
||||
DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistz256_method) {
|
||||
out->group_init = ec_GFp_mont_group_init;
|
||||
out->group_finish = ec_GFp_mont_group_finish;
|
||||
out->group_set_curve = ec_GFp_mont_group_set_curve;
|
||||
out->point_get_affine_coordinates = ecp_nistz256_get_affine;
|
||||
out->add = ecp_nistz256_add;
|
||||
out->dbl = ecp_nistz256_dbl;
|
||||
|
@ -710,12 +710,12 @@ static int ec_GFp_nistp256_cmp_x_coordinate(const EC_GROUP *group,
|
||||
// Therefore there is a small possibility, less than 1/2^128, that group_order
|
||||
// < p.x < P. in that case we need not only to compare against |r| but also to
|
||||
// compare against r+group_order.
|
||||
assert(group->field.width == group->order->N.width);
|
||||
assert(group->field->N.width == group->order->N.width);
|
||||
EC_FELEM tmp;
|
||||
BN_ULONG carry =
|
||||
bn_add_words(tmp.words, r->words, group->order->N.d, group->field.width);
|
||||
BN_ULONG carry = bn_add_words(tmp.words, r->words, group->order->N.d,
|
||||
group->field->N.width);
|
||||
if (carry == 0 &&
|
||||
bn_less_than_words(tmp.words, group->field.d, group->field.width)) {
|
||||
bn_less_than_words(tmp.words, group->field->N.d, group->field->N.width)) {
|
||||
fiat_p256_from_generic(r_Z2, &tmp);
|
||||
fiat_p256_mul(r_Z2, r_Z2, Z2_mont);
|
||||
if (OPENSSL_memcmp(&r_Z2, &X, sizeof(r_Z2)) == 0) {
|
||||
@ -727,9 +727,6 @@ static int ec_GFp_nistp256_cmp_x_coordinate(const EC_GROUP *group,
|
||||
}
|
||||
|
||||
DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistp256_method) {
|
||||
out->group_init = ec_GFp_mont_group_init;
|
||||
out->group_finish = ec_GFp_mont_group_finish;
|
||||
out->group_set_curve = ec_GFp_mont_group_set_curve;
|
||||
out->point_get_affine_coordinates =
|
||||
ec_GFp_nistp256_point_get_affine_coordinates;
|
||||
out->add = ec_GFp_nistp256_add;
|
||||
|
@ -88,16 +88,6 @@
|
||||
// used, it is a Montgomery representation (i.e. 'encoding' means multiplying
|
||||
// by some factor R).
|
||||
|
||||
int ec_GFp_simple_group_init(EC_GROUP *group) {
|
||||
BN_init(&group->field);
|
||||
group->a_is_minus3 = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ec_GFp_simple_group_finish(EC_GROUP *group) {
|
||||
BN_free(&group->field);
|
||||
}
|
||||
|
||||
int ec_GFp_simple_group_set_curve(EC_GROUP *group, const BIGNUM *p,
|
||||
const BIGNUM *a, const BIGNUM *b,
|
||||
BN_CTX *ctx) {
|
||||
@ -114,13 +104,10 @@ int ec_GFp_simple_group_set_curve(EC_GROUP *group, const BIGNUM *p,
|
||||
goto err;
|
||||
}
|
||||
|
||||
// group->field
|
||||
if (!BN_copy(&group->field, p)) {
|
||||
group->field = BN_MONT_CTX_new_for_modulus(p, ctx);
|
||||
if (group->field == NULL) {
|
||||
goto err;
|
||||
}
|
||||
BN_set_negative(&group->field, 0);
|
||||
// Store the field in minimal form, so it can be used with |BN_ULONG| arrays.
|
||||
bn_set_minimal_width(&group->field);
|
||||
|
||||
if (!ec_bignum_to_felem(group, &group->a, a) ||
|
||||
!ec_bignum_to_felem(group, &group->b, b) ||
|
||||
@ -133,7 +120,7 @@ int ec_GFp_simple_group_set_curve(EC_GROUP *group, const BIGNUM *p,
|
||||
!BN_add_word(tmp, 3)) {
|
||||
goto err;
|
||||
}
|
||||
group->a_is_minus3 = (0 == BN_cmp(tmp, &group->field));
|
||||
group->a_is_minus3 = (0 == BN_cmp(tmp, &group->field->N));
|
||||
|
||||
ret = 1;
|
||||
|
||||
@ -144,7 +131,7 @@ err:
|
||||
|
||||
int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
|
||||
BIGNUM *b) {
|
||||
if ((p != NULL && !BN_copy(p, &group->field)) ||
|
||||
if ((p != NULL && !BN_copy(p, &group->field->N)) ||
|
||||
(a != NULL && !ec_felem_to_bignum(group, a, &group->a)) ||
|
||||
(b != NULL && !ec_felem_to_bignum(group, b, &group->b))) {
|
||||
return 0;
|
||||
@ -329,21 +316,22 @@ int ec_GFp_simple_cmp_x_coordinate(const EC_GROUP *group, const EC_JACOBIAN *p,
|
||||
|
||||
void ec_GFp_simple_felem_to_bytes(const EC_GROUP *group, uint8_t *out,
|
||||
size_t *out_len, const EC_FELEM *in) {
|
||||
size_t len = BN_num_bytes(&group->field);
|
||||
bn_words_to_big_endian(out, len, in->words, group->field.width);
|
||||
size_t len = BN_num_bytes(&group->field->N);
|
||||
bn_words_to_big_endian(out, len, in->words, group->field->N.width);
|
||||
*out_len = len;
|
||||
}
|
||||
|
||||
int ec_GFp_simple_felem_from_bytes(const EC_GROUP *group, EC_FELEM *out,
|
||||
const uint8_t *in, size_t len) {
|
||||
if (len != BN_num_bytes(&group->field)) {
|
||||
if (len != BN_num_bytes(&group->field->N)) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bn_big_endian_to_words(out->words, group->field.width, in, len);
|
||||
bn_big_endian_to_words(out->words, group->field->N.width, in, len);
|
||||
|
||||
if (!bn_less_than_words(out->words, group->field.d, group->field.width)) {
|
||||
if (!bn_less_than_words(out->words, group->field->N.d,
|
||||
group->field->N.width)) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ void ec_GFp_mont_mul_batch(const EC_GROUP *group, EC_JACOBIAN *r,
|
||||
}
|
||||
|
||||
static unsigned ec_GFp_mont_comb_stride(const EC_GROUP *group) {
|
||||
return (BN_num_bits(&group->field) + EC_MONT_PRECOMP_COMB_SIZE - 1) /
|
||||
return (EC_GROUP_get_degree(group) + EC_MONT_PRECOMP_COMB_SIZE - 1) /
|
||||
EC_MONT_PRECOMP_COMB_SIZE;
|
||||
}
|
||||
|
||||
|
@ -160,7 +160,7 @@ static int cbs_get_prefixed_point(CBS *cbs, const EC_GROUP *group,
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
size_t plen = 1 + 2 * BN_num_bytes(&group->field);
|
||||
size_t plen = ec_point_byte_len(group, POINT_CONVERSION_UNCOMPRESSED);
|
||||
if (!CBS_get_bytes(cbs, &child, plen)) {
|
||||
return 0;
|
||||
}
|
||||
@ -912,7 +912,7 @@ static int pmbtoken_sign(const PMBTOKEN_METHOD *method,
|
||||
}
|
||||
|
||||
// Skip over any unused requests.
|
||||
size_t point_len = 1 + 2 * BN_num_bytes(&group->field);
|
||||
size_t point_len = ec_point_byte_len(group, POINT_CONVERSION_UNCOMPRESSED);
|
||||
size_t token_len = point_len;
|
||||
if (method->prefix_point) {
|
||||
token_len += 2;
|
||||
@ -1015,7 +1015,7 @@ static STACK_OF(TRUST_TOKEN) *pmbtoken_unblind(
|
||||
// Serialize the token. Include |key_id| to avoid an extra copy in the layer
|
||||
// above.
|
||||
CBB token_cbb;
|
||||
size_t point_len = 1 + 2 * BN_num_bytes(&group->field);
|
||||
size_t point_len = ec_point_byte_len(group, POINT_CONVERSION_UNCOMPRESSED);
|
||||
if (!CBB_init(&token_cbb,
|
||||
4 + TRUST_TOKEN_NONCE_SIZE + 3 * (2 + point_len)) ||
|
||||
!CBB_add_u32(&token_cbb, key_id) ||
|
||||
|
@ -1080,15 +1080,14 @@ TEST_P(TrustTokenMetadataTest, TruncatedProof) {
|
||||
ASSERT_TRUE(CBS_get_u32(&real_response, &parsed_public_metadata));
|
||||
ASSERT_TRUE(CBB_add_u32(bad_response.get(), parsed_public_metadata));
|
||||
|
||||
const EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp384r1);
|
||||
size_t token_length =
|
||||
TRUST_TOKEN_NONCE_SIZE + 2 * (1 + 2 * BN_num_bytes(&group->field));
|
||||
const size_t kP384PointLen = 1 + 2 * (384 / 8);
|
||||
size_t token_length = TRUST_TOKEN_NONCE_SIZE + 2 * kP384PointLen;
|
||||
if (method() == TRUST_TOKEN_experiment_v1()) {
|
||||
token_length += 4;
|
||||
}
|
||||
if (method() == TRUST_TOKEN_experiment_v2_voprf() ||
|
||||
method() == TRUST_TOKEN_pst_v1_voprf()) {
|
||||
token_length = 1 + 2 * BN_num_bytes(&group->field);
|
||||
token_length = kP384PointLen;
|
||||
}
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
ASSERT_TRUE(CBB_add_bytes(bad_response.get(), CBS_data(&real_response),
|
||||
@ -1149,15 +1148,14 @@ TEST_P(TrustTokenMetadataTest, ExcessDataProof) {
|
||||
ASSERT_TRUE(CBS_get_u32(&real_response, &parsed_public_metadata));
|
||||
ASSERT_TRUE(CBB_add_u32(bad_response.get(), parsed_public_metadata));
|
||||
|
||||
const EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp384r1);
|
||||
size_t token_length =
|
||||
TRUST_TOKEN_NONCE_SIZE + 2 * (1 + 2 * BN_num_bytes(&group->field));
|
||||
const size_t kP384PointLen = 1 + 2 * (384 / 8);
|
||||
size_t token_length = TRUST_TOKEN_NONCE_SIZE + 2 * kP384PointLen;
|
||||
if (method() == TRUST_TOKEN_experiment_v1()) {
|
||||
token_length += 4;
|
||||
}
|
||||
if (method() == TRUST_TOKEN_experiment_v2_voprf() ||
|
||||
method() == TRUST_TOKEN_pst_v1_voprf()) {
|
||||
token_length = 1 + 2 * BN_num_bytes(&group->field);
|
||||
token_length = kP384PointLen;
|
||||
}
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
ASSERT_TRUE(CBB_add_bytes(bad_response.get(), CBS_data(&real_response),
|
||||
|
@ -83,7 +83,7 @@ static int cbb_serialize_point(CBB *out, const EC_GROUP *group,
|
||||
|
||||
static int cbs_get_point(CBS *cbs, const EC_GROUP *group, EC_AFFINE *out) {
|
||||
CBS child;
|
||||
size_t plen = 1 + 2 * BN_num_bytes(&group->field);
|
||||
size_t plen = ec_point_byte_len(group, POINT_CONVERSION_UNCOMPRESSED);
|
||||
if (!CBS_get_bytes(cbs, &child, plen) ||
|
||||
!ec_point_from_uncompressed(group, out, CBS_data(&child),
|
||||
CBS_len(&child))) {
|
||||
@ -567,7 +567,7 @@ static int voprf_sign_tt(const VOPRF_METHOD *method,
|
||||
}
|
||||
|
||||
// Skip over any unused requests.
|
||||
size_t point_len = 1 + 2 * BN_num_bytes(&group->field);
|
||||
size_t point_len = ec_point_byte_len(group, POINT_CONVERSION_UNCOMPRESSED);
|
||||
if (!CBS_skip(cbs, point_len * (num_requested - num_to_issue))) {
|
||||
OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
|
||||
goto err;
|
||||
@ -645,7 +645,7 @@ static STACK_OF(TRUST_TOKEN) *voprf_unblind_tt(
|
||||
// Serialize the token. Include |key_id| to avoid an extra copy in the layer
|
||||
// above.
|
||||
CBB token_cbb;
|
||||
size_t point_len = 1 + 2 * BN_num_bytes(&group->field);
|
||||
size_t point_len = ec_point_byte_len(group, POINT_CONVERSION_UNCOMPRESSED);
|
||||
if (!CBB_init(&token_cbb, 4 + TRUST_TOKEN_NONCE_SIZE + (2 + point_len)) ||
|
||||
!CBB_add_u32(&token_cbb, key_id) ||
|
||||
!CBB_add_bytes(&token_cbb, pretoken->salt, TRUST_TOKEN_NONCE_SIZE) ||
|
||||
@ -944,7 +944,7 @@ static int voprf_sign_impl(const VOPRF_METHOD *method,
|
||||
}
|
||||
|
||||
// Skip over any unused requests.
|
||||
size_t point_len = 1 + 2 * BN_num_bytes(&group->field);
|
||||
size_t point_len = ec_point_byte_len(group, POINT_CONVERSION_UNCOMPRESSED);
|
||||
if (!CBS_skip(cbs, point_len * (num_requested - num_to_issue))) {
|
||||
OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
|
||||
goto err;
|
||||
@ -1044,7 +1044,7 @@ static STACK_OF(TRUST_TOKEN) *voprf_unblind(
|
||||
// Serialize the token. Include |key_id| to avoid an extra copy in the layer
|
||||
// above.
|
||||
CBB token_cbb;
|
||||
size_t point_len = 1 + 2 * BN_num_bytes(&group->field);
|
||||
size_t point_len = ec_point_byte_len(group, POINT_CONVERSION_UNCOMPRESSED);
|
||||
if (!CBB_init(&token_cbb, 4 + TRUST_TOKEN_NONCE_SIZE + (2 + point_len)) ||
|
||||
!CBB_add_u32(&token_cbb, key_id) ||
|
||||
!CBB_add_bytes(&token_cbb, pretoken->salt, TRUST_TOKEN_NONCE_SIZE) ||
|
||||
|
Loading…
x
Reference in New Issue
Block a user