Re: mini-gmp mpz_powm incorrect result

2022-09-29 Thread Marco Bodrato

Ciao,
Il 2022-09-05 21:23 ni...@lysator.liu.se ha scritto:

Marco Bodrato  writes:

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


Definitely needed, thanks for looking into that.



+  if (mpz_cmp_ui (res, 1) <= 0)
+mpz_add_ui (res, res, 9);


Adding 9 looks very arbitrary?


It is arbitrary.
It is large enough to not be completely trivial and small enough to be 
short to write.

I added a comment, saying that it is arbitrary :-)

Can we test mpz_powm (res, b, e, m), with e set to 0, and first |m| > 
1,

then m = ±1? To get coverage for various signs and values for b and m.


The code handling e=0 is not so complex to deserve a sophisticated test.
Anyway, of course the test can be improved.


BTW, it seems docs for mpz_powm doesn't say explicitly what 0^0 (mod m)
should give? But docs for mpz_*_pow_ui does say that 0^0 yields 1, so
for consitency, powm should give 1 mod m, which I think is what the 
code

(with fix) does.


Especially for _powm it is a good idea to return [1] for any x^0, 
regardless of x (i.e. also when x is 0). Otherwise, we should check 
whether x is 0 or not mod m.
We just added the exception that the class [1] is represented by 0 when 
the modulus m=0.  But that's not an exception wrt the above idea.


Ĝis,
m
___
gmp-bugs mailing list
gmp-bugs@gmplib.org
https://gmplib.org/mailman/listinfo/gmp-bugs


Re: mini-gmp mpz_powm incorrect result

2022-09-29 Thread Niels Möller
Marco Bodrato  writes:

>>> 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?

Committed, and I've verified that it fixes Guido's test case.
 
> I propose to also add a couple of tests to mini-gmp/tests/t-powm.c ,
> to keep track of this.

Definitely needed, thanks for looking into that.

> 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_add_ui (res, res, 9);

Adding 9 looks very arbitrary?

> +  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);

Can we test mpz_powm (res, b, e, m), with e set to 0, and first |m| > 1,
then m = ±1? To get coverage for various signs and values for b and m.

BTW, it seems docs for mpz_powm doesn't say explicitly what 0^0 (mod m)
should give? But docs for mpz_*_pow_ui does say that 0^0 yields 1, so
for consitency, powm should give 1 mod m, which I think is what the code
(with fix) does.

Regards,
/Niels

-- 
Niels Möller. PGP key CB4962D070D77D7FCB8BA36271D8F1FF368C6677.
Internet email is subject to wholesale government surveillance.
___
gmp-bugs mailing list
gmp-bugs@gmplib.org
https://gmplib.org/mailman/listinfo/gmp-bugs


Re: mini-gmp mpz_powm incorrect result

2022-09-29 Thread Marco Bodrato

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_add_ui (res, res, 9);
+
+  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
___
gmp-bugs mailing list
gmp-bugs@gmplib.org
https://gmplib.org/mailman/listinfo/gmp-bugs


Re: mini-gmp mpz_powm incorrect result

2022-09-29 Thread Marco Bodrato

Il 2022-09-05 19:04 Marco Bodrato ha scritto:

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?


I incorrectly removed the "Niels Möller wrote:" line.
The question is for Niels, of course.


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


I'll push the tests just after the correction...

Ĝis,
m

PS: thanks for the report
___
gmp-bugs mailing list
gmp-bugs@gmplib.org
https://gmplib.org/mailman/listinfo/gmp-bugs


Re: mini-gmp mpz_powm incorrect result

2022-08-30 Thread Niels Möller
Paul Zimmermann  writes:

> $ diff -u mini-gmp.c.orig mini-gmp.c
> --- mini-gmp.c.orig 2022-08-29 10:28:20.700995412 +0200
> +++ mini-gmp.c  2022-08-29 10:27:36.112191428 +0200
> @@ -3060,6 +3060,7 @@
>if (en == 0)
>  {
>mpz_set_ui (r, 1);
> +  mpz_tdiv_r (r, r, m);
>return;
>  }

Should solve the problem, but maybe a bit overkill to call mpz_tdiv_r. Perhaps

   mpz_set_ui (r, mpz_cmpabs_ui (m, 1) != 0);

or even (mn == 0 check just above this code rules out |m| < 1)

   mpz_set_ui (r, mpz_cmpabs_ui (m, 1));

Regards,
/Niels

-- 
Niels Möller. PGP key CB4962D070D77D7FCB8BA36271D8F1FF368C6677.
Internet email is subject to wholesale government surveillance.
___
gmp-bugs mailing list
gmp-bugs@gmplib.org
https://gmplib.org/mailman/listinfo/gmp-bugs


