[BACK]Return to millerrabin.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp / mpz

Annotation of OpenXM_contrib/gmp/mpz/millerrabin.c, Revision 1.1

1.1     ! ohara       1: /* mpz_millerrabin(n,reps) -- An implementation of the probabilistic primality
        !             2:    test found in Knuth's Seminumerical Algorithms book.  If the function
        !             3:    mpz_millerrabin() returns 0 then n is not prime.  If it returns 1, then n is
        !             4:    'probably' prime.  The probability of a false positive is (1/4)**reps, where
        !             5:    reps is the number of internal passes of the probabilistic algorithm.  Knuth
        !             6:    indicates that 25 passes are reasonable.
        !             7:
        !             8:    THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY.  THEY'RE ALMOST
        !             9:    CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
        !            10:    FUTURE GNU MP RELEASES.
        !            11:
        !            12: Copyright 1991, 1993, 1994, 1996, 1997, 1998, 1999, 2000, 2001 Free Software
        !            13: Foundation, Inc.  Contributed by John Amanatides.
        !            14:
        !            15: This file is part of the GNU MP Library.
        !            16:
        !            17: The GNU MP Library is free software; you can redistribute it and/or modify
        !            18: it under the terms of the GNU Lesser General Public License as published by
        !            19: the Free Software Foundation; either version 2.1 of the License, or (at your
        !            20: option) any later version.
        !            21:
        !            22: The GNU MP Library is distributed in the hope that it will be useful, but
        !            23: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
        !            24: or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
        !            25: License for more details.
        !            26:
        !            27: You should have received a copy of the GNU Lesser General Public License
        !            28: along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
        !            29: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
        !            30: MA 02111-1307, USA. */
        !            31:
        !            32: #include "gmp.h"
        !            33: #include "gmp-impl.h"
        !            34:
        !            35: static int millerrabin _PROTO ((mpz_srcptr n, mpz_srcptr nm1,
        !            36:                                 mpz_ptr x, mpz_ptr y,
        !            37:                                 mpz_srcptr q, unsigned long int k));
        !            38:
        !            39: int
        !            40: mpz_millerrabin (mpz_srcptr n, int reps)
        !            41: {
        !            42:   int r;
        !            43:   mpz_t nm1, x, y, q;
        !            44:   unsigned long int k;
        !            45:   gmp_randstate_t rstate;
        !            46:   int is_prime;
        !            47:   TMP_DECL (marker);
        !            48:   TMP_MARK (marker);
        !            49:
        !            50:   MPZ_TMP_INIT (nm1, SIZ (n) + 1);
        !            51:   mpz_sub_ui (nm1, n, 1L);
        !            52:
        !            53:   MPZ_TMP_INIT (x, SIZ (n));
        !            54:   MPZ_TMP_INIT (y, 2 * SIZ (n)); /* mpz_powm_ui needs excessive memory!!! */
        !            55:
        !            56:   /* Perform a Fermat test.  */
        !            57:   mpz_set_ui (x, 210L);
        !            58:   mpz_powm (y, x, nm1, n);
        !            59:   if (mpz_cmp_ui (y, 1L) != 0)
        !            60:     {
        !            61:       TMP_FREE (marker);
        !            62:       return 0;
        !            63:     }
        !            64:
        !            65:   MPZ_TMP_INIT (q, SIZ (n));
        !            66:
        !            67:   /* Find q and k, where q is odd and n = 1 + 2**k * q.  */
        !            68:   k = mpz_scan1 (nm1, 0L);
        !            69:   mpz_tdiv_q_2exp (q, nm1, k);
        !            70:
        !            71:   gmp_randinit (rstate, GMP_RAND_ALG_DEFAULT, 32L);
        !            72:
        !            73:   is_prime = 1;
        !            74:   for (r = 0; r < reps && is_prime; r++)
        !            75:     {
        !            76:       do
        !            77:        mpz_urandomb (x, rstate, mpz_sizeinbase (n, 2) - 1);
        !            78:       while (mpz_cmp_ui (x, 1L) <= 0);
        !            79:
        !            80:       is_prime = millerrabin (n, nm1, x, y, q, k);
        !            81:     }
        !            82:
        !            83:   gmp_randclear (rstate);
        !            84:
        !            85:   TMP_FREE (marker);
        !            86:   return is_prime;
        !            87: }
        !            88:
        !            89: static int
        !            90: millerrabin (mpz_srcptr n, mpz_srcptr nm1, mpz_ptr x, mpz_ptr y,
        !            91:              mpz_srcptr q, unsigned long int k)
        !            92: {
        !            93:   unsigned long int i;
        !            94:
        !            95:   mpz_powm (y, x, q, n);
        !            96:
        !            97:   if (mpz_cmp_ui (y, 1L) == 0 || mpz_cmp (y, nm1) == 0)
        !            98:     return 1;
        !            99:
        !           100:   for (i = 1; i < k; i++)
        !           101:     {
        !           102:       mpz_powm_ui (y, y, 2L, n);
        !           103:       if (mpz_cmp (y, nm1) == 0)
        !           104:        return 1;
        !           105:       if (mpz_cmp_ui (y, 1L) == 0)
        !           106:        return 0;
        !           107:     }
        !           108:   return 0;
        !           109: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>