diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2023-11-09 15:20:56 +0100 |
---|---|---|
committer | Denis Kenzior <denkenz@gmail.com> | 2023-11-09 09:29:03 -0600 |
commit | 95e7f719b01c95c6a142c9380e14e9a3fd3598d1 (patch) | |
tree | 3cd15de40ff8c09a5a4a1015d7f5ee26813f39ef | |
parent | 659a48d6bf3ab83f7f17ede42d0e98608704b3cc (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.c | 35 | ||||
-rw-r--r-- | ell/ecc.h | 2 | ||||
-rw-r--r-- | ell/ell.sym | 1 |
3 files changed, 38 insertions, 0 deletions
@@ -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 @@ -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; |