# mini-gmp mpz_powm incorrect result

Marco Bodrato bodrato at mail.dm.unipi.it
Mon Sep 5 19:04:23 CEST 2022

Ciao,

Il 2022-08-30 10:25 Vincent Lefevre ha scritto:
>> or even (mn == 0 check just above this code rules out |m| < 1)
>>
>>    mpz_set_ui (r, mpz_cmpabs_ui (m, 1));

I agree with this solution. Will you commit it?

> Concerning this second solution, the GMP manual says:
>
>  -- Function: int mpz_cmpabs_ui (const mpz_t OP1, unsigned long int
> OP2)
>      Compare the absolute values of OP1 and OP2.  Return a positive
>      value if abs(OP1) > abs(OP2), zero if abs(OP1) = abs(OP2), or a
>      negative value if abs(OP1) < abs(OP2).
>
> So if the mpz_cmpabs_ui implementation is changed so that it can
> return a value larger than 1, you need to make sure to remember to
> update the code.

I propose to also add a couple of tests to mini-gmp/tests/t-powm.c , to
keep track of this.

----8<------
diff -r b0d6b9f5807e mini-gmp/tests/t-powm.c
--- a/mini-gmp/tests/t-powm.c   Sat Aug 20 18:44:17 2022 +0200
+++ b/mini-gmp/tests/t-powm.c   Mon Sep 05 19:02:23 2022 +0200
@@ -53,6 +53,31 @@
abort ();
}
}
+
+  if (mpz_cmp_ui (res, 1) <= 0)
+
+  mpz_set_ui (e, 0);
+  /* Test the case m^0 (mod m), expect 1 (m is greater than 1). */
+  mpz_powm (res, res, e, res);
+  if (mpz_cmp_ui (res, 1) != 0)
+    {
+      fprintf (stderr, "mpz_powm failed: b=m, e=0; 1 expected,\n");
+      dump ("m", res);
+      dump ("r", res);
+      abort ();
+    }
+
+  /* Now res is 1. */
+  /* Test the case 1^0 (mod 1), expect 0. */
+  mpz_powm (res, res, e, res);
+  if (mpz_size (res))
+    {
+      fprintf (stderr, "mpz_powm failed: b=1, e=0, m=1; 0
expected,\n");
+      dump ("r", res);
+      abort ();
+    }
+
mpz_clear (b);
mpz_clear (e);
mpz_clear (m);
----8<------

Ĝis,
m