task.py
1 | from Crypto.Util.number import * |
虽然有pow但不是RSA,因为n是素数
我觉得判断的原因就是p * q为非素数,再加上一个素数,就得到素数
后面知道是利用Tonelli–Shanks算法求解二次剩余问题。
已知n、c求m
参考:https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm
https://blog.csdn.net/wmdcstdio/article/details/49862189?locationNum=15
Tonelli–Shanks算法
Tonellii - Shanks算法(Shanks称为RESSOL算法)在模运算中用于求解r2≡n(mod p)的一个全等,其中p是质数:即求n模p的平方根。
Tonelli–Shanks不可用于复合模:求平方根模的复合数是一个与大整数分解等价的计算问题。
核心
给予一个非零n和一个奇素数p,欧拉判别法告诉我们n有一个平方根(例如,n是一个二次剩余)那么有:
np−12≡1(mod p)相反,如果一个数z没有平方根(不满足二次剩余),则有:
zp−12≡−1(mod p)我们不难发现z,因为在1和p-1之间的接近一半的的整数有这种性质,所以我们假定我们有这样的非二次剩余。
通过(通常情况下)重复除以2,我们可以把p-1写作Q2S,而且此处Q为奇数,注意到如果我们尝试
接着R2≡nQ+1(mod p)=(n)(nQ)(mod p)
如果t≡nQ≡1(mod p)
那么R是n的一个平方根。否则对于M=S,我们有R和t满足
如果我给一个R和t对于特定的M满足先前提到的(R不是n的平方根),我们能简单地计算出另外的R和t,且对于M-1满足先前提到的关系,这样我们能重复这一过程知道t变成1的2的20次方根,例如,t=1,在这时R是一个n的一个平方根。
我们可以检查t是否是1的一个2M−2根通过开{M-1}次方,和检查是否等于1。如果是,那我们不需要做任何事,相同的R和t就可以了。但如果不是,t2M−2一定要是-1(因为将它开方得到1,1模p只能有两个平方根1和-1)
为了找到一对新的R和t,我们能把R乘一个待定的因数b。接下来t一定要被因数b2为了保证R2≡nt(mod p), 所以我们需要去找到一个因数b2,以达成tb2是一个1的2M−2根,或者相同地,b2是一个-1的2M−2根。
关键的就是利用z,这个已知的非二次剩余数,欧拉判别法应用如上所示,zQ是-1的2S−1根,通过重复对zQ开方,我们可以得到一个−1的2i次方根的序列。我们可以选择一个合适的去作为b,通过一点点变量维护和琐碎的情况压缩(翻不动),算法就有了。
例子
求解这样的全等式:r2≡5(mod 41)
n=5 p=4141是一个所需要的素数,并且41≡1(mod 4) 5是一个通过欧拉判别法得知的二次剩余数:541−12=520=1(正如之前,在(Z/41Z)× (41模整数的乘法群)被暗中mod 41)
类似的等于关系下面会多次出现,因为其实还隐藏了mod41
1.p−1=40=5∗23,所以Q← 5 , S← 3
2.找到z
- 241−12=1,所以2是一个二次剩余数
- 341−12=40=−1,所以3是一个二次非剩余数,令z← 3
3.令
- M← S=3
- c← zQ=35=38
- t← nQ=55=9
- R← nQ+12=55+12=2
4.循环
- 第一次迭代:
- t≠ 1,所以我们没完成
- t21=40,t22=1所以i←2
- b←c2M−i−1=3823−2−1=38
- M←i=2
- c←b2=382=9
- t←tb2=9⋅9=40
- R←Rb=2⋅38=35
/n
- 二次迭代:
- t≠1, 所以我们还未完成
- t21=1所以 i←1
- b←c2M−i−1=922−1−1=9
- M←i=1
- c←b2=92=40
- t←tb2=40⋅40=1
- R←Rb=35⋅9=28
/n
三次迭代
- t=1,我们完成了,返回值r=R=28
的确,282≡5(mod 41)和(−28)2≡132≡5(mod 41),所以这个算法最终产生了两个同余解
脚本
1 | from Crypto.Util.number import * |