寻找因子和素性检验

《初等数论及其运用》6.1 章节

Wilson 定理

对于 \(p\)

\[ (p - 1)! \equiv \left\{ \begin{array}{ll} -1 & p 是素数 \\ 2 & p = 4\\ 0 & p \neq 4 且是合数\\ \end{array} \right. \]

证明:
对于素数,利用缩系的性质证明。
对于合数,考虑分解 \(p=ab\),然后考虑 \((p-1)!\) 里面是否包含 \(a,b\) 即可。很容易证明。

Fermat 小定理

对于 \((a,p) = 1\),有 \(a^{p-1} \equiv 1(\bmod p)\)

判断素数

miller-rabin 算法

考虑用费马小定理判断素性。对于 \(\Z_n^*\)(模 \(n\) 的缩系)中的一个元素 \(a\),如果 \(a^{p - 1} \not \equiv 1(\bmod p)\) 那么 \(p\) 一定是合数。

也即,我们可以选取一个 \(S \subseteq \Z_n^+\),计算 \(\bigwedge \limits_{i \in S} witness(i, n)\) 的值,其中 \(witness(i, n)\) 是一个二元函数,表示 \(i^{n - 1} \equiv 1\) 是否成立。如果均成立,那么认为它是素数。

很遗憾这个判断对于一些伪素数可能出现错误。事实上,取多组基均不能判断出的素数存在,称为 Carmicheal 数。这使得这个算法是错误的。

但是我们对 \(witness\) 函数稍微改进,就可以得到一个没有坏的输入的素性检验方法。

过程是这样的:对于奇数 \(n\)(首先判断一下偶数),令 \(n - 1 = 2^t \times u\),其中 \(u\) 是奇数,\(t \ge 1\)。考虑算出 \(i^u\) 的值,然后不断乘以 \(2\)。乘了 \(i\)\(2\) 之后的数记为 \(a_i\),得到一个序列 \(a_0, a_1, ..., a_t\)。如果存在一个 \(k\),使得 \(a_k = 1, a_{k-1} \neq 1, a_{k-1} \neq -1\),那么其是合数。

这个论断为什么成立呢?考虑 \(a_k = a_{k-1}^2\)。如果 \(a_{k-1}^2 - 1 \equiv 0, (a_{k-1}^2 - 1)(a_{k-1}^2 +1) \equiv 0\),那么我们找到了一组因子。为了避免找到平凡因子 \(0, n\),判断 \(a_{k-1}^2\) 是否是 \(\pm 1\) 即可。如果都不是,一定找到的是非平凡因子。(这点分类讨论一下不难证明)

WITNESS(a, n)
	let t and u be such that t >= 1, u is odd, and n - 1 = 2^t u
	x_0 = a^u mod n
	for i = 1 to t
		x_i = x_{i-1}^2 mod n
		if x_i == 1 and x_{i-1} != -1 and x_{i-1} != 1 
			return TRUE
	if(x_t != 1) 
		return TRUE
	return FALSE
MILLER_RABIN(n, s)
	for j=1 to s
		a = random(1, n - 1)
		if(WITNESS(a, n)) return COMPOSITE
	return PRIME

如果 \(x\) 数组出现一个 \(1\),那么后面的都是 \(1\)
出现一个 \(-1\),后面也都是 \(1\)
直观感受一下,得到的 \(x\) 数组有四种可能:

  1. \(x = <..., d>,d \neq 1\):不是 \(1\) 结尾,是合数。
  2. \(x = <..., -1, 1, ..., 1>\):以 \(1\) 结尾,而且最后一个不是 \(1\) 的数是 \(-1\),没判断出。
  3. \(x = <1, 1, ..., 1>\):以 \(1\) 结尾,第一个数是 \(1\),当且仅当 \(a = 1\),没判断出。
  4. \(x = <..., d, 1, ..., 1>\):是合数。

事实上,对于任何一个正合数 \(n\),其非证据的个数 \(\le \cfrac{n}{2}\),也就是说对正合数进行 \(s\) 次验证之后没判断出的概率是 \(2^{-s}\)

在 oi 方面,对 \(2^{64}\) 下的数进行素性检验可以用到 \(s = {2, 3, 5, 7, ...}\)(前 \(12\) 个素数),可以百分百保证正确性。

注意用这组数据进行检验的时候:

  • 所有数据都要用到,而不是只用 \(<n\) 的。
  • 使用 \(a \bmod n\)。如果为 \(0\) 直接跳过这组测试。

寻找因子

pollard rho 算法
posted @ 2022-11-28 21:59  OIer某罗  阅读(20)  评论(0编辑  收藏  举报