diff options
Diffstat (limited to 'src/crypto/fipsmodule/ec/p224-64.c')
-rw-r--r-- | src/crypto/fipsmodule/ec/p224-64.c | 58 |
1 files changed, 39 insertions, 19 deletions
diff --git a/src/crypto/fipsmodule/ec/p224-64.c b/src/crypto/fipsmodule/ec/p224-64.c index 71a8af0a..7e2f45bb 100644 --- a/src/crypto/fipsmodule/ec/p224-64.c +++ b/src/crypto/fipsmodule/ec/p224-64.c @@ -257,23 +257,6 @@ static void p224_felem_sum(p224_felem out, const p224_felem in) { out[3] += in[3]; } -// Get negative value: out = -in -// Assumes in[i] < 2^57 -static void p224_felem_neg(p224_felem out, const p224_felem in) { - static const p224_limb two58p2 = - (((p224_limb)1) << 58) + (((p224_limb)1) << 2); - static const p224_limb two58m2 = - (((p224_limb)1) << 58) - (((p224_limb)1) << 2); - static const p224_limb two58m42m2 = - (((p224_limb)1) << 58) - (((p224_limb)1) << 42) - (((p224_limb)1) << 2); - - // Set to 0 mod 2^224-2^96+1 to ensure out > in - out[0] = two58p2 - in[0]; - out[1] = two58m42m2 - in[1]; - out[2] = two58m2 - in[2]; - out[3] = two58m2 - in[3]; -} - // Subtract field elements: out -= in // Assumes in[i] < 2^57 static void p224_felem_diff(p224_felem out, const p224_felem in) { @@ -513,6 +496,15 @@ static void p224_felem_contract(p224_felem out, const p224_felem in) { out[3] = tmp[3]; } +// Get negative value: out = -in +// Requires in[i] < 2^63, +// ensures out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, out[3] <= 2^56 + 2^16 +static void p224_felem_neg(p224_felem out, const p224_felem in) { + p224_widefelem tmp = {0}; + p224_felem_diff_128_64(tmp, in); + p224_felem_reduce(out, tmp); +} + // Zero-check: returns 1 if input is 0, and 0 otherwise. We know that field // elements are reduced to in < 2^225, so we only need to check three cases: 0, // 2^224 - 2^96 + 1, and 2^225 - 2^97 + 2 @@ -1095,6 +1087,34 @@ static int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, return 1; } +static int ec_GFp_nistp224_field_mul(const EC_GROUP *group, BIGNUM *r, + const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx) { + p224_felem felem1, felem2; + p224_widefelem wide; + if (!p224_BN_to_felem(felem1, a) || + !p224_BN_to_felem(felem2, b)) { + return 0; + } + p224_felem_mul(wide, felem1, felem2); + p224_felem_reduce(felem1, wide); + p224_felem_contract(felem1, felem1); + return p224_felem_to_BN(r, felem1) != NULL; +} + +static int ec_GFp_nistp224_field_sqr(const EC_GROUP *group, BIGNUM *r, + const BIGNUM *a, BN_CTX *ctx) { + p224_felem felem; + if (!p224_BN_to_felem(felem, a)) { + return 0; + } + p224_widefelem wide; + p224_felem_square(wide, felem); + p224_felem_reduce(felem, wide); + p224_felem_contract(felem, felem); + return p224_felem_to_BN(r, felem) != NULL; +} + 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; @@ -1103,8 +1123,8 @@ DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistp224_method) { ec_GFp_nistp224_point_get_affine_coordinates; out->mul = ec_GFp_nistp224_points_mul; out->mul_public = ec_GFp_nistp224_points_mul; - out->field_mul = ec_GFp_simple_field_mul; - out->field_sqr = ec_GFp_simple_field_sqr; + out->field_mul = ec_GFp_nistp224_field_mul; + out->field_sqr = ec_GFp_nistp224_field_sqr; out->field_encode = NULL; out->field_decode = NULL; }; |