Solovay-Strassen Primality Testing

April 29, 2014

Both tests are easy to write, but both rely on infrastructure that we have built in previous exercises. Here is the probabilistic test:

(define (ss-prime? n)
  (if (not (integer? n)) (error 'ss-prime? "must be integer")
    (if (< n 2) #f (if (zero? (modulo n 2)) (= n 2) ; n is even
      (let loop ((k 40) (a (randint 1 n)))
        (if (zero? k) #t ; probably prime
          (let ((j (jacobi a n)) (x (expm a (/ (- n 1) 2) n)))
            (if (or (zero? j) (not (= (modulo j n) x))) #f ; composite
              (loop (- k 1) (randint 1 n))))))))))

We choose k = 40, which is a reasonable value; you could choose something different or make it a parameter if you wish. Note that there is no need to explicitly compute gcd(a, n), as the Jacobi symbol will be zero in that case. The version on the ERH is similar, except that we loop over primes instead of counting down k:

(define (ss-proof? n)
  (if (not (integer? n)) (error 'ss-proof? "must be integer")
    (if (exact (floor (* 2 (square (log n)))))))))
        (if (null? as) #t ; prime on the erh
          (let ((j (jacobi (car as) n)) (x (expm (car as) (/ (- n 1) 2) n)))
            (if (or (zero? j) (not (= (modulo j n) x))) #f ; composite
              (loop (cdr as))))))))))

It is easy to test the two functions by comparing their output to the primes computed by the Sieve of Eratosthenes:

(let ((ps (primes 1000000)))
  (do ((n 2 (+ n 1))) ((= n 1000000))
    (assert (if (member n ps) #t #f) (ss-prime? n))
    (assert (if (member n ps) #t #f) (ss-proof? n))))

You can see the entire code at http://programmingpraxis.codepad.org/1nFhkEil.

Advertisement

Pages: 1 2

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: