summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2013-12-04 10:03:57 +0900
committerNIIBE Yutaka <gniibe@fsij.org>2013-12-04 10:31:31 +0900
commitc56080c26186d25dec05f01831494c77d8d07e13 (patch)
treee2957ceb59382e54d7d438a472782eb519e53933
parent2ff86db2e1b0f6cc22a1ca86037b526c5fa3be51 (diff)
downloadlibgcrypt-c56080c26186d25dec05f01831494c77d8d07e13.tar.gz
mpi: fix gcry_mpi_powm for negative base.
* mpi/mpi-pow.c (gcry_mpi_powm) [USE_ALGORITHM_SIMPLE_EXPONENTIATION]: Fix for the case where BASE is negative. * tests/mpitests.c (test_powm): Add a test case of (-17)^6 mod 19. Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
-rw-r--r--mpi/mpi-pow.c4
-rw-r--r--tests/mpitests.c19
2 files changed, 21 insertions, 2 deletions
diff --git a/mpi/mpi-pow.c b/mpi/mpi-pow.c
index 469c382a..4bf0233a 100644
--- a/mpi/mpi-pow.c
+++ b/mpi/mpi-pow.c
@@ -177,7 +177,7 @@ gcry_mpi_powm (gcry_mpi_t res,
}
MPN_COPY ( rp, bp, bsize );
rsize = bsize;
- rsign = bsign;
+ rsign = 0;
/* Main processing. */
{
@@ -192,7 +192,7 @@ gcry_mpi_powm (gcry_mpi_t res,
xp = xp_marker = mpi_alloc_limb_space( 2 * (msize + 1), msec );
memset( &karactx, 0, sizeof karactx );
- negative_result = (ep[0] & 1) && base->sign;
+ negative_result = (ep[0] & 1) && bsign;
i = esize - 1;
e = ep[i];
diff --git a/tests/mpitests.c b/tests/mpitests.c
index 1c4edb66..9d1206e5 100644
--- a/tests/mpitests.c
+++ b/tests/mpitests.c
@@ -520,6 +520,25 @@ test_powm (void)
if (gcry_mpi_cmp (res, base))
die ("test_powm failed at %d\n", __LINE__);
+ /* Check for a case: base is negative and expo is even. */
+ gcry_mpi_set_ui (base, b_int);
+ gcry_mpi_neg (base, base);
+ gcry_mpi_set_ui (exp, e_int * 2);
+ gcry_mpi_set_ui(mod, m_int);
+ gcry_mpi_powm (res, base, exp, mod);
+ /* Result should be positive and it's 7 = (-17)^6 mod 19. */
+ if (gcry_mpi_is_neg (res) || gcry_mpi_cmp_ui (res, 7))
+ {
+ if (verbose)
+ {
+ fprintf (stderr, "is_neg: %d\n", gcry_mpi_is_neg (res));
+ fprintf (stderr, "mpi: ");
+ gcry_mpi_dump (res);
+ putc ('\n', stderr);
+ }
+ die ("test_powm failed for negative base at %d\n", __LINE__);
+ }
+
gcry_mpi_release (base);
gcry_mpi_release (exp);
gcry_mpi_release (mod);