func power(_ xx: Int, _ yy: Int, _ p: Int) -> Int
{
var res = 1 // Initialize result
var x = xx % p // Update x if it is more than or
// equal to p
var y = yy
while (y > 0)
{
// If y is odd, multiply x with result
if 1 == y % 2{
res = (res*x) % p
}
// y must be even now
y = y>>1 // y = y/2
x = (x*x) % p
}
return res
}
// false if n is composite and returns true if n is
// probably prime.
// d is an odd number such that d*2<sup>r</sup> = n-1
// for some r >= 1
func miillerTest(_ dd: Int, _ n: Int) -> Bool
{
// Pick a random number in [2..n-2]
// Corner cases make sure that n > 4
let a = 2 + Int.random(in: 0...n-4)
var d = dd
// Compute a^d % n
var x = power(a, d, n);
if (x == 1 || x == n-1){
return true
}
// Keep squaring x while one of the following doesn't
// happen
// (i) d does not reach n-1
// (ii) (x^2) % n is not 1
// (iii) (x^2) % n is not n-1
while (d != n-1)
{
x = (x * x) % n;
d *= 2;
if (x == 1) {return false}
if (x == n-1) {return true}
}
// Return composite
return false
}
// It returns false if n is composite and returns true if n
// is probably prime. k is an input parameter that determines
// accuracy level. Higher value of k indicates more accuracy.
func isPrime(_ n: Int, _ k: Int) -> Bool
{
// Corner cases
if (n <= 1 || n == 4) {return false}
if (n <= 3) {return true}
// Find r such that n = 2^d * r + 1 for some r >= 1
var d = n - 1
while (d % 2 == 0){
d /= 2
}
// Iterate given number of 'k' times
//for (int i = 0; i < k; i++)
for i in 0..<k{
if (!miillerTest(d, n)){
return false
}
}
return true
}