题目信息
from Crypto.Util.number import *
from secret import flag,a,b
from random import shuffle
D = 0x1337
assert a**2 - D*b**2 == 1
m = bytes_to_long(flag)
p = getPrime(512)
x = (a * m + b) % p
y=bin(x)[2:]
c=[y[i:i+85] for i in range(0,len(y),85)]
shuffle(c)
print(p)
print(c)
# p=11199186558148426014734492874345932099384932524559726349180064588241518696390926354448476750322781683505497782040786332571272422812867731614415519029276349
# c=['0010101111100011101101011111111001011000100110001001000000010001111011110101110011111', '0011010010010010110010011011001100110001100010101110001010001101110001100000111011010', '0110101101011101110000100001000000010001110110001010000000010110010101100100101110000', '0100111001011010000101100111100110101100011100100111011000110001111101000110110101101', '1100100110011101010011011111000101011011010000101100011001110100101000101101111110100', '1110111110001110000101100000000100111010110000001111010001101001100001010110101010001']
知识点
![](https://i-blog.csdnimg.cn/blog_migrate/afb4aedbc3557948c7f556b3f6c31e6b.png)
def Pell(D,numbers=100):
temp = continued_fraction(sqrt(D))
for i in range(number):
denom = temp.denominator(i) # 分母
num = temp.numerator(i) # 分子
if num^2 - D*denom^2 == 1:
return num,denom
return None,None
Pell(D)
可以参考这篇文章http://t.csdn.cn/FOjof
我的评价是不如在线求解捏
![](https://i-blog.csdnimg.cn/blog_migrate/320570752d5b800778ba4fbd979c6b48.jpeg)
http://www.numbertheory.org/php/pell.html 可以在这里在线求解Pell方程最小整数解
解题步骤
D = 0x1337 a**2 - D*b**2 == 1为Pell方程, 且解是无限的
网站在线解一下,得到方程a,b的最小整数解
a = 1809338099956399320,b = 25797719546469589
然后迭代去计算
from Crypto.Util.number import *
from itertools import permutations
D = 0x1337
a = [1809338099956399320]
b = [25797719546469589]
for i in range(20):
a, b = a + [a[-1] * a[0] + D * b[-1] * b[0]], b + [a[-1] * b[0] + b[-1] * a[0]]
p = 11199186558148426014734492874345932099384932524559726349180064588241518696390926354448476750322781683505497782040786332571272422812867731614415519029276349
c = ['0010101111100011101101011111111001011000100110001001000000010001111011110101110011111', '0011010010010010110010011011001100110001100010101110001010001101110001100000111011010', '0110101101011101110000100001000000010001110110001010000000010110010101100100101110000', '0100111001011010000101100111100110101100011100100111011000110001111101000110110101101', '1100100110011101010011011111000101011011010000101100011001110100101000101101111110100', '1110111110001110000101100000000100111010110000001111010001101001100001010110101010001']
res = [int(''.join(res), 2) for res in permutations(c)]
for i in range(len(a)):
ai, bi = a[i], b[i]
for c in res:
m = (c - bi) * inverse(ai, p) % p
flag = long_to_bytes(m)
if b'flag' in flag:
print(flag)
#b'flag{5b80aaa2-2bb2-0ef1-4aa0-a5a9387239d5}'