二次剩余问题x的求解及代码实现(python)

本文介绍了二次剩余的概念及其在数论中的重要性,特别是在密码学和大数分解中的应用。详细阐述了如何根据质因数p的不同特性(p=3 mod 4或p=1 mod 4)来求解二次同余式x^2 ≡ a (mod p)。通过高斯的理论和数学运算,提供了相应的Python代码实现,展示了如何找到满足条件的x值。以p=401和a=41为例,得到解为344。
摘要由CSDN通过智能技术生成

一、问题引入

二次剩余是数论基本概念之一。它是初等数论中非常重要的结果,不仅可用来判断二次同余式是否有解,还有很多用途。C.F.高斯称它为算术中的宝石,他一人先后给出多个证明。 [1] 

研究二次剩余的理论称为二次剩余理论。二次剩余理论在实际上有广泛的应用,包括从噪音工程学到密码学以及大数分解。

即关于方                                          x^2 ≡ a (mod p)

对于这个方程,求出满足条件的x。

二、x的求解

在上述问题下,根据p值的不同性质,可以将求解过程分为两种:

1、p = 3 mod 4情况:

解得 x=+-(a ^ ((a+1) / 4)

证明:

x^2 = a (mod p)

       =>a*1 (mod p)          可知 a^((p-1)/2)=1 (mod p)

       =>a ^ a^((p-1)/2) (mod p)

       =>a^((p+1)/2) (mod p)

x=+-a^((p+1)/4) (mod p)

if p%4==3:
    print(gmpy2.powmod(a,int((p+1)/4),p))
    print(-gmpy2.powmod(a,int((p+1)/4),p))

2、p = 1 mod 4  

 引入理论基础:(来自信安数学基础)

 

 由此可见,我们需要在求解中写出以下几个关键模块:

一、将质因数p转化为 p-1=2^t *P 其中,P为一个奇数,t则为为p-1中所含2的个数

while P%2==0:
        P=P//2
        k=k+1
    q=2

二、求出一个满足模p平方非剩余的数q,可以采取设置一个较小的质数q,验证它的 q^(p-1)/2==-1 (mod)p是否恒成立,即可的解:

q=2
    while q: 
        l=gmpy2.powmod(q,int((p-1)/2),p)
        if l==p-1:
            break
        q=sympy.nextprime(q)

 三、在k-1个循环中判断gmpy2.powmod(m,n,p)==p-1为0还是为1,其中:

如果为1,则x[k-i-1]=x[k-i]*pow(b,j0*(2**(i-1)))%p

如果为0,则x[k-i-1]=x[k-i]%p

最终输出x=x[0]即为我们所求解

for i in range(1,k):
        m=re_a*pow(x[k-i],2)
        n=pow(2,(k-i-1))
        if gmpy2.powmod(m,n,p)==p-1:
            j0=1
            x[k-i-1]=x[k-i]*pow(b,j0*(2**(i-1)))%p
        else:
            j1=0
            x[k-i-1]=x[k-i]%p

 所以我们可以写出以下代码用于求解二次剩余定理:

p=
a=

k=0
import gmpy2
import sympy

P=(p-1)
if p%4==3:
    print(gmpy2.powmod(a,int((p+1)//4),p))
    print(-gmpy2.powmod(a,int((p+1)//4),p))
else:
    while P%2==0:
        P=P//2
        k=k+1
    q=2
    while q: 
        l=gmpy2.powmod(q,int((p-1)//2),p)
        if l==p-1:
            break
        q=sympy.nextprime(q)
    b=gmpy2.powmod(q,P,p)
    x=[0 for i in range(k)]
    re_a=gmpy2.invert(a,p)
    x[k-1]=gmpy2.powmod(a,int((P+1)//2),p)
    for i in range(1,k):
        m=re_a*pow(x[k-i],2)
        n=pow(2,(k-i-1))
        if gmpy2.powmod(m,n,p)==p-1:
            j0=1
            x[k-i-1]=x[k-i]*pow(b,j0*(2**(i-1)))%p
        else:
            j1=0
            x[k-i-1]=x[k-i]%p
    print(x[0])

带入

p=401

a=41

进行测试:

344

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值