/* TomsFastMath, a fast ISO C bignum library. * * This project is meant to fill in where LibTomMath * falls short. That is speed ;-) * * This project is public domain and free for all purposes. * * Tom St Denis, tomstdenis@gmail.com */ #include /* Miller-Rabin test of "a" to the base of "b" as described in * HAC pp. 139 Algorithm 4.24 * * Sets result to 0 if definitely composite or 1 if probably prime. * Randomly the chance of error is no more than 1/4 and often * very much lower. */ void fp_prime_miller_rabin (fp_int * a, fp_int * b, int *result) { fp_int n1, y, r; int s, j; /* default */ *result = FP_NO; /* ensure b > 1 */ if (fp_cmp_d(b, 1) != FP_GT) { return; } /* get n1 = a - 1 */ fp_init_copy(&n1, a); fp_sub_d(&n1, 1, &n1); /* set 2**s * r = n1 */ fp_init_copy(&r, &n1); /* count the number of least significant bits * which are zero */ s = fp_cnt_lsb(&r); /* now divide n - 1 by 2**s */ fp_div_2d (&r, s, &r, NULL); /* compute y = b**r mod a */ fp_init(&y); fp_exptmod(b, &r, a, &y); /* if y != 1 and y != n1 do */ if (fp_cmp_d (&y, 1) != FP_EQ && fp_cmp (&y, &n1) != FP_EQ) { j = 1; /* while j <= s-1 and y != n1 */ while ((j <= (s - 1)) && fp_cmp (&y, &n1) != FP_EQ) { fp_sqrmod (&y, a, &y); /* if y == 1 then composite */ if (fp_cmp_d (&y, 1) == FP_EQ) { return; } ++j; } /* if y != n1 then composite */ if (fp_cmp (&y, &n1) != FP_EQ) { return; } } /* probably prime now */ *result = FP_YES; } /* $Source$ */ /* $Revision$ */ /* $Date$ */