【发布时间】:2011-02-20 04:49:14
【问题描述】:
背景
为了好玩,我正在尝试编写一个用于快速检查的属性,以测试cryptography with RSA 背后的基本思想。
- 选择两个不同的素数,
p和q。 - 让
N = p*q -
e是 relatively prime 到(p-1)(q-1)的某个数字(实际上,对于快速编码,e 通常为 3) -
d是e模(p-1)(q-1)的 modular inverse
对于所有x 和1 < x < N,(x^e)^d = x modulo N 总是正确的
换句话说,x 是“消息”,将其提升到 eth 幂 mod N 是“编码”消息的行为,并将编码后的消息提升到 dth power mod N 是“解码”它的行为。
(对于x = 1,该属性也是微不足道的,这是它自己加密的情况)
代码
以下是我目前编写的方法:
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
(感谢谷歌和随机博客,implementation of modular multiplicative inverse)
问题
问题应该很明显:该属性的条件太多,无法使其完全可用。尝试在 ghci 中调用 quickCheck prop_rsa 使我的终端挂起。
所以我在QuickCheck manual 周围戳了一下,它说:
属性可以采用以下形式
forAll <generator> $ \<pattern> -> <property>
如何为素数创建<generator>?或者使用其他约束,让quickCheck 不必筛选一堆失败的条件?
欢迎任何其他一般性建议(尤其是关于 QuickCheck)。
【问题讨论】:
-
有趣的事实:QuickCheck 帮助我看到
q和p必须是不同的。在我有这个要求之前,它能够在q == p时找到失败的例子 -
道具人,这是一个很好的问题。很少有人会花这么多精力来传达他们想知道的东西。点赞。
-
您可以使用 Rabin-Miller 概率检验; mathworld.wolfram.com/Rabin-MillerStrongPseudoprimeTest.html
-
刚刚在这里找到了 Rabin-Miller 测试的实现:bonsaicode.wordpress.com/2009/05/01/…
-
@Paul 非常好!我一直在努力调整测试,使其只使用小的素数,主要是因为测试更大的素数变得很麻烦。我将看看将其应用到我的代码中。
标签: haskell properties rsa generator quickcheck