Hello,
On 13.2.2025 8.20, NIIBE Yutaka wrote:
Hello, again for _gcry_mpih_cmp_ui,
Jussi Kivilinna <jussi.kivili...@iki.fi> wrote:
* mpi/mpih-const-time.c (_gcry_mpih_cmp_ui): Avoid conditional
branches for return value selection.
After the commit of this, I realize that there is a thinko.
When IS_ALL_ZERO (meaning all the limbs sans the least one are zero)
is false, the function should return 1 (instead of 0).
Ah, that's right. Here's patch attach with new tests to catch this. I'll push
this to master soon.
-Jussi
Something like this:
diff --git a/mpi/mpih-const-time.c b/mpi/mpih-const-time.c
index d8b66c46..a6314932 100644
--- a/mpi/mpih-const-time.c
+++ b/mpi/mpih-const-time.c
@@ -232,5 +232,5 @@ _gcry_mpih_cmp_ui (mpi_ptr_t up, mpi_size_t usize, unsigned
long v)
for (i = 1; i < usize; i++)
is_all_zero &= ct_ulong_gen_mask(mpih_limb_is_zero (up[i]));
- return cmp0 & (int)is_all_zero;
+ return (cmp0 & (int)is_all_zero) | (~is_all_zero & 1);
}
From 957ac97097d0960a621ea1ea9f751b422afa8949 Mon Sep 17 00:00:00 2001
From: Jussi Kivilinna <jussi.kivili...@iki.fi>
Date: Thu, 13 Feb 2025 20:20:04 +0200
Subject: [PATCH] mpih-const-time: fix return value for _gcry_mpih_cmp_ui
* mpi/mpih-const-time.c (_gcry_mpih_cmp_ui): Return '1' when
upper part of MPI is not all zeros.
* tests/mpitests.c (test_invm_cmpui, test_invm): Add tests
for gcry_mpi_invm().
--
Input such as {U=[0,0,0,1], V=1} should return 1 as U is larger
than V, but function was returning '0'.
Signed-off-by: Jussi Kivilinna <jussi.kivili...@iki.fi>
---
mpi/mpih-const-time.c | 2 +-
tests/mpitests.c | 94 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 95 insertions(+), 1 deletion(-)
diff --git a/mpi/mpih-const-time.c b/mpi/mpih-const-time.c
index d8b66c46..9c2cd6a9 100644
--- a/mpi/mpih-const-time.c
+++ b/mpi/mpih-const-time.c
@@ -232,5 +232,5 @@ _gcry_mpih_cmp_ui (mpi_ptr_t up, mpi_size_t usize, unsigned long v)
for (i = 1; i < usize; i++)
is_all_zero &= ct_ulong_gen_mask(mpih_limb_is_zero (up[i]));
- return cmp0 & (int)is_all_zero;
+ return (int)((cmp0 & is_all_zero) | (~is_all_zero & 1));
}
diff --git a/tests/mpitests.c b/tests/mpitests.c
index 2ee08bd3..40cba664 100644
--- a/tests/mpitests.c
+++ b/tests/mpitests.c
@@ -739,6 +739,99 @@ test_addm_subm_mulm (void)
}
+static int
+test_invm_cmpui(void)
+{
+ unsigned char a[2][9] = {
+ /* _gcry_mpih_cmp_ui, is_all_zero == 0 */
+ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1, },
+ /* _gcry_mpih_cmp_ui, is_all_zero == 1 */
+ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2, }
+ };
+ unsigned char b[2][9] = {
+ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1, },
+ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1, }
+ };
+ int expect_ret[2] = { 0, 1 };
+ gcry_mpi_t A;
+ gcry_mpi_t B;
+ gcry_mpi_t C;
+ int i;
+
+ for (i = 0; i < DIM(a); i++)
+ {
+ gcry_mpi_scan(&A, GCRYMPI_FMT_USG, a[i], sizeof(a[i]), NULL);
+ gcry_mpi_scan(&B, GCRYMPI_FMT_USG, b[i], sizeof(b[i]), NULL);
+ C = gcry_mpi_new(0);
+
+ if (gcry_mpi_invm(C, A, B) != expect_ret[i])
+ {
+ die ("test_invm_cmpui failed i=%d at %d\n", i, __LINE__);
+ }
+
+ gcry_mpi_release(A);
+ gcry_mpi_release(B);
+ gcry_mpi_release(C);
+ }
+
+ return 1;
+}
+
+
+static int
+test_invm(void)
+{
+ const char *a[2] = {
+ "12cf3a8ca3d97bea2f080362600cee355",
+ "36fb5bdb5daa9864113ad8a49a41722fc7003a40b02a13daca6997859c2d8534192" \
+ "ff6c02447"
+ };
+ const char *b[2] = {
+ "1c3fddf62aee0be2f6dc2ef8471f1be2e",
+ "25c88352cfa171fc728503df037c355a6d5588b22e3510b08f10848ad7c0980b400"
+ };
+ const char *expected_c[2] = {
+ "01339462644931FD624528EA6B3FB1F985",
+ NULL
+ };
+ gcry_mpi_t A;
+ gcry_mpi_t B;
+ gcry_mpi_t C;
+ char *pc;
+ int i;
+
+ for (i = 0; i < DIM(a); i++)
+ {
+ int expected_inverse = expected_c[i] != NULL;
+
+ gcry_mpi_scan(&A, GCRYMPI_FMT_HEX, a[i], 0, NULL);
+ gcry_mpi_scan(&B, GCRYMPI_FMT_HEX, b[i], 0, NULL);
+ C = gcry_mpi_new(0);
+
+ if (gcry_mpi_invm(C, A, B) != expected_inverse)
+ {
+ die ("test_invm failed i=%d at line %d\n", i, __LINE__);
+ }
+
+ if (expected_inverse)
+ {
+ gcry_mpi_aprint(GCRYMPI_FMT_HEX, (unsigned char **)&pc, NULL, C);
+ if (strcmp (pc, expected_c[i]) != 0)
+ fail ("test_invm failed i=%d at line %d", i, __LINE__);
+ gcry_free(pc);
+ }
+
+ gcry_mpi_release(A);
+ gcry_mpi_release(B);
+ gcry_mpi_release(C);
+ }
+
+ test_invm_cmpui();
+
+ return 1;
+}
+
+
int
main (int argc, char* argv[])
{
@@ -763,6 +856,7 @@ main (int argc, char* argv[])
test_mul ();
test_powm ();
test_addm_subm_mulm ();
+ test_invm ();
return !!error_count;
}
--
2.45.2
_______________________________________________
Gcrypt-devel mailing list
Gcrypt-devel@gnupg.org
https://lists.gnupg.org/mailman/listinfo/gcrypt-devel