summaryrefslogtreecommitdiff
path: root/src/crypto/fipsmodule/ec/p224-64.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto/fipsmodule/ec/p224-64.c')
-rw-r--r--src/crypto/fipsmodule/ec/p224-64.c58
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;
};