From 11da511c784eca003deb90c23570f0873954e0de Mon Sep 17 00:00:00 2001 From: Duncan Wilkie Date: Sat, 18 Nov 2023 06:11:09 -0600 Subject: Initial commit. --- gmp-6.3.0/tests/mpn/t-minvert.c | 167 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 gmp-6.3.0/tests/mpn/t-minvert.c (limited to 'gmp-6.3.0/tests/mpn/t-minvert.c') diff --git a/gmp-6.3.0/tests/mpn/t-minvert.c b/gmp-6.3.0/tests/mpn/t-minvert.c new file mode 100644 index 0000000..ca5690f --- /dev/null +++ b/gmp-6.3.0/tests/mpn/t-minvert.c @@ -0,0 +1,167 @@ +/* Copyright 2013-2015 Free Software Foundation, Inc. + +This file is part of the GNU MP Library test suite. + +The GNU MP Library test suite is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 3 of the License, +or (at your option) any later version. + +The GNU MP Library test suite is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +Public License for more details. + +You should have received a copy of the GNU General Public License along with +the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ + +#include +#include /* for strtol */ + +#include "gmp-impl.h" +#include "longlong.h" +#include "tests/tests.h" + +#define MAX_SIZE 50 + +#define COUNT 200 + +static void +mpz_to_mpn (mp_ptr ap, mp_size_t an, const mpz_t b) +{ + mp_size_t bn = mpz_size (b); + ASSERT_ALWAYS (bn <= an); + MPN_COPY_INCR (ap, mpz_limbs_read (b), bn); + MPN_ZERO (ap + bn, an - bn); +} + +int +mpz_eq_mpn (mp_ptr ap, mp_size_t an, const mpz_t b) +{ + mp_size_t bn = mpz_size (b); + + return (bn >= 0 && bn <= an + && mpn_cmp (ap, mpz_limbs_read (b), bn) == 0 + && (an == bn || mpn_zero_p (ap + bn, an - bn))); +} + +static mp_bitcnt_t +bit_size (mp_srcptr xp, mp_size_t n) +{ + MPN_NORMALIZE (xp, n); + return n > 0 ? mpn_sizeinbase (xp, n, 2) : 0; +} + +int +main (int argc, char **argv) +{ + gmp_randstate_ptr rands; + long count = COUNT; + mp_ptr mp; + mp_ptr ap; + mp_ptr tp; + mp_ptr scratch; + mpz_t m, a, r, g; + int test; + mp_limb_t ran; + mp_size_t itch; + TMP_DECL; + + tests_start (); + rands = RANDS; + + + TMP_MARK; + mpz_init (m); + mpz_init (a); + mpz_init (r); + mpz_init (g); + + TESTS_REPS (count, argv, argc); + + mp = TMP_ALLOC_LIMBS (MAX_SIZE); + ap = TMP_ALLOC_LIMBS (MAX_SIZE); + tp = TMP_ALLOC_LIMBS (MAX_SIZE); + scratch = TMP_ALLOC_LIMBS (mpn_sec_invert_itch (MAX_SIZE) + 1); + + for (test = 0; test < count; test++) + { + mp_bitcnt_t bits; + int rres, tres; + mp_size_t n; + + bits = urandom () % (GMP_NUMB_BITS * MAX_SIZE) + 1; + + if (test & 1) + mpz_rrandomb (m, rands, bits); + else + mpz_urandomb (m, rands, bits); + if (test & 2) + mpz_rrandomb (a, rands, bits); + else + mpz_urandomb (a, rands, bits); + + mpz_setbit (m, 0); + if (test & 4) + { + /* Ensure it really is invertible */ + if (mpz_sgn (a) == 0) + mpz_set_ui (a, 1); + else + for (;;) + { + mpz_gcd (g, a, m); + if (mpz_cmp_ui (g, 1) == 0) + break; + mpz_remove (a, a, g); + } + } + + rres = mpz_invert (r, a, m); + if ( (test & 4) && !rres) + { + gmp_fprintf (stderr, "test %d: Not invertible!\n" + "m = %Zd\n" + "a = %Zd\n", test, m, a); + abort (); + } + ASSERT_ALWAYS (! (test & 4) || rres); + + n = (bits + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS; + ASSERT_ALWAYS (n <= MAX_SIZE); + itch = mpn_sec_invert_itch (n); + scratch[itch] = ran = urandom (); + + mpz_to_mpn (ap, n, a); + mpz_to_mpn (mp, n, m); + tres = mpn_sec_invert (tp, ap, mp, n, + bit_size (ap, n) + bit_size (mp, n), + scratch); + + if (rres != tres || (rres == 1 && !mpz_eq_mpn (tp, n, r)) || ran != scratch[itch]) + { + gmp_fprintf (stderr, "Test %d failed.\n" + "m = %Zd\n" + "a = %Zd\n", test, m, a); + fprintf (stderr, "ref ret: %d\n" + "got ret: %d\n", rres, tres); + if (rres) + gmp_fprintf (stderr, "ref: %Zd\n", r); + if (tres) + gmp_fprintf (stderr, "got: %Nd\n", tp, n); + if (ran != scratch[itch]) + fprintf (stderr, "scratch[itch] changed.\n"); + abort (); + } + } + + TMP_FREE; + + mpz_clear (m); + mpz_clear (a); + mpz_clear (r); + mpz_clear (g); + + tests_end (); + return 0; +} -- cgit v1.2.3