记一次复数域rsa解题过程
题目:
complex
from Crypto.Util.number import *
from gmpy2 import invert,lcm,is_prime
from secret import flag
class Complex:
def __init__(self, re, im):
self.re = re
self.im = im
def __mul__(self, c):
re_ = self.re * c.re - self.im * c.im
im_ = self.re * c.im + self.im * c.re
return Complex(re_, im_)
def show(self):
print([self.re, self.im])
def get_value(self):
return self.re,self.im
def complex_pow(c, exp, n):
result = Complex(1, 0)
while exp > 0:
if exp & 1:
result = result * c
result.re = result.re % n
result.im = result.im % n
c = c * c
c.re = c.re % n
c.im = c.im % n
exp >>= 1
return result
cm = Complex(bytes_to_long(flag[:len(flag)//2]),
bytes_to_long(flag[len(flag)//2:]))
e = 65537
p,q=getPrime(128),getPrime(128)
x=(p**2)+(q**2)
print(x)
n = p*q
cc=complex_pow(cm,e,n)
cc.show()
'''
70437980819862722265263950547631065951898643436511174130243756637556383797010
[19465741148801079803774061735500784053796561700996421103193067069375902171549, 24672862982433363355883370758790090703098092788871994731869225483897602445819]
'''
分析:
从加密流程可以看出: cm的实部是flag前半部分,虚部是flag后半部分,根据已知条件X=p^2+q^2多项式求解出p,q后,再进行常规RSA解密:求N->求phi ->求d,最后利用题目定义的complex_pow(c,d,n)
求解明文。
复数域求phi公式为:
多项式、复数域RSA求解推荐在sagemath环境运行,安装使用教程可以参考链接https://zhuanlan.zhihu.com/p/76006823,嫌弃安装复杂也可以使用在线运行环境:Sage Cell Server,sagemath安装python库直接pip即可,如pip install gmpy2
解题脚本:
#sage
import libnum,gmpy2
class Complex:
def __init__(self, re, im):
self.re = re
self.im = im
def __mul__(self, c):
re_ = self.re * c.re - self.im * c.im
im_ = self.re * c.im + self.im * c.re
return Complex(re_, im_)
def show(self):
print([self.re, self.im])
def get_value(self):
return self.re,self.im
def complex_pow(c, exp, n):
result = Complex(1, 0)
while exp > 0:
if exp & 1:
result = result * c
result.re = result.re % n
result.im = result.im % n
c = c * c
c.re = c.re % n
c.im = c.im % n
exp >>= 1
return result
X = 70437980819862722265263950547631065951898643436511174130243756637556383797010
cc = [19465741148801079803774061735500784053796561700996421103193067069375902171549, 24672862982433363355883370758790090703098092788871994731869225483897602445819]
p, q = two_squares(X)
e = 65537
c1 = Complex(cc[0],cc[1])
n = p*q
phi = (p^2 - 1) * (q^2 - 1)
d = gmpy2.invert(e,phi)
mm = complex_pow(c1,d,n).get_value()
print(libnum.n2s(int(mm[0]))+libnum.n2s(int(mm[1])))
flag:
flag{604876d9e5322fc9ef1665af81577e25}