[PATCH] cipher:ecc: Add curve ietf25 with exact RFC8410 semantics.
NIIBE Yutaka via Gcrypt-devel <[email protected]>
| Newsgroups | gmane.comp.encryption.gpg.libgcrypt.devel |
|---|---|
| Message-ID | <2cc9475876bd579357d72405a57f8a23594a5545.1785984705.git.gniibe@fsij.org> |
* cipher/ecc-curves.c ("ietf25"): Add.
(domain_parms): Add "ietf25".
(find_domain_parms_idx): Allow curve with no other name.
* tests/curves.c (N_CURVES): Increment.
* tests/t-cv25519.c (test_cv_hl25): New.
(test_cv): Add test_cv_hl25.
--
GnuPG-bug-id: 8400
Signed-off-by: NIIBE Yutaka <[email protected]>
---
cipher/ecc-curves.c | 16 ++++++-
tests/curves.c | 2 +-
tests/t-cv25519.c | 112 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 128 insertions(+), 2 deletions(-)
_______________________________________________
Gcrypt-devel mailing list
[email protected]
https://lists.gnupg.org/mailman/listinfo/gcrypt-devel
0001-cipher-ecc-Add-curve-ietf25-with-exact-RFC8410-seman.patch
(text/x-patch, 5.6 KB)
diff --git a/cipher/ecc-curves.c b/cipher/ecc-curves.c
index 08b374d5..93594a70 100644
--- a/cipher/ecc-curves.c
+++ b/cipher/ecc-curves.c
@@ -51,6 +51,7 @@ static const struct
{ "Curve25519", "1.3.6.1.4.1.3029.1.5.1" }, /* OpenPGP */
{ "Curve25519", "1.3.101.110" }, /* rfc8410 */
{ "Curve25519", "X25519" }, /* rfc8410 */
+ { "ietf25" }, /* rfc9580 */
{ "Ed448", "1.3.101.113" }, /* rfc8410 */
{ "X448", "1.3.101.111" }, /* rfc8410 */
@@ -177,6 +178,18 @@ static const ecc_domain_parms_t domain_parms[] =
* the function _gcry_ecc_fill_in_curve. See bug #4712.
*/
},
+ {
+ /* (y^2 = x^3 + 486662*x^2 + x) */
+ "ietf25", 255, 0,
+ MPI_EC_MONTGOMERY, ECC_DIALECT_SAFECURVE,
+ "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED",
+ "0x01DB41",
+ "0x01",
+ "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED",
+ "0x0000000000000000000000000000000000000000000000000000000000000009",
+ "0x5F51E65E475F794B1FE122D388B72EB36DC2B28192839E4DD6163A5D81312C14",
+ 8
+ },
{
/* (x^2 + y^2 = 1 + dx^2y^2) */
"Ed448", 448, 1,
@@ -596,7 +609,8 @@ find_domain_parms_idx (const char *name)
if (!domain_parms[idx].desc)
{
for (aliasno = 0; curve_aliases[aliasno].name; aliasno++)
- if (!strcmp (name, curve_aliases[aliasno].other))
+ if (curve_aliases[aliasno].other
+ && !strcmp (name, curve_aliases[aliasno].other))
break;
if (curve_aliases[aliasno].name)
{
diff --git a/tests/curves.c b/tests/curves.c
index 3cd74422..c50cb6dd 100644
--- a/tests/curves.c
+++ b/tests/curves.c
@@ -33,7 +33,7 @@
#include "t-common.h"
/* Number of curves defined in ../cipher/ecc-curves.c */
-#define N_CURVES 27
+#define N_CURVES 28
/* A real world sample public key. */
static char const sample_key_1[] =
diff --git a/tests/t-cv25519.c b/tests/t-cv25519.c
index 14a6719b..2902b434 100644
--- a/tests/t-cv25519.c
+++ b/tests/t-cv25519.c
@@ -241,6 +241,117 @@ test_cv_hl (int testno, const char *k_str, const char *u_str,
xfree (buffer);
}
+static void
+test_cv_hl25 (int testno, const char *k_str, const char *u_str,
+ const char *result_str)
+{
+ gpg_error_t err;
+ void *buffer = NULL;
+ size_t buflen;
+ gcry_sexp_t s_pk = NULL;
+ gcry_mpi_t mpi_k = NULL;
+ gcry_sexp_t s_data = NULL;
+ gcry_sexp_t s_result = NULL;
+ gcry_sexp_t s_tmp = NULL;
+ unsigned char *res = NULL;
+ size_t res_len;
+
+ if (verbose > 1)
+ info ("Running test %d\n", testno);
+
+ if (!(buffer = hex2buffer (k_str, &buflen)) || buflen != 32)
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "k", "invalid hex string");
+ goto leave;
+ }
+
+ mpi_k = gcry_mpi_set_opaque (NULL, buffer, buflen*8);
+ if ((err = gcry_sexp_build (&s_data, NULL, "%m", mpi_k)))
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "data", gpg_strerror (err));
+ goto leave;
+ }
+
+ if (!(buffer = hex2buffer (u_str, &buflen)) || buflen != 32)
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "u", "invalid hex string");
+ goto leave;
+ }
+
+ /*
+ * The procedure of decodeUCoordinate will be done internally
+ * by _gcry_ecc_mont_decodepoint. So, we just put the little-endian
+ * binary to build S-exp.
+ */
+ if ((err = gcry_sexp_build (&s_pk, NULL,
+ "(public-key"
+ " (ecc"
+ " (curve \"ietf25\")"
+ " (q%b)))", (int)buflen, buffer)))
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "pk", gpg_strerror (err));
+ goto leave;
+ }
+
+ xfree (buffer);
+ buffer = NULL;
+
+ err = gcry_pk_encrypt (&s_result, s_data, s_pk);
+ if (in_fips_mode)
+ {
+ if (!err)
+ fail ("gcry_pk_encrypt is not expected to work in FIPS mode for test %d",
+ testno);
+ if (verbose > 1)
+ info ("not executed in FIPS mode\n");
+ goto leave;
+ }
+ if (err)
+ fail ("gcry_pk_encrypt failed for test %d: %s", testno,
+ gpg_strerror (err));
+
+ s_tmp = gcry_sexp_find_token (s_result, "s", 0);
+ if (!s_tmp || !(res = gcry_sexp_nth_buffer (s_tmp, 1, &res_len)))
+ fail ("gcry_pk_encrypt failed for test %d: %s", testno, "missing value");
+ else
+ {
+ char *r, *r0;
+ int i;
+
+ r0 = r = xmalloc (2*(res_len)+1);
+ if (!r0)
+ {
+ fail ("memory allocation for test %d", testno);
+ goto leave;
+ }
+
+ for (i=0; i < res_len; i++, r += 2)
+ snprintf (r, 3, "%02x", res[i]);
+ if (strcmp (result_str, r0))
+ {
+ fail ("gcry_pk_encrypt failed for test %d: %s",
+ testno, "wrong value returned");
+ info (" expected: '%s'", result_str);
+ info (" got: '%s'", r0);
+ }
+ xfree (r0);
+ }
+
+ leave:
+ xfree (res);
+ gcry_mpi_release (mpi_k);
+ gcry_sexp_release (s_tmp);
+ gcry_sexp_release (s_result);
+ gcry_sexp_release (s_data);
+ gcry_sexp_release (s_pk);
+ xfree (buffer);
+}
+
+
/*
* Test X25519 functionality through the API for X25519.
*
@@ -327,6 +438,7 @@ test_cv (int testno, const char *k_str, const char *u_str,
const char *result_str)
{
test_cv_hl (testno, k_str, u_str, result_str);
+ test_cv_hl25 (testno, k_str, u_str, result_str);
test_cv_x25519 (testno, k_str, u_str, result_str);
}