1+ // Utility function to do modular exponentiation.
2+ // It returns (x^y) % p
3+ function power ( x , y , p )
4+ {
5+ var res = 1 ;
6+ x = x % p ;
7+ while ( y > 0 ) {
8+ // If y is odd, multiply x with result
9+ if ( y & 1 ) res = ( res * x ) % p ;
10+ // y must be even now
11+ y = y >> 1 ; // y = y/2
12+ x = ( x * x ) % p ;
13+ }
14+ return res ;
15+ }
16+
17+
18+ /**
19+ * Determine if N is prime using Miller-Rabin probabilistic algorithm
20+ * @param {Number } n The number
21+ * @param {Number } k An integer that determine the accuracy of the solution
22+ * @return {Boolean }
23+ */
24+ function testProbablyPrime ( n , k ) {
25+ logger . _print ( "==> Testing number " + n ) ;
26+
27+ if ( n === 1 || n === 3 ) {
28+ logger . _print ( "==> Simple case, N is 1 or 3" ) ;
29+ return true ;
30+ }
31+ if ( n % 2 === 0 ) {
32+ logger . _print ( "==> Simple case, " + n + " mod 2 = 0" ) ;
33+ return false ;
34+ }
35+
36+ // Write (n - 1) as 2^s * d
37+ var d = n - 1 ;
38+ while ( d % 2 === 0 ) {
39+ d /= 2 ;
40+ }
41+ logger . _print ( "d = " + d ) ;
42+
43+ // Do 5 iterations if none supplied
44+ k = k || 5 ;
45+ var P = 100 * ( 1 - ( 1 / Math . pow ( 4 , k ) ) ) ;
46+
47+ WitnessLoop: do {
48+ logger . _print ( "Remaining iterations: #" + k ) ;
49+
50+ var a = 2 + Math . floor ( Math . random ( ) * ( n - 4 ) ) ;
51+ logger . _print ( "--> first test with random = " + a ) ;
52+
53+ // Compute a^d % n
54+ var x = power ( a , d , n ) ;
55+
56+ if ( x === 1 || x === n - 1 ) {
57+ logger . _print ( "--> continue WitnessLoop, x = 1 or x = n-1" ) ;
58+ continue ;
59+ }
60+
61+ logger . _print ( "--> second test" ) ;
62+
63+ // Keep squaring x while one of the following doesn't
64+ // happen
65+ // (i) d does not reach n-1
66+ // (ii) (x^2) % n is not 1
67+ // (iii) (x^2) % n is not n-1
68+ var i = d ;
69+ while ( i != n - 1 ) {
70+ x = ( x * x ) % n ;
71+ i *= 2 ;
72+
73+ if ( x == 1 ) {
74+ logger . _print ( "--> exiting, " + n + " is composite" ) ;
75+ return false ;
76+ }
77+
78+ if ( x == n - 1 ) {
79+ logger . _print ( "--> continue WitnessLoop" ) ;
80+ continue WitnessLoop;
81+ }
82+ }
83+
84+ logger . _print ( "--> exiting, " + n + " is composite 'cause (n-1) is reached" ) ;
85+ return false ;
86+
87+ } while ( -- k ) ;
88+
89+ logger . _print ( "End of tests, " + n + " is probably prime with probabilty of " + P + "%" ) ;
90+ return true ;
91+ }
0 commit comments