Programming Praxis


Home | Pages | Archives


Solovay-Strassen Primality Testing

April 29, 2014 9:00 AM

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.

Posted by programmingpraxis

Categories: Exercises

Tags:

Leave a Reply



Mobile Site | Full Site


Get a free blog at WordPress.com Theme: WordPress Mobile Edition by Alex King.