aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2023-11-09 15:20:56 +0100
committerDenis Kenzior <denkenz@gmail.com>2023-11-09 09:29:03 -0600
commit95e7f719b01c95c6a142c9380e14e9a3fd3598d1 (patch)
tree3cd15de40ff8c09a5a4a1015d7f5ee26813f39ef
parent659a48d6bf3ab83f7f17ede42d0e98608704b3cc (diff)
ecc: Add helper for creating a scalar modulo curve order
The SPAKE2+ key exchange protocol requires the ability have a scalar modulo curve order. This adds a helper that allows to create a new scalar and run modulo curver order on it. This is similar to the helper that does the same with the curve prime value.
-rw-r--r--ell/ecc.c35
-rw-r--r--ell/ecc.h2
-rw-r--r--ell/ell.sym1
3 files changed, 38 insertions, 0 deletions
diff --git a/ell/ecc.c b/ell/ecc.c
index ff147b84..2124856d 100644
--- a/ell/ecc.c
+++ b/ell/ecc.c
@@ -846,6 +846,41 @@ LIB_EXPORT struct l_ecc_scalar *l_ecc_scalar_new_modp(
return NULL;
}
+LIB_EXPORT struct l_ecc_scalar *l_ecc_scalar_new_modn(
+ const struct l_ecc_curve *curve,
+ const void *bytes, size_t len)
+{
+ struct l_ecc_scalar *c;
+ uint64_t tmp[2 * L_ECC_MAX_DIGITS];
+ unsigned int ndigits = len / 8;
+
+ if (!bytes)
+ return NULL;
+
+ if (len % 8)
+ return NULL;
+
+ if (ndigits > curve->ndigits * 2)
+ return NULL;
+
+ c = _ecc_constant_new(curve, NULL, 0);
+ if (!c)
+ return NULL;
+
+ memset(tmp, 0, sizeof(tmp));
+ _ecc_be2native(tmp, bytes, ndigits);
+
+ _vli_mmod_slow(c->c, tmp, curve->n, curve->ndigits);
+
+ if (!_vli_is_zero_or_one(c->c, curve->ndigits) &&
+ secure_memcmp_64(curve->n, c->c, curve->ndigits) > 0)
+ return c;
+
+ l_ecc_scalar_free(c);
+
+ return NULL;
+}
+
/*
* Takes a buffer of the same size as the curve and scales it to a range
* 1..n using value = (value mod (n - 1)) + 1. For the curves we support
diff --git a/ell/ecc.h b/ell/ecc.h
index de116f01..5a8cf034 100644
--- a/ell/ecc.h
+++ b/ell/ecc.h
@@ -66,6 +66,8 @@ struct l_ecc_scalar *l_ecc_scalar_new_random(
const struct l_ecc_curve *curve);
struct l_ecc_scalar *l_ecc_scalar_new_modp(const struct l_ecc_curve *curve,
const void *buf, size_t len);
+struct l_ecc_scalar *l_ecc_scalar_new_modn(const struct l_ecc_curve *curve,
+ const void *buf, size_t len);
struct l_ecc_scalar *l_ecc_scalar_new_reduced_1_to_n(
const struct l_ecc_curve *curve,
const void *buf, size_t len);
diff --git a/ell/ell.sym b/ell/ell.sym
index 0f593e1f..a887b2b0 100644
--- a/ell/ell.sym
+++ b/ell/ell.sym
@@ -608,6 +608,7 @@ global:
l_ecc_scalar_new;
l_ecc_scalar_new_random;
l_ecc_scalar_new_modp;
+ l_ecc_scalar_new_modn;
l_ecc_scalar_new_reduced_1_to_n;
l_ecc_scalar_sum_x;
l_ecc_scalars_are_equal;