diff options
Diffstat (limited to 'src/crypto/fipsmodule/ec/simple.c')
-rw-r--r-- | src/crypto/fipsmodule/ec/simple.c | 239 |
1 files changed, 117 insertions, 122 deletions
diff --git a/src/crypto/fipsmodule/ec/simple.c b/src/crypto/fipsmodule/ec/simple.c index 1a03d84a..75c06da1 100644 --- a/src/crypto/fipsmodule/ec/simple.c +++ b/src/crypto/fipsmodule/ec/simple.c @@ -77,16 +77,16 @@ #include "../../internal.h" -/* Most method functions in this file are designed to work with non-trivial - * representations of field elements if necessary (see ecp_mont.c): while - * standard modular addition and subtraction are used, the field_mul and - * field_sqr methods will be used for multiplication, and field_encode and - * field_decode (if defined) will be used for converting between - * representations. - * - * Functions here specifically assume that if a non-trivial representation is - * used, it is a Montgomery representation (i.e. 'encoding' means multiplying - * by some factor R). */ +// Most method functions in this file are designed to work with non-trivial +// representations of field elements if necessary (see ecp_mont.c): while +// standard modular addition and subtraction are used, the field_mul and +// field_sqr methods will be used for multiplication, and field_encode and +// field_decode (if defined) will be used for converting between +// representations. +// +// Functions here specifically assume that if a non-trivial representation is +// 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); @@ -123,7 +123,7 @@ int ec_GFp_simple_group_set_curve(EC_GROUP *group, const BIGNUM *p, BN_CTX *new_ctx = NULL; BIGNUM *tmp_a; - /* p must be a prime > 3 */ + // p must be a prime > 3 if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) { OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FIELD); return 0; @@ -142,13 +142,13 @@ int ec_GFp_simple_group_set_curve(EC_GROUP *group, const BIGNUM *p, goto err; } - /* group->field */ + // group->field if (!BN_copy(&group->field, p)) { goto err; } BN_set_negative(&group->field, 0); - /* group->a */ + // group->a if (!BN_nnmod(tmp_a, a, p, ctx)) { goto err; } @@ -160,7 +160,7 @@ int ec_GFp_simple_group_set_curve(EC_GROUP *group, const BIGNUM *p, goto err; } - /* group->b */ + // group->b if (!BN_nnmod(&group->b, b, p, ctx)) { goto err; } @@ -169,7 +169,7 @@ int ec_GFp_simple_group_set_curve(EC_GROUP *group, const BIGNUM *p, goto err; } - /* group->a_is_minus3 */ + // group->a_is_minus3 if (!BN_add_word(tmp_a, 3)) { goto err; } @@ -360,7 +360,7 @@ int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) { if (x == NULL || y == NULL) { - /* unlike for projective coordinates, we do not tolerate this */ + // unlike for projective coordinates, we do not tolerate this OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); return 0; } @@ -412,88 +412,87 @@ int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, 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'.) - */ + // 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 int b_Z_is_one = BN_cmp(&b->Z, &group->one) == 0; if (b_Z_is_one) { if (!BN_copy(n1, &a->X) || !BN_copy(n2, &a->Y)) { goto end; } - /* n1 = X_a */ - /* n2 = Y_a */ + // n1 = X_a + // n2 = Y_a } else { if (!field_sqr(group, n0, &b->Z, ctx) || !field_mul(group, n1, &a->X, n0, ctx)) { goto end; } - /* n1 = X_a * Z_b^2 */ + // n1 = X_a * Z_b^2 if (!field_mul(group, n0, n0, &b->Z, ctx) || !field_mul(group, n2, &a->Y, n0, ctx)) { goto end; } - /* n2 = Y_a * Z_b^3 */ + // n2 = Y_a * Z_b^3 } - /* n3, n4 */ + // n3, n4 int a_Z_is_one = BN_cmp(&a->Z, &group->one) == 0; if (a_Z_is_one) { if (!BN_copy(n3, &b->X) || !BN_copy(n4, &b->Y)) { goto end; } - /* n3 = X_b */ - /* n4 = Y_b */ + // n3 = X_b + // n4 = Y_b } else { if (!field_sqr(group, n0, &a->Z, ctx) || !field_mul(group, n3, &b->X, n0, ctx)) { goto end; } - /* n3 = X_b * Z_a^2 */ + // n3 = X_b * Z_a^2 if (!field_mul(group, n0, n0, &a->Z, ctx) || !field_mul(group, n4, &b->Y, n0, ctx)) { goto end; } - /* n4 = Y_b * Z_a^3 */ + // n4 = Y_b * Z_a^3 } - /* n5, n6 */ + // n5, n6 if (!BN_mod_sub_quick(n5, n1, n3, p) || !BN_mod_sub_quick(n6, n2, n4, p)) { goto end; } - /* n5 = n1 - n3 */ - /* n6 = n2 - n4 */ + // n5 = n1 - n3 + // n6 = n2 - n4 if (BN_is_zero(n5)) { if (BN_is_zero(n6)) { - /* a is the same point as b */ + // a is the same point as b BN_CTX_end(ctx); ret = EC_POINT_dbl(group, r, a, ctx); ctx = NULL; goto end; } else { - /* a is the inverse of b */ + // a is the inverse of b BN_zero(&r->Z); ret = 1; goto end; } } - /* 'n7', 'n8' */ + // 'n7', 'n8' if (!BN_mod_add_quick(n1, n1, n3, p) || !BN_mod_add_quick(n2, n2, n4, p)) { goto end; } - /* 'n7' = n1 + n3 */ - /* 'n8' = n2 + n4 */ + // 'n7' = n1 + n3 + // 'n8' = n2 + n4 - /* Z_r */ + // Z_r if (a_Z_is_one && b_Z_is_one) { if (!BN_copy(&r->Z, n5)) { goto end; @@ -515,28 +514,28 @@ int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, } } - /* Z_r = Z_a * Z_b * n5 */ + // Z_r = Z_a * Z_b * n5 - /* X_r */ + // X_r if (!field_sqr(group, n0, n6, ctx) || !field_sqr(group, n4, n5, ctx) || !field_mul(group, n3, n1, n4, ctx) || !BN_mod_sub_quick(&r->X, n0, n3, p)) { goto end; } - /* X_r = n6^2 - n5^2 * 'n7' */ + // X_r = n6^2 - n5^2 * 'n7' - /* 'n9' */ + // 'n9' if (!BN_mod_lshift1_quick(n0, &r->X, p) || !BN_mod_sub_quick(n0, n3, n0, p)) { goto end; } - /* n9 = n5^2 * 'n7' - 2 * X_r */ + // n9 = n5^2 * 'n7' - 2 * X_r - /* Y_r */ + // Y_r if (!field_mul(group, n0, n0, n6, ctx) || !field_mul(group, n5, n4, n5, ctx)) { - goto end; /* now n5 is n5^3 */ + goto end; // now n5 is n5^3 } if (!field_mul(group, n1, n2, n5, ctx) || !BN_mod_sub_quick(n0, n0, n1, p)) { @@ -545,17 +544,17 @@ int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, if (BN_is_odd(n0) && !BN_add(n0, n0, p)) { goto end; } - /* now 0 <= n0 < 2*p, and n0 is even */ + // now 0 <= n0 < 2*p, and n0 is even if (!BN_rshift1(&r->Y, n0)) { goto end; } - /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */ + // Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 ret = 1; end: if (ctx) { - /* otherwise we already called BN_CTX_end */ + // otherwise we already called BN_CTX_end BN_CTX_end(ctx); } BN_CTX_free(new_ctx); @@ -597,12 +596,11 @@ int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, 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'.) - */ + // 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 (BN_cmp(&a->Z, &group->one) == 0) { if (!field_sqr(group, n0, &a->X, ctx) || !BN_mod_lshift1_quick(n1, n0, p) || @@ -610,7 +608,7 @@ int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, !BN_mod_add_quick(n1, n0, &group->a, p)) { goto err; } - /* n1 = 3 * X_a^2 + a_curve */ + // n1 = 3 * X_a^2 + a_curve } else if (group->a_is_minus3) { if (!field_sqr(group, n1, &a->Z, ctx) || !BN_mod_add_quick(n0, &a->X, n1, p) || @@ -620,8 +618,8 @@ int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, !BN_mod_add_quick(n1, n0, n1, p)) { goto err; } - /* n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2) - * = 3 * X_a^2 - 3 * Z_a^4 */ + // n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2) + // = 3 * X_a^2 - 3 * Z_a^4 } else { if (!field_sqr(group, n0, &a->X, ctx) || !BN_mod_lshift1_quick(n1, n0, p) || @@ -632,10 +630,10 @@ int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, !BN_mod_add_quick(n1, n1, n0, p)) { goto err; } - /* n1 = 3 * X_a^2 + a_curve * Z_a^4 */ + // n1 = 3 * X_a^2 + a_curve * Z_a^4 } - /* Z_r */ + // Z_r if (BN_cmp(&a->Z, &group->one) == 0) { if (!BN_copy(n0, &a->Y)) { goto err; @@ -646,38 +644,38 @@ int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, if (!BN_mod_lshift1_quick(&r->Z, n0, p)) { goto err; } - /* Z_r = 2 * Y_a * Z_a */ + // Z_r = 2 * Y_a * Z_a - /* n2 */ + // n2 if (!field_sqr(group, n3, &a->Y, ctx) || !field_mul(group, n2, &a->X, n3, ctx) || !BN_mod_lshift_quick(n2, n2, 2, p)) { goto err; } - /* n2 = 4 * X_a * Y_a^2 */ + // n2 = 4 * X_a * Y_a^2 - /* X_r */ + // X_r if (!BN_mod_lshift1_quick(n0, n2, p) || !field_sqr(group, &r->X, n1, ctx) || !BN_mod_sub_quick(&r->X, &r->X, n0, p)) { goto err; } - /* X_r = n1^2 - 2 * n2 */ + // X_r = n1^2 - 2 * n2 - /* n3 */ + // n3 if (!field_sqr(group, n0, n3, ctx) || !BN_mod_lshift_quick(n3, n0, 3, p)) { goto err; } - /* n3 = 8 * Y_a^4 */ + // n3 = 8 * Y_a^4 - /* Y_r */ + // Y_r if (!BN_mod_sub_quick(n0, n2, &r->X, p) || !field_mul(group, n0, n1, n0, ctx) || !BN_mod_sub_quick(&r->Y, n0, n3, p)) { goto err; } - /* Y_r = n1 * (n2 - X_r) - n3 */ + // Y_r = n1 * (n2 - X_r) - n3 ret = 1; @@ -689,7 +687,7 @@ err: int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) { if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y)) { - /* point is its own inverse */ + // point is its own inverse return 1; } @@ -734,17 +732,16 @@ int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, goto err; } - /* We have a curve defined by a Weierstrass equation - * y^2 = x^3 + a*x + b. - * The point to consider is given in Jacobian projective coordinates - * where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3). - * Substituting this and multiplying by Z^6 transforms the above equation - * into - * Y^2 = X^3 + a*X*Z^4 + b*Z^6. - * To test this, we add up the right-hand side in 'rh'. - */ + // We have a curve defined by a Weierstrass equation + // y^2 = x^3 + a*x + b. + // The point to consider is given in Jacobian projective coordinates + // where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3). + // Substituting this and multiplying by Z^6 transforms the above equation + // into + // Y^2 = X^3 + a*X*Z^4 + b*Z^6. + // To test this, we add up the right-hand side in 'rh'. - /* rh := X^2 */ + // rh := X^2 if (!field_sqr(group, rh, &point->X, ctx)) { goto err; } @@ -756,7 +753,7 @@ int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, goto err; } - /* rh := (rh + a*Z^4)*X */ + // rh := (rh + a*Z^4)*X if (group->a_is_minus3) { if (!BN_mod_lshift1_quick(tmp, Z4, p) || !BN_mod_add_quick(tmp, tmp, Z4, p) || @@ -772,24 +769,24 @@ int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, } } - /* rh := rh + b*Z^6 */ + // rh := rh + b*Z^6 if (!field_mul(group, tmp, &group->b, Z6, ctx) || !BN_mod_add_quick(rh, rh, tmp, p)) { goto err; } } else { - /* rh := (rh + a)*X */ + // rh := (rh + a)*X if (!BN_mod_add_quick(rh, rh, &group->a, p) || !field_mul(group, rh, rh, &point->X, ctx)) { goto err; } - /* rh := rh + b */ + // rh := rh + b if (!BN_mod_add_quick(rh, rh, &group->b, p)) { goto err; } } - /* 'lh' := Y^2 */ + // 'lh' := Y^2 if (!field_sqr(group, tmp, &point->Y, ctx)) { goto err; } @@ -804,11 +801,10 @@ err: int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) { - /* return values: - * -1 error - * 0 equal (in affine coordinates) - * 1 not equal - */ + // return values: + // -1 error + // 0 equal (in affine coordinates) + // 1 not equal int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); @@ -852,11 +848,10 @@ int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, goto end; } - /* We have to decide whether - * (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3), - * or equivalently, whether - * (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3). - */ + // We have to decide whether + // (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3), + // or equivalently, whether + // (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3). if (!b_Z_is_one) { if (!field_sqr(group, Zb23, &b->Z, ctx) || @@ -877,9 +872,9 @@ int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, tmp2_ = &b->X; } - /* compare X_a*Z_b^2 with X_b*Z_a^2 */ + // compare X_a*Z_b^2 with X_b*Z_a^2 if (BN_cmp(tmp1_, tmp2_) != 0) { - ret = 1; /* points differ */ + ret = 1; // points differ goto end; } @@ -889,7 +884,7 @@ int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, !field_mul(group, tmp1, &a->Y, Zb23, ctx)) { goto end; } - /* tmp1_ = tmp1 */ + // tmp1_ = tmp1 } else { tmp1_ = &a->Y; } @@ -898,18 +893,18 @@ int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, !field_mul(group, tmp2, &b->Y, Za23, ctx)) { goto end; } - /* tmp2_ = tmp2 */ + // tmp2_ = tmp2 } else { tmp2_ = &b->Y; } - /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */ + // compare Y_a*Z_b^3 with Y_b*Z_a^3 if (BN_cmp(tmp1_, tmp2_) != 0) { - ret = 1; /* points differ */ + ret = 1; // points differ goto end; } - /* points are equal */ + // points are equal ret = 0; end: @@ -997,8 +992,8 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, } } - /* Set each prod_Z[i] to the product of points[0]->Z .. points[i]->Z, - * skipping any zero-valued inputs (pretend that they're 1). */ + // Set each prod_Z[i] to the product of points[0]->Z .. points[i]->Z, + // skipping any zero-valued inputs (pretend that they're 1). if (!BN_is_zero(&points[0]->Z)) { if (!BN_copy(prod_Z[0], &points[0]->Z)) { @@ -1023,13 +1018,13 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, } } - /* Now use a single explicit inversion to replace every non-zero points[i]->Z - * by its inverse. We use |BN_mod_inverse_odd| instead of doing a constant- - * time inversion using Fermat's Little Theorem because this function is - * usually only used for converting multiples of a public key point to - * affine, and a public key point isn't secret. If we were to use Fermat's - * Little Theorem then the cost of the inversion would usually be so high - * that converting the multiples to affine would be counterproductive. */ + // Now use a single explicit inversion to replace every non-zero points[i]->Z + // by its inverse. We use |BN_mod_inverse_odd| instead of doing a constant- + // time inversion using Fermat's Little Theorem because this function is + // usually only used for converting multiples of a public key point to + // affine, and a public key point isn't secret. If we were to use Fermat's + // Little Theorem then the cost of the inversion would usually be so high + // that converting the multiples to affine would be counterproductive. int no_inverse; if (!BN_mod_inverse_odd(tmp, &no_inverse, prod_Z[num - 1], &group->field, ctx)) { @@ -1038,9 +1033,9 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, } if (group->meth->field_encode != NULL) { - /* In the Montgomery case, we just turned R*H (representing H) - * into 1/(R*H), but we need R*(1/H) (representing 1/H); - * i.e. we need to multiply by the Montgomery factor twice. */ + // In the Montgomery case, we just turned R*H (representing H) + // into 1/(R*H), but we need R*(1/H) (representing 1/H); + // i.e. we need to multiply by the Montgomery factor twice. if (!group->meth->field_encode(group, tmp, tmp, ctx) || !group->meth->field_encode(group, tmp, tmp, ctx)) { goto err; @@ -1048,34 +1043,34 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, } for (size_t i = num - 1; i > 0; --i) { - /* Loop invariant: tmp is the product of the inverses of - * points[0]->Z .. points[i]->Z (zero-valued inputs skipped). */ + // Loop invariant: tmp is the product of the inverses of + // points[0]->Z .. points[i]->Z (zero-valued inputs skipped). if (BN_is_zero(&points[i]->Z)) { continue; } - /* Set tmp_Z to the inverse of points[i]->Z (as product - * of Z inverses 0 .. i, Z values 0 .. i - 1). */ + // Set tmp_Z to the inverse of points[i]->Z (as product + // of Z inverses 0 .. i, Z values 0 .. i - 1). if (!group->meth->field_mul(group, tmp_Z, prod_Z[i - 1], tmp, ctx) || - /* Update tmp to satisfy the loop invariant for i - 1. */ + // Update tmp to satisfy the loop invariant for i - 1. !group->meth->field_mul(group, tmp, tmp, &points[i]->Z, ctx) || - /* Replace points[i]->Z by its inverse. */ + // Replace points[i]->Z by its inverse. !BN_copy(&points[i]->Z, tmp_Z)) { goto err; } } - /* Replace points[0]->Z by its inverse. */ + // Replace points[0]->Z by its inverse. if (!BN_is_zero(&points[0]->Z) && !BN_copy(&points[0]->Z, tmp)) { goto err; } - /* Finally, fix up the X and Y coordinates for all points. */ + // Finally, fix up the X and Y coordinates for all points. for (size_t i = 0; i < num; i++) { EC_POINT *p = points[i]; if (!BN_is_zero(&p->Z)) { - /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1). */ + // turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1). if (!group->meth->field_sqr(group, tmp, &p->Z, ctx) || !group->meth->field_mul(group, &p->X, &p->X, tmp, ctx) || !group->meth->field_mul(group, tmp, tmp, &p->Z, ctx) || |