[二次剩余]求解二次剩余

Description

求解x2n(modp)p是一个奇质数。

Solution

由费马小定理

np11(modp)
所以
np12±1(modp)
由欧拉准则
(np)np12(modp)
其中
(np)
为勒让德符号。因为xn12(modp),所以有xp1np121(modp)。即
(np)=110npnpn0(modp)
k=a2n,ω=k
则该方程的解为
x(a+ω)p+12(modp)
证明:若k是该模意义下的非二次剩余,则
wp1=np12=1
同时:
(a+b)pap+bp(modp)
x21(a+ω)p+1(a+ω)p(a+ω)(ap+ωp)(a+ω)(ap1a+ωp1ω)(a+ω)(aω)(a+ω)a2ω2a2(a2n)n(modp)
另一解为
x2x1(modp)

如何找到这个k呢。因为非二次剩余的个数大约有一半,随机几次即可。
后面去实现了一下,发现要重新定义一个复数域Fp2,然后就好啦。
struct Complex {
    ll r, i;
    Complex(ll _r = 0, ll _i = 0):r(_r), i(_i) {}
    inline Complex operator +(ll x) {
        return Complex((x + r) % P, i);
    }
    inline Complex operator *(Complex a) {
        ll rr = (a.r * r % P + w * a.i % P * i % P + P * 3) % P,
            ii = (a.i * r % P + a.r * i % P) % P;
        return Complex(rr, ii);
    }
};

inline ll Qr(ll x, ll p) {
    if (Pow(x, (P - 1) / 2) == P - 1) return -1;
    if (Pow(x, (P - 1) / 2) == 0) return 0;
    ll a;
    Complex k(0, 1);
    while (true) {
        a = rand();
        if (Pow((a * a - x + P) % P, (P - 1) / 2) == P - 1) break;
    }
    w = (a * a - x + P) % P;
    return Pow(k + a, (P + 1) / 2);
}

### 关于RSA加密算法中的二次剩余求解 #### 定义与背景 在密码学领域,特别是对于像RSA这样的非对称加密算法来说,二次剩余是一个重要的概念。如果存在一个整数 \( x \),满足方程 \( x^2 \equiv n (\text{mod}\ p) \),那么\(n\)被称为模p下的二次剩余[^1]。 #### 求解方法 为了计算给定的数值是否为某个素数或合数的二次剩余,可以采用不同的数学工具和技术: - **勒让德符号**:用于判断某数是不是奇质数的平方剩余。具体而言,当考虑形如 \(a^{(p−1)/2}(\text{mod}\ p)\) 的表达式时,其结果能够指示出\(a\)相对于质数\(p\)是否构成二次剩余[^3]。 - **雅可比符号**:这是勒让德符号的一个推广版本,适用于处理更大的范围内的数以及更复杂的场景下判定二次同余式的可能性[^4]。 - **Cipolla算法**:这是一种专门用来解决有限域上二次非剩余问题的有效算法。它基于构造性的证明来寻找根,并且可以在多项式时间内完成操作[^2]。 - **Tonelli-Shanks算法**:此算法提供了一种有效的方式去找到模大素数意义下的二次剩余的具体值。该算法利用了离散对数的一些性质来进行快速定位可能存在的解集。 ```python def tonelli_shanks(n, p): """Find the square root of n modulo prime p using Tonelli-Shanks algorithm.""" q = p - 1 s = 0 while q % 2 == 0: q //= 2 s += 1 if pow(n, (p + 1)//4, p) != 1 and pow(n, (p - 1)//2, p) == 1: z = None for i in range(2, p): if pow(i, (p - 1)//2, p) == p - 1: z = i break c = pow(z, q, p) r = pow(n, (q + 1) // 2, p) t = pow(n, q, p) m = s while True: if t == 1: return r temp_t = t for i in range(m): if temp_t == 1: break temp_t = pow(temp_t, 2, p) b = pow(c, 1 << (m-i-1), p) r = (r * b) % p c = (b * b) % p t = (t * c) % p m = i print("Example usage:") example_p = 7919 # A large enough prime number. example_n = 5833 # The value we want to find its quadratic residue. result = tonelli_shanks(example_n, example_p) if result is not None: print(f"The square roots are ±{result}") else: print("No solution found.") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值