(root)/
gmp-6.3.0/
mini-gmp/
tests/
t-pprime_p.c
       1  /* test mpz_probab_prime_p
       2  
       3  Copyright 2001, 2002, 2004, 2011, 2012, 2014, 2016 Free Software
       4  Foundation, Inc.
       5  
       6  This file is part of the GNU MP Library test suite.
       7  
       8  The GNU MP Library test suite is free software; you can redistribute it
       9  and/or modify it under the terms of the GNU General Public License as
      10  published by the Free Software Foundation; either version 3 of the License,
      11  or (at your option) any later version.
      12  
      13  The GNU MP Library test suite is distributed in the hope that it will be
      14  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
      15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
      16  Public License for more details.
      17  
      18  You should have received a copy of the GNU General Public License along with
      19  the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
      20  
      21  #include "testutils.h"
      22  
      23  static int
      24  isprime (unsigned long int t)
      25  {
      26    unsigned long int q, r, d;
      27  
      28    if (t < 32)
      29      return (0xa08a28acUL >> t) & 1;
      30    if ((t & 1) == 0)
      31      return 0;
      32  
      33    if (t % 3 == 0)
      34      return 0;
      35    if (t % 5 == 0)
      36      return 0;
      37    if (t % 7 == 0)
      38      return 0;
      39  
      40    for (d = 11;;)
      41      {
      42        q = t / d;
      43        r = t - q * d;
      44        if (q < d)
      45  	return 1;
      46        if (r == 0)
      47  	break;
      48        d += 2;
      49        q = t / d;
      50        r = t - q * d;
      51        if (q < d)
      52  	return 1;
      53        if (r == 0)
      54  	break;
      55        d += 4;
      56      }
      57    return 0;
      58  }
      59  
      60  static void
      61  check_one (mpz_srcptr n, int want)
      62  {
      63    int  got;
      64  
      65    got = mpz_probab_prime_p (n, 25);
      66  
      67    /* "definitely prime" is fine if we only wanted "probably prime" */
      68    if (got == 2 && want == 1)
      69      want = 2;
      70  
      71    if (got != want)
      72      {
      73        printf ("mpz_probab_prime_p\n");
      74        dump   ("  n    ", n);
      75        printf ("  got =%d", got);
      76        printf ("  want=%d\n", want);
      77        abort ();
      78      }
      79  }
      80  
      81  static void
      82  check_pn (mpz_ptr n, int want)
      83  {
      84    check_one (n, want);
      85    mpz_neg (n, n);
      86    check_one (n, want);
      87  }
      88  
      89  static void
      90  check_small (void)
      91  {
      92    mpz_t  n;
      93    long   i;
      94  
      95    mpz_init (n);
      96  
      97    for (i = 0; i < 1700; i++)
      98      {
      99        mpz_set_si (n, i);
     100        check_pn (n, isprime (i));
     101      }
     102  
     103    mpz_clear (n);
     104  }
     105  
     106  void
     107  check_composites (void)
     108  {
     109    int i;
     110    int reps = 1000;
     111    mpz_t a, b, n, bs;
     112    unsigned long size_range, size;
     113  
     114    mpz_init (a);
     115    mpz_init (b);
     116    mpz_init (n);
     117    mpz_init (bs);
     118  
     119    for (i = 0; i < reps; i++)
     120      {
     121        mini_urandomb (bs, 16);
     122        size_range = mpz_get_ui (bs) % 10 + 1; /* 0..1024 bit operands */
     123  
     124        mini_urandomb (bs, size_range);
     125        size = mpz_get_ui (bs);
     126        mini_rrandomb (a, size);
     127  
     128        mini_urandomb (bs, size_range);
     129        size = mpz_get_ui (bs);
     130        mini_rrandomb (b, size);
     131  
     132        /* Exclude trivial factors */
     133        if (mpz_cmp_ui (a, 1) == 0)
     134  	mpz_set_ui (a, 2);
     135        if (mpz_cmp_ui (b, 1) == 0)
     136  	mpz_set_ui (b, 2);
     137  
     138        mpz_mul (n, a, b);
     139  
     140        check_pn (n, 0);
     141      }
     142    mpz_clear (a);
     143    mpz_clear (b);
     144    mpz_clear (n);
     145    mpz_clear (bs);
     146  }
     147  
     148  static void
     149  check_primes (void)
     150  {
     151    static const char * const primes[] = {
     152      "2", "17", "65537",
     153      /* diffie-hellman-group1-sha1, also "Well known group 2" in RFC
     154         2412, 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 } */
     155      "0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
     156      "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
     157      "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
     158      "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
     159      "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381"
     160      "FFFFFFFFFFFFFFFF",
     161      NULL
     162    };
     163  
     164    mpz_t n;
     165    int i;
     166  
     167    mpz_init (n);
     168  
     169    for (i = 0; primes[i]; i++)
     170      {
     171        mpz_set_str_or_abort (n, primes[i], 0);
     172        check_one (n, 1);
     173      }
     174    mpz_clear (n);
     175  }
     176  
     177  void
     178  testmain (int argc, char *argv[])
     179  {
     180    check_small ();
     181    check_composites ();
     182    check_primes ();
     183  }