Latest commit introduces undefined behavior in hgcd2.c

2019-09-18 Thread Guido Vranken
My bignum fuzzer running at OSS-Fuzz came up with this:

hgcd2.c:223:42: runtime error: shift exponent 64 is too large for
64-bit type 'mp_limb_t' (aka 'unsigned long')
#0 0x76a4db in div2 /src/libgmp/mpn/hgcd2.c:223:42
#1 0x769684 in __gmpn_hgcd2 /src/libgmp/mpn/hgcd2.c:372:18
#2 0x74ac55 in __gmpn_gcd /src/libgmp/mpn/gcd.c:200:11
#3 0x73c209 in __gmpz_gcd /src/libgmp/mpz/gcd.c

Introduced in commit https://gmplib.org/repo/gmp/rev/f044264e2fe9
___
gmp-bugs mailing list
gmp-bugs@gmplib.org
https://gmplib.org/mailman/listinfo/gmp-bugs


Re: Latest commit introduces undefined behavior in hgcd2.c

2019-09-18 Thread Guido Vranken
I don't mind if you don't fix it, but technically undefined behavior
can have consequences beyond the value of the involved variable.

On Wed, Sep 18, 2019 at 9:20 PM Torbjörn Granlund  wrote:
>
> Guido Vranken  writes:
>
>   My bignum fuzzer running at OSS-Fuzz came up with this:
>
>   hgcd2.c:223:42: runtime error: shift exponent 64 is too large for
>   64-bit type 'mp_limb_t' (aka 'unsigned long')
>   #0 0x76a4db in div2 /src/libgmp/mpn/hgcd2.c:223:42
>   #1 0x769684 in __gmpn_hgcd2 /src/libgmp/mpn/hgcd2.c:372:18
>   #2 0x74ac55 in __gmpn_gcd /src/libgmp/mpn/gcd.c:200:11
>   #3 0x73c209 in __gmpz_gcd /src/libgmp/mpz/gcd.c
>
>   Introduced in commit https://gmplib.org/repo/gmp/rev/f044264e2fe9
>
> I think it is a false positive.  The result of the shifted value is
> masked when the shift count is not in range.
>
> (We got the same false positive from our nightly testing using gcc's
> sanitized-something command-line option.)
>
> --
> Torbjörn
> Please encrypt, key id 0xC8601622
___
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


mini-gmp mpz_powm incorrect result

2022-08-28 Thread Guido Vranken
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


Re: mini-gmp mpz_gcdext Bézout coefficients do not match documentation

2024-02-20 Thread Guido Vranken
I've confirmed with my fuzzer that the committed patch resolves the issues.
Thanks.

On Sun, Feb 18, 2024 at 8:27 PM Niels Möller  wrote:

> marco.bodr...@tutanota.com writes:
>
> > The only reason why I prefer my solution is: when cmp<0, there is no
> need to compute
> > mpz_sub (t1, t0, t1);
>
> That's certainly a micro optimization, but let's keep things simple.
>
> I've pushed this fix now, I think there were only comment and ChangeLog
> changes since the previous version of the patch.
>
> Thanks for the review,
> /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


mini-gmp mpz_gcdext Bézout coefficients do not match documentation

2024-02-17 Thread Guido Vranken
Computing extended gcd using mpz_gcdext where a = 1, b = 2:

libgmp: g: 1, s: 1, t: 0
mini-gmp: g: 1, s: -1, t: 1
This violates the docs: "s = sgn(a) if abs(b) = 2", e.g. s must be 1

Computing extended gcd using mpz_gcdext where a = 6, b = 4:
libgmp: g: 2, s: 1, t: -1
mini-libgmp: g: 2, s: -1, t: 2

The docs state: "abs(s) < abs(b) / (2 g) and abs(t) < abs(a) / (2 g)"
I think that should be: "abs(s) <= abs(b) / (2 g) and abs(t) <= abs(a) / (2
g)"
(< should be <=)
Then, for libgmp this is true: s: 1 <= 4 / 4, t: 1 <= 6 / 4
For mini-gmp this is false for t: s: 1 <= 4 / 4, t: 2 <= 6 / 4

Reproducer:

//#include 
#include "mini-gmp.c"

#include 

static void test(
const unsigned long int a_ui,
const unsigned long int b_ui)
{
mpz_t a, b, g, s, t;
mpz_init(a);
mpz_init(b);
mpz_init(g);
mpz_init(s);
mpz_init(t);

mpz_set_ui(a, a_ui);
mpz_set_ui(b, b_ui);

mpz_gcdext(g, s, t, a, b);

printf("g: %s, s: %s, t: %s\n",
mpz_get_str(NULL, 10, g),
mpz_get_str(NULL, 10, s),
mpz_get_str(NULL, 10, t));
}

int main()
{
test(1, 2);
test(6, 4);
}

Tested on Linux x64 using the latest repository code.
___
gmp-bugs mailing list
gmp-bugs@gmplib.org
https://gmplib.org/mailman/listinfo/gmp-bugs