Use QuickCheck by generating primes

Posted by Dan on Stack Overflow See other posts from Stack Overflow or by Dan
Published on 2011-02-20T04:49:14Z Indexed on 2011/02/20 7:25 UTC
Read the original article Hit count: 327

Filed under:
|
|
|
|

Background

For fun, I'm trying to write a property for quick-check that can test the basic idea behind cryptography with RSA.

  • Choose two distinct primes, p and q.
  • Let N = p*q
  • e is some number relatively prime to (p-1)(q-1) (in practice, e is usually 3 for fast encoding)
  • d is the modular inverse of e modulo (p-1)(q-1)

For all x such that 1 < x < N, it is always true that (x^e)^d = x modulo N

In other words, x is the "message", raising it to the eth power mod N is the act of "encoding" the message, and raising the encoded message to the dth power mod N is the act of "decoding" it.

(The property is also trivially true for x = 1, a case which is its own encryption)

Code

Here are the methods I have coded up so far:

import Test.QuickCheck

-- modular exponentiation
modExp :: Integral a => a -> a -> a -> a
modExp y z n = modExp' (y `mod` n) z `mod` n
    where modExp' y z | z == 0 = 1
                      | even z =  modExp (y*y) (z `div` 2) n
                      | odd z  = (modExp (y*y) (z `div` 2) n) * y

-- relatively prime
rPrime :: Integral a => a -> a -> Bool
rPrime a b = gcd a b == 1

-- multiplicative inverse (modular)
mInverse :: Integral a => a -> a -> a
mInverse 1 _ = 1
mInverse x y = (n * y + 1) `div` x
    where n = x - mInverse (y `mod` x) x

-- just a quick way to test for primality
n `divides` x = x `mod` n == 0
primes = 2:filter isPrime [3..]
isPrime x = null . filter (`divides` x) $ takeWhile (\y -> y*y <= x) primes

-- the property
prop_rsa (p,q,x) = isPrime p  &&
                   isPrime q  &&
                   p /= q     &&
                   x > 1      &&
                   x < n      &&
                   rPrime e t ==>
                   x == (x `powModN` e) `powModN` d
    where e = 3
          n = p*q
          t = (p-1)*(q-1)
          d = mInverse e t
          a `powModN` b = modExp a b n

(Thanks, google and random blog, for the implementation of modular multiplicative inverse)

Question

The problem should be obvious: there are way too many conditions on the property to make it at all usable. Trying to invoke quickCheck prop_rsa in ghci made my terminal hang.

So I've poked around the QuickCheck manual a bit, and it says:

Properties may take the form

forAll <generator> $ \<pattern> -> <property>

How do I make a <generator> for prime numbers? Or with the other constraints, so that quickCheck doesn't have to sift through a bunch of failed conditions?

Any other general advice (especially regarding QuickCheck) is welcome.

© Stack Overflow or respective owner

Related posts about haskell

Related posts about property