Skip to content

Instantly share code, notes, and snippets.

@milanboers
Last active May 1, 2016 05:12
Show Gist options
  • Save milanboers/4854458d8e6508d2f9f41f542ce666e0 to your computer and use it in GitHub Desktop.
Save milanboers/4854458d8e6508d2f9f41f542ce666e0 to your computer and use it in GitHub Desktop.
Deterministic version of the Miller-Rabin primality test for Scala
//MillerRabin.scala
import scala.language.implicitConversions
object MillerRabin {
implicit class MillerRabin(n: Long) {
private lazy val asl : Array[BigInt] = if (n < 2047L) Array(2L)
else if (n < 1373653L) Array(2L, 3L)
else if (n < 9080191L) Array(31L, 73L)
else if (n < 25326001L) Array(2L, 3L, 5L)
else if (n < 3215031751L) Array(2L, 3L, 5L, 7L)
else if (n < 4759123141L) Array(2L, 7L, 61L)
else if (n < 1122004669633L) Array(2L, 13L, 23L, 1662803L)
else if (n < 2152302898747L) Array(2L, 3L, 5L, 7L, 11L)
else if (n < 3474749660383L) Array(2L, 3L, 5L, 7L, 11L, 13L)
else if (n < 341550071728321L) Array(2L, 3L, 5L, 7L, 11L, 13L, 17L)
else if (n < 3825123056546413051L) Array(2L, 3L, 5L, 7L, 11L, 13L, 17L, 19L, 23L)
else Array(2L, 3L, 5L, 7L, 11L, 13L, 17L, 19L, 23L, 29L, 31L, 37L)
private lazy val (s,d): (Int, Long) = {
def sdf(s: Int, d: Long) : (Int, Long) = if(d % 2 == 0) sdf(s+1, d >>> 1) else (s,d)
sdf(0, n-1)
}
private def millerRabin(a: BigInt): Boolean =
a.modPow(d, n) != 1 &&
!(0L until s).view.exists(r => a.modPow(BigInt(2).pow(r.intValue())*d, n) == n - 1)
implicit def isPrime: Boolean = !asl.view.exists(millerRabin) || n == 2
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment