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>