PyCryptodomeのisPrime
はRandom BasisのMiller-Rabin
miller rabinをかいくぐる合成数の作りかた
baseを固定した時: baseについてのstrong pseudoprime。 Arnault's method
baseがランダムな時:
ランダムな base についての 1/4 の誤判定率(理論値)をほぼ達成する数は lambda(x) をいい感じにするように適当に生成すれば出てきた。factordb に誤判定したリストがあったので眺めて規則性を見つけたが、 なんでこれがいい感じなのかは分からない……
いい感じ: xが大きな素数数個の積で表されており、かつ lambda(x) が大きな素因数を一つもつ
def mr_test(n, d, r, a): a = Zmod(n)(a) y = a ^ d if y == 1 or y == -1: return True for _ in range(r - 1): y ^= 2 if y == -1: break else: return False return True def liar_prob(n): d = n - 1 r = 0 while d % 2 == 0: d /= 2 r += 1 if n <= 1000: l = list(range(1, n)) elif n <= 10000: l = list(range(1, n)) random.shuffle(l) l = l[:1000] else: s = set() R = Zmod(n) while len(s) < 1000: s.add(random.randrange(1, n)) l = list(s) res = float(len([i for i in l if mr_test(n, d, r, i)]) / len(l)) return res def find_spsp(B): while True: p = getPrime(B) a = p * 2 * 3 + 1 b = p * 4 * 3 + 1 if isPrime(a): print(a, b) if isPrime(a) and isPrime(b): pr = liar_prob(a * b) print(pr) if 0.2 <= pr: print(a*b, pr) return a * b find_spsp(128) # 4237060777988884017800671780056666555374693122698792516704419635488944279425403 0.249