Re: mini-gmp mpz_powm incorrect result

2022-08-29 Thread Guido Vranken
Thank you, I have confirmed that your patch resolves the issue.

On Mon, Aug 29, 2022 at 10:29 AM Paul Zimmermann 
wrote:

> thank you, I confirm the bug, here is a potential fix:
>
> $ diff -u mini-gmp.c.orig mini-gmp.c
> --- mini-gmp.c.orig 2022-08-29 10:28:20.700995412 +0200
> +++ mini-gmp.c  2022-08-29 10:27:36.112191428 +0200
> @@ -3060,6 +3060,7 @@
>if (en == 0)
>  {
>mpz_set_ui (r, 1);
> +  mpz_tdiv_r (r, r, m);
>return;
>  }
>
> Paul
>
> > From: Guido Vranken 
> > Date: Sun, 28 Aug 2022 16:22:40 +0200
> >
> > The following program computes 1^0 % 1:
> >
> > //#include 
> > #include "mini-gmp.c"
> > #include 
> >
> > #define CF_CHECK_EQ(expr, res) if ( (expr) != (res) ) { goto end; }
> >
> > int main(void)
> > {
> > mpz_t a, b, c, res;
> > char* s = NULL;
> > /* noret */ mpz_init(a);
> > /* noret */ mpz_init(b);
> > /* noret */ mpz_init(c);
> > /* noret */ mpz_init(res);
> >
> > CF_CHECK_EQ(mpz_set_str(a, "1", 10), 0);
> > CF_CHECK_EQ(mpz_set_str(b, "0", 10), 0);
> > CF_CHECK_EQ(mpz_set_str(c, "1", 10), 0);
> > CF_CHECK_EQ(mpz_set_str(res, "0", 10), 0);
> >
> > /* noret */ mpz_powm(res, a, b, c);
> >
> > printf("%s\n", mpz_get_str(NULL, 10, res));
> > end:
> > return 0;
> > }
> >
> > The result should be 0, which is the case with regular libgmp, but with
> > mini-gmp the result is 1, and this is incorrect.
> >
> > Tested on version 6.2.1 and the latest repository checkout, with recent
> > clang and gcc, on x64 Linux.
> > ___
> > gmp-bugs mailing list
> > gmp-bugs@gmplib.org
> > https://gmplib.org/mailman/listinfo/gmp-bugs
>
___
gmp-bugs mailing list
gmp-bugs@gmplib.org
https://gmplib.org/mailman/listinfo/gmp-bugs


Re: mini-gmp mpz_powm incorrect result

2022-08-29 Thread Paul Zimmermann
thank you, I confirm the bug, here is a potential fix:

$ diff -u mini-gmp.c.orig mini-gmp.c
--- mini-gmp.c.orig 2022-08-29 10:28:20.700995412 +0200
+++ mini-gmp.c  2022-08-29 10:27:36.112191428 +0200
@@ -3060,6 +3060,7 @@
   if (en == 0)
 {
   mpz_set_ui (r, 1);
+  mpz_tdiv_r (r, r, m);
   return;
 }

Paul

> From: Guido Vranken 
> Date: Sun, 28 Aug 2022 16:22:40 +0200
> 
> The following program computes 1^0 % 1:
> 
> //#include 
> #include "mini-gmp.c"
> #include 
> 
> #define CF_CHECK_EQ(expr, res) if ( (expr) != (res) ) { goto end; }
> 
> int main(void)
> {
> mpz_t a, b, c, res;
> char* s = NULL;
> /* noret */ mpz_init(a);
> /* noret */ mpz_init(b);
> /* noret */ mpz_init(c);
> /* noret */ mpz_init(res);
> 
> CF_CHECK_EQ(mpz_set_str(a, "1", 10), 0);
> CF_CHECK_EQ(mpz_set_str(b, "0", 10), 0);
> CF_CHECK_EQ(mpz_set_str(c, "1", 10), 0);
> CF_CHECK_EQ(mpz_set_str(res, "0", 10), 0);
> 
> /* noret */ mpz_powm(res, a, b, c);
> 
> printf("%s\n", mpz_get_str(NULL, 10, res));
> end:
> return 0;
> }
> 
> The result should be 0, which is the case with regular libgmp, but with
> mini-gmp the result is 1, and this is incorrect.
> 
> Tested on version 6.2.1 and the latest repository checkout, with recent
> clang and gcc, on x64 Linux.
> ___
> gmp-bugs mailing list
> gmp-bugs@gmplib.org
> https://gmplib.org/mailman/listinfo/gmp-bugs
___
gmp-bugs mailing list
gmp-bugs@gmplib.org
https://gmplib.org/mailman/listinfo/gmp-bugs