二次剩余
p p p是奇素数。所有的运算都是在群 Z p ∗ Z_{p}^{*} Zp∗中的运算。方程 x 2 = a ≠ 0 x^2=a \neq 0 x2=a̸=0问是否有解,以及解是什么?若有解, a a a就是模 p p p的二次剩余;若无解,则 a a a就是模 p p p的非二次剩余。
-
a = 0 a=0 a=0,显然只有唯一解 x = 0 x=0 x=0.
-
a ≠ 0 a\neq 0 a̸=0,有解等价于 a p − 1 2 = 1 a^{\frac{p-1}{2}}=1 a2p−1=1;无解等价于 a p − 1 2 = − 1 a^{\frac{p-1}{2}}=-1 a2p−1=−1.
群 Z p ∗ Z_{p}^{*} Zp∗恰好有一半的元素是二次剩余,一半的元素不是二次剩余。当元素 a a a是二次剩余是,解有且只有两个 x 0 , x 1 x_0,x_1 x0,x1,且 x 0 = − x 1 x_0=-x_1 x0=−x1,即解 x = ± c x=\pm c x=±c
因此,验证 a a a是否是二次剩余可以用快速模幂,复杂度 O ( log 2 p ) O(\log_2{p}) O(log2p).
对于二次剩余 a a a,求解x使用[Cipolla]{.underline}(洋葱? 奇波拉?)算法。
Cipolla(洋葱?)算法
这是一个随机性算法,复杂度是 O ( log 2 p ) O(\log_2{p}) O(log2p)
这个算法是在域 F p 2 F_{p^2} Fp2上进行运算的,在这个域上做乘法、幂运算,然后解的那个表达式算出来之后,一定是属于域 F p F_{p} Fp的, F p 2 F_{p^2} Fp2是 F p F_{p} Fp的扩充。
-
使用随机的方法,找到一个满足 b b b满足 b 2 − a b^2-a b2−a不是二次剩余。需要检验 b 2 − a b^2-a b2−a是不是二次剩余的期望次数是 2 2 2.每次检验是 O (