github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/mpn/t-minvert.c (about) 1 /* Copyright 2013-2015 Free Software Foundation, Inc. 2 3 This file is part of the GNU MP Library test suite. 4 5 The GNU MP Library test suite is free software; you can redistribute it 6 and/or modify it under the terms of the GNU General Public License as 7 published by the Free Software Foundation; either version 3 of the License, 8 or (at your option) any later version. 9 10 The GNU MP Library test suite is distributed in the hope that it will be 11 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 13 Public License for more details. 14 15 You should have received a copy of the GNU General Public License along with 16 the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ 17 18 #include <stdio.h> 19 #include <stdlib.h> /* for strtol */ 20 21 #include "gmp.h" 22 #include "gmp-impl.h" 23 #include "longlong.h" 24 #include "tests/tests.h" 25 26 #define MAX_SIZE 50 27 28 #define COUNT 200 29 30 static void 31 mpz_to_mpn (mp_ptr ap, mp_size_t an, const mpz_t b) 32 { 33 mp_size_t bn = mpz_size (b); 34 ASSERT_ALWAYS (bn <= an); 35 MPN_COPY_INCR (ap, mpz_limbs_read (b), bn); 36 MPN_ZERO (ap + bn, an - bn); 37 } 38 39 int 40 mpz_eq_mpn (mp_ptr ap, mp_size_t an, const mpz_t b) 41 { 42 mp_size_t bn = mpz_size (b); 43 44 return (bn >= 0 && bn <= an 45 && mpn_cmp (ap, mpz_limbs_read (b), bn) == 0 46 && (an == bn || mpn_zero_p (ap + bn, an - bn))); 47 } 48 49 static mp_bitcnt_t 50 bit_size (mp_srcptr xp, mp_size_t n) 51 { 52 MPN_NORMALIZE (xp, n); 53 return n > 0 ? mpn_sizeinbase (xp, n, 2) : 0; 54 } 55 56 int 57 main (int argc, char **argv) 58 { 59 gmp_randstate_ptr rands; 60 long count = COUNT; 61 mp_ptr mp; 62 mp_ptr ap; 63 mp_ptr tp; 64 mp_ptr scratch; 65 mpz_t m, a, r, g; 66 int test; 67 mp_limb_t ran; 68 mp_size_t itch; 69 TMP_DECL; 70 71 tests_start (); 72 rands = RANDS; 73 74 75 TMP_MARK; 76 mpz_init (m); 77 mpz_init (a); 78 mpz_init (r); 79 mpz_init (g); 80 81 if (argc > 1) 82 { 83 char *end; 84 count = strtol (argv[1], &end, 0); 85 if (*end || count <= 0) 86 { 87 fprintf (stderr, "Invalid test count: %s.\n", argv[1]); 88 return 1; 89 } 90 } 91 92 mp = TMP_ALLOC_LIMBS (MAX_SIZE); 93 ap = TMP_ALLOC_LIMBS (MAX_SIZE); 94 tp = TMP_ALLOC_LIMBS (MAX_SIZE); 95 scratch = TMP_ALLOC_LIMBS (mpn_sec_invert_itch (MAX_SIZE) + 1); 96 97 for (test = 0; test < count; test++) 98 { 99 mp_bitcnt_t bits; 100 int rres, tres; 101 mp_size_t n; 102 103 bits = urandom () % (GMP_NUMB_BITS * MAX_SIZE) + 1; 104 105 if (test & 1) 106 mpz_rrandomb (m, rands, bits); 107 else 108 mpz_urandomb (m, rands, bits); 109 if (test & 2) 110 mpz_rrandomb (a, rands, bits); 111 else 112 mpz_urandomb (a, rands, bits); 113 114 mpz_setbit (m, 0); 115 if (test & 4) 116 { 117 /* Ensure it really is invertible */ 118 if (mpz_sgn (a) == 0) 119 mpz_set_ui (a, 1); 120 else 121 for (;;) 122 { 123 mpz_gcd (g, a, m); 124 if (mpz_cmp_ui (g, 1) == 0) 125 break; 126 mpz_remove (a, a, g); 127 } 128 } 129 130 rres = mpz_invert (r, a, m); 131 if ( (test & 4) && !rres) 132 { 133 gmp_fprintf (stderr, "test %d: Not invertible!\n" 134 "m = %Zd\n" 135 "a = %Zd\n", test, m, a); 136 abort (); 137 } 138 ASSERT_ALWAYS (! (test & 4) || rres); 139 140 n = (bits + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS; 141 ASSERT_ALWAYS (n <= MAX_SIZE); 142 itch = mpn_sec_invert_itch (n); 143 scratch[itch] = ran = urandom (); 144 145 mpz_to_mpn (ap, n, a); 146 mpz_to_mpn (mp, n, m); 147 tres = mpn_sec_invert (tp, ap, mp, n, 148 bit_size (ap, n) + bit_size (mp, n), 149 scratch); 150 151 if (rres != tres || (rres == 1 && !mpz_eq_mpn (tp, n, r)) || ran != scratch[itch]) 152 { 153 gmp_fprintf (stderr, "Test %d failed.\n" 154 "m = %Zd\n" 155 "a = %Zd\n", test, m, a); 156 fprintf (stderr, "ref ret: %d\n" 157 "got ret: %d\n", rres, tres); 158 if (rres) 159 gmp_fprintf (stderr, "ref: %Zd\n", r); 160 if (tres) 161 gmp_fprintf (stderr, "got: %Nd\n", tp, n); 162 if (ran != scratch[itch]) 163 fprintf (stderr, "scratch[itch] changed.\n"); 164 abort (); 165 } 166 } 167 168 TMP_FREE; 169 170 mpz_clear (m); 171 mpz_clear (a); 172 mpz_clear (r); 173 mpz_clear (g); 174 175 tests_end (); 176 return 0; 177 }