赛后拿到题复现,学习一下。
半决赛 RSA 题目:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 import randomfrom Crypto.Util.number import *flag = b'' k = 3 d = k/(2 *(k+1 )) ns = [] pqs = [] es = [] for i in range (3 ): p = getPrime(512 ) q = getPrime(512 ) if p < q: tmp = p p = q q = tmp n = p*q ns.append(n) pqs.append((p,q)) n = min (ns) x = random.randint(0 ,int (n^(d/2 ))) x = next_prime(x) for i in range (3 ): p,q = pqs[i][0 ],pqs[i][1 ] bound1 = int ((p-q)/(3 *(p+q)) * x * n ^ 0.25 ) bound2 = int ((p-q)/(3 *(p+q)) * x^2 * n ^ 0.25 ) z = random.randint(bound1,bound2) f = (p-1 )*(q-1 ) e = inverse(x^2 ,f) * z % f es.append(e) e = 8462913 c = pow (bytes_to_long(flag),e,ns[0 ]) print (f'ns={ns} ' )print (f'es={es} ' )print (f'c={c} ' )''' ns=[58456238154727772714762362790039415372652580738847549549926175214592421074440425380491278175531057453959583518365006871715668115289674464868754600641087664868445977308497244134179400977293896807231964047365956545629327100737851868274388108150918741474301542596310528990700043925342513137054619092876834352167, 77621328849675766747673031143217563980503830449890233197117569566535170499356584333526498228802079135043121885950830320777642529199704224484173792215691924850086027618183393165197503325417741686635820334799489140360184827244176669486536901652827052817389390205607840551799799037689580359943641014734459153393, 112244920700186260026594736958318991062998987080230137582151100770199379608284829383065111800934933346946496041561749555085922429662611986339400029890877247514987095240380019377389184545006798594193383230298132838994539491402564579629017309643629910561998268286162916487705908044261914142200286678017692930877] es=[46762963588977775648213636278524171408894671002158172701955774077187382885695296449518850546775920334764033057745226744111631183010556541467024035131602309988991836959736948179491431343087734419406823467043032520956443072556932946767546576469286010676651317873358203560021064830688914958086524112915123700678, 49605058941818136068558533413619424099600243928109466352604646203354430655695939177245076016870792265350960174089601299549033530643078866868937787258274475767441534991912769995268058506952466739575911255510940326565376471493045685544056383561868628029099619187607579109612157304977780126730283103824111801708, 35433601810279274137096137736120773703247868305827931187532982974242279082633517463016086358856291932337981126992048059591164336008738979183437333221010305682689432537562502148059203087673302900990705589870381203411821061168753251557946997898741497047442934600089950257888693394999451561437497637827070063398] c=45042826649205831967869785980034342377048541926664036544108272069702081866501394370318117629151408517708467341069558466115205805860156690204194355692872459196902123082567148537856941845388225814307822482217762135547080677443326657146552580523747535577686386312386011950929734955156100305548239483424574706729 '''
题目基于RSA,加密过程首先生成:
一个大约为192bit的$x$
三组RSA的密钥$p_i,q_i,n_i$
之后进行三轮加密,每轮加密生成一个620bit左右的$z_i$,并计算:
给出$e_i,n_i$,要求分解$n_1$进行RSA解密。
首先把$x$移到左边并展开成等式:
由于$e_i$和$\phi_i$数量级相近且$k_i$比较小,所以$k_i$是一个和$x^2$数量级接近的小量,因此再进一步把$\phi_i$展开的话会得到:
把未知量线性化一下就是:
与已知的系数$e_i,n_i+1$相比这几个变量都不大,所以造如下格:
这个格具有的线性关系是:
所以配平规约一下就可以求出$X,Y_i,Z_i$了,也就是我们现在拥有了:
$x^2$
$k_i$
$z_i - k_i(p_i+q_i)$
这个时候把已知量用上,记$C_i = e_ix^2 - k_i(n_i+1) $,重新组织一下上面的等式就是:
我们只需要分解$n_1$就可以了,所以我们利用:
来造一个格:
他的线性关系是:
同样的,前三列配平并将最后一列配上一个大系数就可以进行规约。然而规约后的第一行并不是我们的目标向量,而是如下形式:
原因很简单,因为上面的格显然存在一个向量是:
这显然比我们预期的向量短,所以LLL后的第二行实际上是与这个向量约减后的结果,换句话说我们只能从LLL后的第二行得到$p_1+q_1$的一半左右的高位而已,得不到准确结果。
而已知$p+q$高位分解$n$的问题就很常见了,首先在RealField上求解方程,可以把$p+q$高位转化到$p$的高位,经测试这样做一般会有254位是准确的,那么现在问题就变成了已知$p$的高254位求解$p$的copper问题了。
这个问题很经典,要加快这个过程可以用上以下几个小优化:
首先,从RealField求解的根中选择较大的那一个来copper,因为这样可以使small_roots
里的beta参数设置成0.5,从而提高上界
由于$p$是素数,所以可以不爆破二进制位,而爆破$p$模一些小素因子的余数,从而减小爆破量,比如这里由于已知254位,所以选择$2310=2 \cdot 3 \cdot 5 \cdot 7 \cdot 11$比较合适
有关这个优化的原理可以看我之前出的一道题目:
[tangcuxiaojkuai]easy_copper2 | NSSCTF
多进程XD,这个是最粗暴但是又最有用的优化,不用的话可能得爆接近十分钟
解出$p_1,q_1$之后会发现还有$e,\phi(n_1)$不互素的问题,并且$e$和$p-1,q-1$的gcd分别是$e$和3,所以模$p$下应该解的会很慢,放到模$q$下去开三次根会好一些。
exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 from Crypto.Util.number import *from multiprocessing import Poolfrom tqdm import *k = 3 d = k/(2 *(k+1 )) X = int (1024 *(d/2 )) Z = 630 ns = [58456238154727772714762362790039415372652580738847549549926175214592421074440425380491278175531057453959583518365006871715668115289674464868754600641087664868445977308497244134179400977293896807231964047365956545629327100737851868274388108150918741474301542596310528990700043925342513137054619092876834352167 , 77621328849675766747673031143217563980503830449890233197117569566535170499356584333526498228802079135043121885950830320777642529199704224484173792215691924850086027618183393165197503325417741686635820334799489140360184827244176669486536901652827052817389390205607840551799799037689580359943641014734459153393 , 112244920700186260026594736958318991062998987080230137582151100770199379608284829383065111800934933346946496041561749555085922429662611986339400029890877247514987095240380019377389184545006798594193383230298132838994539491402564579629017309643629910561998268286162916487705908044261914142200286678017692930877 ] es = [46762963588977775648213636278524171408894671002158172701955774077187382885695296449518850546775920334764033057745226744111631183010556541467024035131602309988991836959736948179491431343087734419406823467043032520956443072556932946767546576469286010676651317873358203560021064830688914958086524112915123700678 , 49605058941818136068558533413619424099600243928109466352604646203354430655695939177245076016870792265350960174089601299549033530643078866868937787258274475767441534991912769995268058506952466739575911255510940326565376471493045685544056383561868628029099619187607579109612157304977780126730283103824111801708 , 35433601810279274137096137736120773703247868305827931187532982974242279082633517463016086358856291932337981126992048059591164336008738979183437333221010305682689432537562502148059203087673302900990705589870381203411821061168753251557946997898741497047442934600089950257888693394999451561437497637827070063398 ] c = 45042826649205831967869785980034342377048541926664036544108272069702081866501394370318117629151408517708467341069558466115205805860156690204194355692872459196902123082567148537856941845388225814307822482217762135547080677443326657146552580523747535577686386312386011950929734955156100305548239483424574706729 L1 = Matrix(ZZ, 4 , 4 ) for i in range (1 , 4 ): L1[0 , i] = es[i-1 ] L1[i, i] = -ns[i-1 ] - 1 L1[0 , 0 ] = 2 ^513 res = L1.LLL()[0 ] x2, k1, k2, k3 = list (map (abs , L1.solve_left(res))) L2 = Matrix(ZZ, [ [1 , 0 , 0 , 1 ], [0 , 2 ^(Z-513 ), 0 , -k1], [0 , 0 , 2 ^Z, -(es[0 ]*x2 - k1*(ns[0 ]+1 ))] ]) L2[:, -1 :] *= 2 ^1000 L2 = L2.LLL() res = L2[1 ][1 ] // 2 ^(Z-513 ) PR.<x> = PolynomialRing(RealField(1000 )) f = x*(res-x) - ns[0 ] ph = (abs (int (max (f.roots(multiplicities=False )))) >> 258 << 258 ) // 2310 * 2310 def attack (p_low ): PR.<x> = PolynomialRing(Zmod(ns[0 ])) f = ph + 2310 *x + p_low f = f.monic() res = f.small_roots(X=2 ^258 //2310 , beta=0.5 , epsilon=0.016 ) if (res != []): p = 2310 *int (res[0 ]) + p_low + ph q = ns[0 ] // p print (p) print (q) return True pos = [] for i in range (1 ,2310 ): if (GCD(i,2310 ) == 1 ): pos.append(i) with Pool(16 ) as pool: for i in tqdm(pool.imap(attack, pos), total=len (pos)): if (i == True ): break p = 7696200979887856341831037613988614280823562431557099321251289719686349578851157595313091133333376255237947592610103860940743200558583228583143108125315529 q = 7595466686419558151205913432118661460574378336265188601308332178368424478703273480167149453312906478797521330243646557948961908036589158891684701262055023 e = 8462913 PR.<x> = PolynomialRing(Zmod(q)) f = x^3 - pow (c, inverse(e//3 , q-1 ), q) for i in f.roots(multiplicities=False ): print (long_to_bytes(int (i)))
noisy-nfsr 题目:
task.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 import secrets, signalfrom utils import nbit, LFSR, NFSR, NOISEdef proof_of_work (): import random, string, hashlib ss = '' .join(random.choices(string.ascii_letters + string.digits, k=20 )) sh = hashlib.sha256(ss.encode()).hexdigest() print (f"| sha256(XXXX + {ss[4 :]} ) == {sh} " ) prefix = input ("| XXXX>" ) return prefix == ss[:4 ] if __name__ == "__main__" : try : assert proof_of_work() signal.alarm(666 ) seed, mask = [secrets.randbits(12 ) | 2 **(12 -1 ) for _ in range (2 )] lfsr = LFSR(seed, mask) noise = NOISE(lfsr) seeds = [secrets.randbits(nbit) | 2 **(nbit-1 ) for _ in range (2 )] masks = [secrets.randbits(nbit) | 2 **(nbit-1 ) for _ in range (2 )] print (f"| {masks = } " ) args = [(512 , 128 ), (256 , 256 ), (128 , 512 )] n, m = args[int (input ('| args>' )) % len (args)] print ("| Good luck" ) for _ in range (n): print ("| Menu:\n| [H]it\n| [S]tand\n| [Q]uit" ) inp = input ("| inp>" ).lower() if inp == 'h' : lfsrs = [LFSR(seed, mask) for seed, mask in zip (seeds, masks)] nfsr = NFSR(*lfsrs, noise=noise) bits = nfsr.encrypt(b'\x00' *m) print (f"| {bits.hex () = } " ) else : if inp == 's' and all (int (input ('| seed>' )) == seed for seed in seeds): print ('| 🏁' , open ('flag' , 'r' ).read()) break print ("| Bye" ) except : print ("| Nah" )
utils.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 nbit = 128 class LFSR : def __init__ (self, seed: int , mask: int ): self.state = seed & (2 **nbit - 1 ) self.mask = mask & (2 **nbit - 1 ) def __next__ (self ): b = (self.state & self.mask).bit_count() & 1 self.state = ((self.state << 1 ) | b) & (2 **nbit - 1 ) return b def __call__ (self, bits: int ): out = 0 for _ in range (bits): out = (out << 1 ) | next (self) return out class NFSR : def __init__ (self, lfsr0: LFSR, lfsr1: LFSR, noise: iter ): self.lfsr0 = lfsr0 self.lfsr1 = lfsr1 self.noise = noise def __next__ (self ): b0, b1 = self.lfsr0(1 ), self.lfsr1(1 ) b = b0 ^ b1 ^ next (self.noise) return b def __call__ (self, bits: int ): out = 0 for _ in range (bits): out = (out << 1 ) | next (self) return out def encrypt (self, msg: bytes ): return bytes ([m ^ self(8 ) for m in msg]) def NOISE (lfsr: LFSR, p: float =2 /3 , prec: int =256 ): import secrets t = 2 **prec while True : if lfsr(1 ): yield int (secrets.randbelow(t) / t > p) else : yield int (secrets.randbelow(t) / t <= p)
题目基于nfsr,他有几个部件,每个部件分别的逻辑为:
回到题目,连接上靶机后,靶机会先做如下初始化:
之后正式进入交互,每次交互可以做:
任务理清楚了,那么下面就进入解题环节。
思路一 首先注意到以下几个事实:
noise对应的那个lfsr,其seed和mask都仅有12bit,并且由于MSB是1,所以爆破量只有11x2=22bit,也就是爆破2^22这个数量级,其中就存在正确的seed和mask
如果能用某种方式爆破得到noise的初始lfsr的话,那么也就等价于我们可以知道noise的lfsr的所有输出流。而由于noise的实际输出是这个输出流2/3概率偏转后的值,而我们有多组nfsr的输出,所以可以通过概率统计来确定nfsr里两个lfsr的输出
而由于nfsr对于两个lfsr来说仅仅是异或而已,在模2下是线性运算,所以如果没有noise的干扰的话,搜集足够比特就可以解线性方程得到两个lfsr的初始seed
这里足够比特指线性无关的256bit(128x2)
因此整个思路的唯一问题就只剩下如何爆破noise的初始lfsr了。这很简单,比如对于我们前两轮交互来说,我们拿到的输出就是:
这里括号内表示输出的比特数,noise及lfsr的下标表示起始比特的位置
那么做异或就得到:
把p概率翻转的函数记为$f$,那么对于上面这个异或值的每一个比特来说,都是:
所以只需要爆破11bit的seed以及11bit的mask,并统计输出是不是对于这个lfsr符合上面的分布即可。
但是实际上会发现这个做法有个问题就是太慢太慢了,虽然说他确实可以爆破出来,但是就算加多进程也没有办法在规定的alarm(666)
里跑出来,所以只能换思路。
思路二 由于noise的lfsr,他的mask只有12位,这代表着他的最大周期也就只会有$2^{12}-1$,并且有不小的概率周期不大(只有几百甚至几十)。
基于这一点,我们把目光从多组nfsr的输出转换到一组nfsr的输出,那么当noise的lfsr周期较小的时候,如果把这个周期记为T,那么对于同一组内的第i和第i+T个比特来说都有:
这里lfsr的下标t表示noise对应的lfsr的某个起始位置,不固定
把这两个比特异或起来就有:
之所以用中括号分成两部分,原因在于不同组的nfsr的输出用的是两个完全一样的lfsr。所以我们爆破T的话,当T正确的时候,这样的比特会因为异或了$[f(lfsr_t(1)) \oplus f(lfsr_t(1))]$的缘故,呈现出一个和随机分布不一样的分布,这就是检测T正确的依据。
举个例子就是,比如我们选择$n,m = (256,256)$,那么对于任意的i和正确的T来说,我们可以获得255个如下的异或比特:
$[f(lfsr_t(1)) \oplus f(lfsr_t(1))]$不是完全随机的0、1,推导一下会得到:
其中函数g表示p’概率翻转的函数,p’满足:
这个概率不是0.5,说明$[f(lfsr_t(1)) \oplus f(lfsr_t(1))]$的输出会有更大的概率是0或者1其中一个,而对于255组输出来说,他们的$[lfsr1_i(1) \oplus lfsr2_i(1) \oplus lfsr1_{i+T}(1) \oplus lfsr2_{i+T}(1)]$都一样,所以做统计发现分布不符合随机分布的话,就说明T正确了
有了正确的T之后,我们就可以确定我们获得的异或比特满足:
我们选取这些异或比特统计数据偏差较大的值(偏差大一些说明更可信),就可以确定下来一个比特等于:
搜集足够的比特来解线性方程即可。
说实话后面这部分实在感觉写不明白了,详情参考exp吧
这种方法对于解题来说做不到百分百成功率,导致失败的原因有:
需要周期T较小来提供更多异或比特来进行统计,所以T较大时解不出来
要搜集够256个线性无关的bit才能解出唯一seed,实际上这很难
不过解决的思路很简单粗暴,就反复重连就可以了。
exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 from Crypto.Util.number import *from itertools import productfrom hashlib import sha256import stringfrom pwn import *def proof_of_work (): table = string.digits + string.ascii_letters sh.recvuntil(b"| sha256(XXXX + " ) temp = sh.recvline() suffix = temp[:16 ].decode() hex1 = temp[20 :].strip().decode() for i in product(table, repeat=4 ): temp1 = "" .join(i) if (sha256((temp1+suffix).encode()).hexdigest() == hex1): sh.recvuntil(b"| XXXX>" ) sh.sendline(temp1.encode()) return while (1 ): sh = process(["python3" , "task.py" ]) proof_of_work() sh.recvuntil(b"| masks = " ) masks = eval (sh.recvline().strip().decode()) sh.recvuntil(b"| args>" ) sh.sendline(b"1" ) n, m = 255 , 256 output = [] for i in range (n): sh.recvuntil(b"| inp>" ) sh.sendline(b"h" ) sh.recvuntil(b"| bits.hex() =" ) output.append(bytes .fromhex(sh.recvline().strip().decode()[1 :-1 ])) from tqdm import * output_bin = [bin (bytes_to_long(i))[2 :].zfill(8 *m) for i in output] for T in trange(10 , 300 ): nums = 8 *m // T chunks = [[] for i in range (n)] for i in range (n): for j in range (nums): chunks[i].append(output_bin[i][j*T:(j+1 )*T]) xor_chunks = [[] for i in range (n)] for i in range (n): for j in range (1 , nums): xor_chunks[i].append(bin (int (chunks[i][0 ],2 ) ^^ int (chunks[i][j],2 ))[2 :].zfill(T)) Find = 0 for k in range (nums-1 ): bin_chunks = [] for j in range (T): temp = "" for i in range (n): temp += xor_chunks[i][k][j] bin_chunks.append(temp) for i in range (T): if (bin_chunks[i].count("0" ) < 100 or bin_chunks[i].count("1" ) < 100 ): Find += 1 break if (Find == nums-1 ): print (T) break nums = 8 *m // T chunks = [[] for i in range (n)] for i in range (n): for j in range (nums): chunks[i].append(output_bin[i][j*T:(j+1 )*T]) xor_chunks = [[] for i in range (n)] for i in range (n): for j in range (1 , nums): xor_chunks[i].append(bin (int (chunks[i][0 ],2 ) ^^ int (chunks[i][j],2 ))[2 :].zfill(T)) known_bits = [] for k in range (nums-1 ): bin_chunks = [] for j in range (T): temp = "" for i in range (n): temp += xor_chunks[i][k][j] bin_chunks.append(temp) for j in range (T): if (abs (bin_chunks[j].count("0" )-128 ) > 21 ): known_bits.append([j, k, int (bin_chunks[j].count("0" ) < 128 )]) print (known_bits) print (len (known_bits)) nbit = 128 L1 = Matrix(GF(2 ), nbit, nbit) L2 = Matrix(GF(2 ), nbit, nbit) for i in range (nbit-1 ): L1[i, i+1 ] = 1 L2[i, i+1 ] = 1 for i in range (nbit): L1[-1 , i] = int (bin (masks[0 ])[2 :].zfill(nbit)[i]) L2[-1 , i] = int (bin (masks[1 ])[2 :].zfill(nbit)[i]) L = Matrix(GF(2 ), 0 , 256 ) R = [] for i in known_bits: a, b, bit = i temp1 = ((L1^(a+1 ) + L1^((b+1 )*T+(a+1 )))[-1 ]).list () temp2 = ((L2^(a+1 ) + L2^((b+1 )*T+(a+1 )))[-1 ]).list () L = L.stack(vector(GF(2 ), temp1+temp2)) R.append(bit) R = vector(GF(2 ), R) SEED = L.solve_right(R) print (L.rank()) SEEDS = [int ("" .join(list (map (str , SEED[:128 ]))), 2 ), int ("" .join(list (map (str , SEED[128 :]))), 2 )] print (SEEDS) if (L.rank() >= 255 ): sh.recvuntil(b"| inp>" ) sh.sendline(b"s" ) sh.recvuntil(b'| seed>' ) sh.sendline(str (SEEDS[0 ]).encode()) sh.recvuntil(b'| seed>' ) sh.sendline(str (SEEDS[1 ]).encode()) print (sh.recvline()) break sh.close()
决赛 piff 题目:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 from sage.rings.finite_rings.hom_finite_field import FiniteFieldHomomorphism_genericfrom Crypto.Util.number import *from Crypto.Cipher import AESfrom secret import flagimport randomdef pad (msg ): return msg + bytes ([16 - len (msg) % 16 ]) * (16 - len (msg) % 16 ) def generate_irreducible_polynomial (R, n ): while True : f = R.random_element(degree=n) while f.degree() != n: f = R.random_element(degree=n) if f.is_irreducible(): return f def get_phi (R, t, stri ): t_str = str (t).split("a |--> " )[1 ].replace(stri,"x" ) return R(t_str) q = 41 n = 128 F = GF(q) R = PolynomialRing(F,'x' ) x = R.gen() f = generate_irreducible_polynomial(R,n).monic() F1 = generate_irreducible_polynomial(R,n).monic() F2 = generate_irreducible_polynomial(R,n).monic() k1 = GF(q^n, name = 'a' , modulus = f) k2 = GF(q^n, name = 'b' , modulus = F1) k3 = GF(q^n, name = 'c' , modulus = F2) t1 = FiniteFieldHomomorphism_generic(Hom(k1, k2)) t2 = FiniteFieldHomomorphism_generic(Hom(k1, k3)) phi1 = get_phi(R, t1, "b" ) phi2 = get_phi(R, t2, "c" ) k = [random.choice([0 ,1 ]) for _ in range (128 )] r = [random.choice([0 ,1 ]) for _ in range (128 )] m,r = R(k),R(r) p = 2 C = (p*phi1(x)*r(phi1(x)) + m(phi1(x))) % F1(x) key = int ('' .join(str (i) for i in k) , 2 ) aes = AES.new(long_to_bytes(key), mode=AES.MODE_ECB) cipher = aes.encrypt(pad(flag)) print ("F1 = {}" .format (F1))print ("φ1 = {}" .format (phi1))print ("F2 = {}" .format (F2))print ("φ2 = {}" .format (phi2))print ("C={}" .format (C))print ("cipher={}" .format (cipher))""" F1 = x^128 + 25*x^127 + 32*x^126 + 15*x^125 + 8*x^124 + 24*x^123 + 5*x^122 + 16*x^121 + 27*x^120 + 33*x^119 + 32*x^118 + 11*x^117 + 37*x^116 + 9*x^115 + 23*x^114 + 29*x^113 + 30*x^112 + 14*x^111 + 6*x^110 + 38*x^109 + 22*x^108 + 39*x^106 + 16*x^105 + 19*x^104 + 15*x^103 + 31*x^102 + 33*x^101 + 39*x^100 + 7*x^99 + 3*x^98 + 30*x^97 + 34*x^95 + 15*x^94 + 28*x^93 + 40*x^92 + 29*x^91 + 30*x^90 + 35*x^89 + 34*x^88 + 29*x^87 + 11*x^86 + 6*x^85 + 28*x^84 + x^83 + 12*x^82 + 2*x^81 + 7*x^80 + 12*x^79 + 5*x^78 + 35*x^77 + 6*x^76 + 23*x^75 + 21*x^74 + 6*x^73 + 32*x^72 + 23*x^71 + 11*x^70 + 8*x^69 + 18*x^68 + 38*x^67 + 13*x^66 + 38*x^64 + 19*x^63 + 36*x^62 + 21*x^61 + 12*x^60 + 28*x^59 + 22*x^58 + 19*x^57 + 8*x^56 + 7*x^55 + 34*x^54 + 9*x^53 + 15*x^52 + 37*x^51 + 6*x^50 + 22*x^49 + 19*x^48 + 33*x^47 + 2*x^46 + x^45 + 17*x^44 + 20*x^43 + 7*x^42 + 37*x^41 + 10*x^40 + 13*x^39 + 2*x^38 + 22*x^37 + 32*x^36 + 40*x^35 + 3*x^34 + 40*x^33 + 23*x^32 + 3*x^31 + 15*x^30 + 14*x^29 + 40*x^28 + 33*x^27 + 31*x^26 + 7*x^25 + 18*x^24 + 23*x^23 + 3*x^22 + 35*x^21 + 2*x^20 + 32*x^19 + 3*x^18 + 39*x^17 + 20*x^16 + 40*x^15 + 25*x^14 + 38*x^13 + 14*x^12 + 11*x^11 + 13*x^10 + 16*x^9 + 3*x^8 + 39*x^7 + 29*x^6 + 7*x^5 + 26*x^4 + 9*x^3 + 25*x^2 + 8*x + 4 φ1 = 22*x^126 + 37*x^125 + 33*x^124 + 23*x^123 + 9*x^122 + 12*x^121 + 22*x^120 + 7*x^119 + 12*x^118 + 23*x^117 + 22*x^116 + 16*x^115 + 12*x^114 + 6*x^113 + 23*x^112 + 9*x^111 + 9*x^110 + 23*x^109 + 27*x^108 + 38*x^107 + 21*x^106 + 38*x^105 + 19*x^103 + 12*x^102 + 20*x^101 + x^100 + 36*x^99 + 15*x^98 + 26*x^97 + 14*x^96 + 4*x^95 + 39*x^94 + 29*x^93 + 13*x^92 + 11*x^91 + 24*x^90 + 28*x^89 + 40*x^88 + 6*x^87 + x^86 + 30*x^85 + 33*x^84 + 21*x^83 + 38*x^82 + 24*x^81 + 3*x^80 + 29*x^79 + 32*x^78 + 14*x^77 + 28*x^76 + 19*x^75 + 21*x^74 + 16*x^73 + 32*x^72 + 4*x^71 + 24*x^70 + 30*x^69 + 18*x^68 + 19*x^67 + 16*x^66 + 12*x^65 + 24*x^64 + 26*x^63 + 10*x^62 + 25*x^61 + 15*x^60 + 22*x^59 + 35*x^58 + 27*x^57 + 35*x^56 + 25*x^55 + 3*x^54 + 4*x^53 + 27*x^52 + 12*x^51 + 20*x^50 + 29*x^49 + 29*x^48 + 11*x^47 + 34*x^46 + 13*x^45 + 5*x^44 + 5*x^43 + 26*x^42 + 29*x^41 + 15*x^40 + 21*x^39 + 24*x^38 + 26*x^37 + 2*x^36 + 22*x^35 + 40*x^34 + 14*x^33 + x^32 + 28*x^31 + 28*x^30 + 29*x^29 + 31*x^28 + 12*x^27 + 10*x^26 + 35*x^25 + 5*x^24 + 18*x^23 + 23*x^22 + 33*x^21 + 21*x^20 + 37*x^19 + 30*x^18 + 19*x^17 + 37*x^16 + 8*x^15 + 34*x^14 + 25*x^13 + 29*x^12 + 29*x^11 + 8*x^10 + 19*x^9 + 40*x^8 + 35*x^7 + 18*x^6 + 2*x^5 + 32*x^4 + 3*x^3 + 11*x^2 + 10*x + 36 F2 = x^128 + 39*x^127 + 16*x^126 + 24*x^125 + 18*x^124 + 31*x^123 + 12*x^122 + 37*x^121 + 11*x^120 + 15*x^119 + 34*x^118 + 25*x^117 + 27*x^116 + 4*x^115 + 16*x^114 + 18*x^113 + 31*x^112 + 40*x^111 + 9*x^110 + 15*x^109 + 23*x^108 + 24*x^107 + 26*x^106 + 6*x^105 + 32*x^104 + 16*x^103 + 38*x^102 + 2*x^101 + 3*x^100 + 40*x^99 + 30*x^98 + 27*x^97 + 24*x^96 + 7*x^95 + 40*x^94 + 28*x^93 + 11*x^92 + 30*x^91 + 36*x^90 + x^89 + 16*x^88 + 36*x^87 + 14*x^86 + x^84 + 33*x^83 + 5*x^82 + 15*x^81 + 33*x^80 + 28*x^79 + 39*x^78 + 16*x^77 + 29*x^76 + 34*x^75 + 38*x^74 + 34*x^73 + 25*x^72 + 9*x^71 + 5*x^70 + 19*x^69 + 39*x^68 + 23*x^67 + x^66 + 4*x^65 + 11*x^64 + 15*x^63 + 25*x^62 + 36*x^61 + 40*x^60 + 18*x^59 + 14*x^58 + 2*x^57 + 4*x^56 + 2*x^55 + 26*x^54 + 13*x^53 + 17*x^52 + 38*x^51 + 12*x^50 + 12*x^49 + 18*x^48 + 40*x^47 + 10*x^46 + 17*x^45 + 37*x^44 + 34*x^43 + 34*x^42 + 25*x^41 + 16*x^40 + 16*x^39 + 11*x^38 + 36*x^36 + 31*x^35 + 4*x^33 + 17*x^32 + 8*x^31 + 17*x^30 + 30*x^29 + 30*x^28 + 26*x^27 + 21*x^26 + 29*x^25 + 15*x^24 + 38*x^23 + 19*x^22 + 24*x^21 + 7*x^20 + 5*x^19 + 2*x^18 + 31*x^17 + 13*x^16 + 14*x^15 + 40*x^14 + 29*x^13 + 30*x^12 + 37*x^11 + 33*x^10 + 11*x^9 + 12*x^8 + 14*x^7 + 34*x^6 + 18*x^5 + 13*x^4 + 11*x^3 + 31*x^2 + 31*x + 25 φ2 = 29*x^126 + 38*x^125 + 25*x^124 + 11*x^123 + 13*x^122 + 23*x^121 + 2*x^120 + 34*x^119 + 3*x^118 + 40*x^117 + 19*x^116 + 17*x^115 + 31*x^114 + 6*x^113 + 28*x^112 + 34*x^111 + 37*x^110 + 25*x^109 + 39*x^108 + x^107 + 33*x^106 + 11*x^105 + 8*x^104 + 37*x^103 + 26*x^102 + 27*x^101 + 10*x^100 + 10*x^99 + 26*x^97 + 31*x^96 + 13*x^95 + 26*x^94 + 32*x^93 + 21*x^92 + 14*x^91 + 23*x^90 + 14*x^89 + 12*x^88 + 36*x^87 + 35*x^86 + 10*x^85 + 16*x^84 + 6*x^83 + x^82 + 13*x^81 + 23*x^80 + 27*x^79 + 23*x^78 + 31*x^77 + 2*x^76 + 7*x^75 + 39*x^74 + 17*x^73 + 23*x^72 + 3*x^71 + 37*x^70 + 17*x^69 + 17*x^68 + 29*x^67 + 4*x^66 + 30*x^65 + 11*x^64 + 21*x^63 + 11*x^62 + 8*x^61 + 32*x^60 + 26*x^59 + 7*x^58 + 37*x^57 + 4*x^55 + 26*x^54 + 37*x^53 + 27*x^52 + 40*x^51 + 6*x^50 + 9*x^49 + 14*x^48 + 23*x^47 + 9*x^46 + 18*x^45 + 21*x^44 + 37*x^43 + 13*x^42 + 24*x^41 + 11*x^40 + 40*x^39 + 5*x^38 + 32*x^37 + 7*x^36 + 31*x^35 + 4*x^34 + 12*x^33 + 24*x^32 + 40*x^31 + 16*x^30 + 23*x^29 + 29*x^28 + 12*x^27 + 32*x^26 + 25*x^25 + 12*x^24 + x^23 + 5*x^22 + 30*x^21 + 30*x^20 + 17*x^19 + 24*x^17 + 17*x^16 + 18*x^15 + 31*x^14 + 37*x^13 + 18*x^12 + 14*x^11 + 5*x^10 + 2*x^9 + 23*x^8 + 21*x^7 + 29*x^6 + 39*x^5 + 13*x^3 + 13*x^2 + 25*x + 30 C=20*x^127 + 31*x^126 + 21*x^125 + 19*x^124 + 30*x^123 + 4*x^122 + 32*x^121 + 19*x^120 + 24*x^119 + 33*x^118 + 40*x^117 + 39*x^116 + 3*x^115 + 32*x^113 + 24*x^112 + 31*x^111 + 15*x^110 + 7*x^109 + 25*x^108 + 16*x^107 + 13*x^106 + 5*x^105 + 11*x^104 + 38*x^103 + 38*x^102 + 28*x^101 + 33*x^100 + 32*x^99 + 24*x^98 + 26*x^97 + 36*x^96 + 32*x^95 + 38*x^94 + 26*x^93 + 28*x^91 + 37*x^90 + 35*x^89 + 25*x^88 + 14*x^87 + 9*x^86 + 33*x^85 + 15*x^84 + 18*x^83 + 12*x^82 + 34*x^81 + 12*x^80 + 35*x^79 + 40*x^78 + 9*x^77 + 23*x^76 + 23*x^75 + 12*x^74 + 7*x^73 + 27*x^72 + 7*x^71 + 14*x^69 + 40*x^68 + 34*x^66 + 39*x^65 + 30*x^64 + 23*x^63 + 8*x^62 + 28*x^61 + 37*x^60 + 34*x^59 + 35*x^58 + 33*x^57 + 3*x^56 + 28*x^55 + 39*x^54 + 13*x^53 + 31*x^52 + 7*x^51 + 38*x^49 + 40*x^48 + 11*x^47 + 30*x^46 + 19*x^45 + 38*x^44 + 37*x^43 + 21*x^42 + 9*x^41 + 8*x^40 + 31*x^39 + 22*x^38 + 24*x^37 + 8*x^36 + 17*x^35 + 16*x^34 + 29*x^33 + 32*x^32 + 17*x^31 + 39*x^30 + 20*x^29 + 4*x^27 + 40*x^26 + 6*x^24 + 27*x^23 + 25*x^22 + 4*x^21 + 5*x^20 + 8*x^19 + 28*x^18 + 21*x^17 + x^16 + 12*x^15 + 19*x^14 + 29*x^13 + 2*x^12 + 9*x^11 + 34*x^10 + 16*x^9 + 12*x^8 + 21*x^7 + 8*x^6 + 23*x^5 + 37*x^4 + 31*x^3 + 25*x^2 + 20*x + 21 cipher=b'\xc9\xe2\xcdzo\xa1\xcc\xe1\x0e(\x98W\xd3\xb9\x85X\xa3!P\xab\x00\x1cR r\xb4\xb8\xed\x8f\x83\x15r' """
这个题目和强网杯的electronic game有一定相关性:
2024-强网杯-wp-crypto | 糖醋小鸡块的blog (tangcuxiaojikuai.xyz)
所以接下来某些部分的推导可以看上面这篇文章。
题目在模$q=41$下先生成三个度为128的不可约多项式$f(x),F_1(x),F_2(x)$,并定义三个有限域$k_1,k_2,k_3$,分别以这三个不可约多项式作为模多项式,并定义两个同态:
之后生成两个系数均由0、1组成的多项式$m(x),r(x)$,并在模$F_1$下计算:
给出$F_1(x),\phi_1(x),F_2(x),\phi_2(x),C(x)$,要求解出$m(x)$从而解AES得到flag。
思路一 在强网杯的electronic game里推导过同态的矩阵表示,记k1表示的矩阵为$M_1$,他就满足:
1 M1 = matrix([(core**i).list () for i in range (n)])
这里的$M_1$是个n阶方阵,而实际上在强网杯那题里面用的是:
1 matrix([(core**i).list () for i in range (n+1 )])
记这个矩阵为$M_1’$,他并不是一个方阵,而是129x128的矩阵。
但实际上两者没有什么区别,假设现在有多项式$a(x)\in k_1,b(x) \in k_2$满足:
那么把$a(x),b(x)$都表示为长为128的向量$a,b$,就有:
而实际上,把a表示成长为129的向量$a’$($x^{128}$位置置0即可),那么就满足:
所以实际上没什么区别,唯一的区别在于如果把$k_1$的模多项式$f(x)$表示成向量$f$的话,由于他的度是128,所以只能表示成长129的向量,因此只能用$M_1’$来进行运算,并且满足:
这里有一个有趣的事实,那就是$f$向量就是$M_1’$的左核
有了$M_1$之后,由于在商环下进行多项式乘法也可以用矩阵表示,所以可以把乘$\phi_1(x)$对应的矩阵记为矩阵$M_2$,所以$C$的计算过程就可以从多项式完全转成矩阵方程:
由于$m,r$都是0、1组成的向量,所以在模41下会比较小,因此可以稍作优化,用如下矩阵方程去LLL一下:
如预期一样可以在LLL之后的向量找到$r,m$,之后就解AES就好了。
exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 from sage.rings.finite_rings.hom_finite_field import FiniteFieldHomomorphism_genericfrom Crypto.Util.number import *from Crypto.Cipher import AESq = 41 n = 128 F = GF(q) R = PolynomialRing(F,'x' ) x = R.gen() F1 = x^128 + 25 *x^127 + 32 *x^126 + 15 *x^125 + 8 *x^124 + 24 *x^123 + 5 *x^122 + 16 *x^121 + 27 *x^120 + 33 *x^119 + 32 *x^118 + 11 *x^117 + 37 *x^116 + 9 *x^115 + 23 *x^114 + 29 *x^113 + 30 *x^112 + 14 *x^111 + 6 *x^110 + 38 *x^109 + 22 *x^108 + 39 *x^106 + 16 *x^105 + 19 *x^104 + 15 *x^103 + 31 *x^102 + 33 *x^101 + 39 *x^100 + 7 *x^99 + 3 *x^98 + 30 *x^97 + 34 *x^95 + 15 *x^94 + 28 *x^93 + 40 *x^92 + 29 *x^91 + 30 *x^90 + 35 *x^89 + 34 *x^88 + 29 *x^87 + 11 *x^86 + 6 *x^85 + 28 *x^84 + x^83 + 12 *x^82 + 2 *x^81 + 7 *x^80 + 12 *x^79 + 5 *x^78 + 35 *x^77 + 6 *x^76 + 23 *x^75 + 21 *x^74 + 6 *x^73 + 32 *x^72 + 23 *x^71 + 11 *x^70 + 8 *x^69 + 18 *x^68 + 38 *x^67 + 13 *x^66 + 38 *x^64 + 19 *x^63 + 36 *x^62 + 21 *x^61 + 12 *x^60 + 28 *x^59 + 22 *x^58 + 19 *x^57 + 8 *x^56 + 7 *x^55 + 34 *x^54 + 9 *x^53 + 15 *x^52 + 37 *x^51 + 6 *x^50 + 22 *x^49 + 19 *x^48 + 33 *x^47 + 2 *x^46 + x^45 + 17 *x^44 + 20 *x^43 + 7 *x^42 + 37 *x^41 + 10 *x^40 + 13 *x^39 + 2 *x^38 + 22 *x^37 + 32 *x^36 + 40 *x^35 + 3 *x^34 + 40 *x^33 + 23 *x^32 + 3 *x^31 + 15 *x^30 + 14 *x^29 + 40 *x^28 + 33 *x^27 + 31 *x^26 + 7 *x^25 + 18 *x^24 + 23 *x^23 + 3 *x^22 + 35 *x^21 + 2 *x^20 + 32 *x^19 + 3 *x^18 + 39 *x^17 + 20 *x^16 + 40 *x^15 + 25 *x^14 + 38 *x^13 + 14 *x^12 + 11 *x^11 + 13 *x^10 + 16 *x^9 + 3 *x^8 + 39 *x^7 + 29 *x^6 + 7 *x^5 + 26 *x^4 + 9 *x^3 + 25 *x^2 + 8 *x + 4 φ1 = 22 *x^126 + 37 *x^125 + 33 *x^124 + 23 *x^123 + 9 *x^122 + 12 *x^121 + 22 *x^120 + 7 *x^119 + 12 *x^118 + 23 *x^117 + 22 *x^116 + 16 *x^115 + 12 *x^114 + 6 *x^113 + 23 *x^112 + 9 *x^111 + 9 *x^110 + 23 *x^109 + 27 *x^108 + 38 *x^107 + 21 *x^106 + 38 *x^105 + 19 *x^103 + 12 *x^102 + 20 *x^101 + x^100 + 36 *x^99 + 15 *x^98 + 26 *x^97 + 14 *x^96 + 4 *x^95 + 39 *x^94 + 29 *x^93 + 13 *x^92 + 11 *x^91 + 24 *x^90 + 28 *x^89 + 40 *x^88 + 6 *x^87 + x^86 + 30 *x^85 + 33 *x^84 + 21 *x^83 + 38 *x^82 + 24 *x^81 + 3 *x^80 + 29 *x^79 + 32 *x^78 + 14 *x^77 + 28 *x^76 + 19 *x^75 + 21 *x^74 + 16 *x^73 + 32 *x^72 + 4 *x^71 + 24 *x^70 + 30 *x^69 + 18 *x^68 + 19 *x^67 + 16 *x^66 + 12 *x^65 + 24 *x^64 + 26 *x^63 + 10 *x^62 + 25 *x^61 + 15 *x^60 + 22 *x^59 + 35 *x^58 + 27 *x^57 + 35 *x^56 + 25 *x^55 + 3 *x^54 + 4 *x^53 + 27 *x^52 + 12 *x^51 + 20 *x^50 + 29 *x^49 + 29 *x^48 + 11 *x^47 + 34 *x^46 + 13 *x^45 + 5 *x^44 + 5 *x^43 + 26 *x^42 + 29 *x^41 + 15 *x^40 + 21 *x^39 + 24 *x^38 + 26 *x^37 + 2 *x^36 + 22 *x^35 + 40 *x^34 + 14 *x^33 + x^32 + 28 *x^31 + 28 *x^30 + 29 *x^29 + 31 *x^28 + 12 *x^27 + 10 *x^26 + 35 *x^25 + 5 *x^24 + 18 *x^23 + 23 *x^22 + 33 *x^21 + 21 *x^20 + 37 *x^19 + 30 *x^18 + 19 *x^17 + 37 *x^16 + 8 *x^15 + 34 *x^14 + 25 *x^13 + 29 *x^12 + 29 *x^11 + 8 *x^10 + 19 *x^9 + 40 *x^8 + 35 *x^7 + 18 *x^6 + 2 *x^5 + 32 *x^4 + 3 *x^3 + 11 *x^2 + 10 *x + 36 C = 20 *x^127 + 31 *x^126 + 21 *x^125 + 19 *x^124 + 30 *x^123 + 4 *x^122 + 32 *x^121 + 19 *x^120 + 24 *x^119 + 33 *x^118 + 40 *x^117 + 39 *x^116 + 3 *x^115 + 32 *x^113 + 24 *x^112 + 31 *x^111 + 15 *x^110 + 7 *x^109 + 25 *x^108 + 16 *x^107 + 13 *x^106 + 5 *x^105 + 11 *x^104 + 38 *x^103 + 38 *x^102 + 28 *x^101 + 33 *x^100 + 32 *x^99 + 24 *x^98 + 26 *x^97 + 36 *x^96 + 32 *x^95 + 38 *x^94 + 26 *x^93 + 28 *x^91 + 37 *x^90 + 35 *x^89 + 25 *x^88 + 14 *x^87 + 9 *x^86 + 33 *x^85 + 15 *x^84 + 18 *x^83 + 12 *x^82 + 34 *x^81 + 12 *x^80 + 35 *x^79 + 40 *x^78 + 9 *x^77 + 23 *x^76 + 23 *x^75 + 12 *x^74 + 7 *x^73 + 27 *x^72 + 7 *x^71 + 14 *x^69 + 40 *x^68 + 34 *x^66 + 39 *x^65 + 30 *x^64 + 23 *x^63 + 8 *x^62 + 28 *x^61 + 37 *x^60 + 34 *x^59 + 35 *x^58 + 33 *x^57 + 3 *x^56 + 28 *x^55 + 39 *x^54 + 13 *x^53 + 31 *x^52 + 7 *x^51 + 38 *x^49 + 40 *x^48 + 11 *x^47 + 30 *x^46 + 19 *x^45 + 38 *x^44 + 37 *x^43 + 21 *x^42 + 9 *x^41 + 8 *x^40 + 31 *x^39 + 22 *x^38 + 24 *x^37 + 8 *x^36 + 17 *x^35 + 16 *x^34 + 29 *x^33 + 32 *x^32 + 17 *x^31 + 39 *x^30 + 20 *x^29 + 4 *x^27 + 40 *x^26 + 6 *x^24 + 27 *x^23 + 25 *x^22 + 4 *x^21 + 5 *x^20 + 8 *x^19 + 28 *x^18 + 21 *x^17 + x^16 + 12 *x^15 + 19 *x^14 + 29 *x^13 + 2 *x^12 + 9 *x^11 + 34 *x^10 + 16 *x^9 + 12 *x^8 + 21 *x^7 + 8 *x^6 + 23 *x^5 + 37 *x^4 + 31 *x^3 + 25 *x^2 + 20 *x + 21 cipher=b'\xc9\xe2\xcdzo\xa1\xcc\xe1\x0e(\x98W\xd3\xb9\x85X\xa3!P\xab\x00\x1cR r\xb4\xb8\xed\x8f\x83\x15r' import randomk1 = GF(q^n, name = 'b' , modulus = F1) b = k1.gen() core = 22 *b^126 + 37 *b^125 + 33 *b^124 + 23 *b^123 + 9 *b^122 + 12 *b^121 + 22 *b^120 + 7 *b^119 + 12 *b^118 + 23 *b^117 + 22 *b^116 + 16 *b^115 + 12 *b^114 + 6 *b^113 + 23 *b^112 + 9 *b^111 + 9 *b^110 + 23 *b^109 + 27 *b^108 + 38 *b^107 + 21 *b^106 + 38 *b^105 + 19 *b^103 + 12 *b^102 + 20 *b^101 + b^100 + 36 *b^99 + 15 *b^98 + 26 *b^97 + 14 *b^96 + 4 *b^95 + 39 *b^94 + 29 *b^93 + 13 *b^92 + 11 *b^91 + 24 *b^90 + 28 *b^89 + 40 *b^88 + 6 *b^87 + b^86 + 30 *b^85 + 33 *b^84 + 21 *b^83 + 38 *b^82 + 24 *b^81 + 3 *b^80 + 29 *b^79 + 32 *b^78 + 14 *b^77 + 28 *b^76 + 19 *b^75 + 21 *b^74 + 16 *b^73 + 32 *b^72 + 4 *b^71 + 24 *b^70 + 30 *b^69 + 18 *b^68 + 19 *b^67 + 16 *b^66 + 12 *b^65 + 24 *b^64 + 26 *b^63 + 10 *b^62 + 25 *b^61 + 15 *b^60 + 22 *b^59 + 35 *b^58 + 27 *b^57 + 35 *b^56 + 25 *b^55 + 3 *b^54 + 4 *b^53 + 27 *b^52 + 12 *b^51 + 20 *b^50 + 29 *b^49 + 29 *b^48 + 11 *b^47 + 34 *b^46 + 13 *b^45 + 5 *b^44 + 5 *b^43 + 26 *b^42 + 29 *b^41 + 15 *b^40 + 21 *b^39 + 24 *b^38 + 26 *b^37 + 2 *b^36 + 22 *b^35 + 40 *b^34 + 14 *b^33 + b^32 + 28 *b^31 + 28 *b^30 + 29 *b^29 + 31 *b^28 + 12 *b^27 + 10 *b^26 + 35 *b^25 + 5 *b^24 + 18 *b^23 + 23 *b^22 + 33 *b^21 + 21 *b^20 + 37 *b^19 + 30 *b^18 + 19 *b^17 + 37 *b^16 + 8 *b^15 + 34 *b^14 + 25 *b^13 + 29 *b^12 + 29 *b^11 + 8 *b^10 + 19 *b^9 + 40 *b^8 + 35 *b^7 + 18 *b^6 + 2 *b^5 + 32 *b^4 + 3 *b^3 + 11 *b^2 + 10 *b + 36 M1 = matrix([(core**i).list () for i in range (n)]) k = [random.choice([0 ,1 ]) for _ in range (128 )] r = [random.choice([0 ,1 ]) for _ in range (128 )] rr = vector(GF(q), r) m,r = R(k),R(r) assert (r(φ1 ) % F1).list () == (rr * M1).list ()def construct_poly_mul_mat (n,v,b ): assert v[-1 ] == 1 mat1 = Matrix(ZZ,n,2 *n-1 ) for i in range (n): for j in range (n): mat1[i,j+i] = b[j] mat2 = Matrix(ZZ,2 *n-1 ,n) for i in range (n): mat2[i,i] = 1 for i in range (n,2 *n-1 ): for j in range (i-n,n): mat2[i,j] = -v[j-(i-n)] init_row = vector(ZZ,n*[0 ]) for j in range (i-n): temp = -v[n-1 -j]*vector(ZZ,mat2[i-j-1 ]) init_row += temp for j in range (n): mat2[i,j] += init_row[j] return (mat1*mat2) PRp.<x> = PolynomialRing(Zmod(q)) f = F1 v = f.list () M2 = construct_poly_mul_mat(n,v,φ1 (x).list ()+[0 ]*2 ) assert ((φ1 (x)*r(φ1 (x))) % F1(x)).list () == (rr * M1 * M2).list ()M = 2 *M1*M2*M1^(-1 ) CC = vector(GF(q), C) L = block_matrix(ZZ,[ [-q, 0 , 0 ], [-M, 1 , 0 ], [Matrix(ZZ, (CC*M1^(-1 )).list ()), 0 , 1 ] ]) L = L.LLL() for i in L: if (all (abs (j) <= 1 for j in i)): m = i[:128 ] key = int ('' .join(str (jj) for jj in m) , 2 ) aes = AES.new(long_to_bytes(key), mode=AES.MODE_ECB) flag = aes.decrypt(cipher) print (flag) break
思路二 而做完后会发现,有几个东西似乎没有用上:
$F_2(x)$
计算$C(x)$时乘的那个2(因为乘多少都不影响用LLL解)
所以预期应该不是这样的,0、1向量的作用不应该是短向量,而应该是要到模2下解才对。
而这很简单,回顾$C$对应的矩阵方程:
和刚才一样有:
这样求逆其实就是$\phi_1$对应的逆而已,所以此时得到的其实是:
也就是:
因为$r(x),m(x)$系数都是0或者1,所以这个多项式乘法不可能超过$q=41$,所以实际上直接模2就是向量$m$了。
exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 from sage.rings.finite_rings.hom_finite_field import FiniteFieldHomomorphism_genericfrom Crypto.Util.number import *from Crypto.Cipher import AESq = 41 n = 128 F = GF(q) R = PolynomialRing(F,'x' ) x = R.gen() F1 = x^128 + 25 *x^127 + 32 *x^126 + 15 *x^125 + 8 *x^124 + 24 *x^123 + 5 *x^122 + 16 *x^121 + 27 *x^120 + 33 *x^119 + 32 *x^118 + 11 *x^117 + 37 *x^116 + 9 *x^115 + 23 *x^114 + 29 *x^113 + 30 *x^112 + 14 *x^111 + 6 *x^110 + 38 *x^109 + 22 *x^108 + 39 *x^106 + 16 *x^105 + 19 *x^104 + 15 *x^103 + 31 *x^102 + 33 *x^101 + 39 *x^100 + 7 *x^99 + 3 *x^98 + 30 *x^97 + 34 *x^95 + 15 *x^94 + 28 *x^93 + 40 *x^92 + 29 *x^91 + 30 *x^90 + 35 *x^89 + 34 *x^88 + 29 *x^87 + 11 *x^86 + 6 *x^85 + 28 *x^84 + x^83 + 12 *x^82 + 2 *x^81 + 7 *x^80 + 12 *x^79 + 5 *x^78 + 35 *x^77 + 6 *x^76 + 23 *x^75 + 21 *x^74 + 6 *x^73 + 32 *x^72 + 23 *x^71 + 11 *x^70 + 8 *x^69 + 18 *x^68 + 38 *x^67 + 13 *x^66 + 38 *x^64 + 19 *x^63 + 36 *x^62 + 21 *x^61 + 12 *x^60 + 28 *x^59 + 22 *x^58 + 19 *x^57 + 8 *x^56 + 7 *x^55 + 34 *x^54 + 9 *x^53 + 15 *x^52 + 37 *x^51 + 6 *x^50 + 22 *x^49 + 19 *x^48 + 33 *x^47 + 2 *x^46 + x^45 + 17 *x^44 + 20 *x^43 + 7 *x^42 + 37 *x^41 + 10 *x^40 + 13 *x^39 + 2 *x^38 + 22 *x^37 + 32 *x^36 + 40 *x^35 + 3 *x^34 + 40 *x^33 + 23 *x^32 + 3 *x^31 + 15 *x^30 + 14 *x^29 + 40 *x^28 + 33 *x^27 + 31 *x^26 + 7 *x^25 + 18 *x^24 + 23 *x^23 + 3 *x^22 + 35 *x^21 + 2 *x^20 + 32 *x^19 + 3 *x^18 + 39 *x^17 + 20 *x^16 + 40 *x^15 + 25 *x^14 + 38 *x^13 + 14 *x^12 + 11 *x^11 + 13 *x^10 + 16 *x^9 + 3 *x^8 + 39 *x^7 + 29 *x^6 + 7 *x^5 + 26 *x^4 + 9 *x^3 + 25 *x^2 + 8 *x + 4 φ1 = 22 *x^126 + 37 *x^125 + 33 *x^124 + 23 *x^123 + 9 *x^122 + 12 *x^121 + 22 *x^120 + 7 *x^119 + 12 *x^118 + 23 *x^117 + 22 *x^116 + 16 *x^115 + 12 *x^114 + 6 *x^113 + 23 *x^112 + 9 *x^111 + 9 *x^110 + 23 *x^109 + 27 *x^108 + 38 *x^107 + 21 *x^106 + 38 *x^105 + 19 *x^103 + 12 *x^102 + 20 *x^101 + x^100 + 36 *x^99 + 15 *x^98 + 26 *x^97 + 14 *x^96 + 4 *x^95 + 39 *x^94 + 29 *x^93 + 13 *x^92 + 11 *x^91 + 24 *x^90 + 28 *x^89 + 40 *x^88 + 6 *x^87 + x^86 + 30 *x^85 + 33 *x^84 + 21 *x^83 + 38 *x^82 + 24 *x^81 + 3 *x^80 + 29 *x^79 + 32 *x^78 + 14 *x^77 + 28 *x^76 + 19 *x^75 + 21 *x^74 + 16 *x^73 + 32 *x^72 + 4 *x^71 + 24 *x^70 + 30 *x^69 + 18 *x^68 + 19 *x^67 + 16 *x^66 + 12 *x^65 + 24 *x^64 + 26 *x^63 + 10 *x^62 + 25 *x^61 + 15 *x^60 + 22 *x^59 + 35 *x^58 + 27 *x^57 + 35 *x^56 + 25 *x^55 + 3 *x^54 + 4 *x^53 + 27 *x^52 + 12 *x^51 + 20 *x^50 + 29 *x^49 + 29 *x^48 + 11 *x^47 + 34 *x^46 + 13 *x^45 + 5 *x^44 + 5 *x^43 + 26 *x^42 + 29 *x^41 + 15 *x^40 + 21 *x^39 + 24 *x^38 + 26 *x^37 + 2 *x^36 + 22 *x^35 + 40 *x^34 + 14 *x^33 + x^32 + 28 *x^31 + 28 *x^30 + 29 *x^29 + 31 *x^28 + 12 *x^27 + 10 *x^26 + 35 *x^25 + 5 *x^24 + 18 *x^23 + 23 *x^22 + 33 *x^21 + 21 *x^20 + 37 *x^19 + 30 *x^18 + 19 *x^17 + 37 *x^16 + 8 *x^15 + 34 *x^14 + 25 *x^13 + 29 *x^12 + 29 *x^11 + 8 *x^10 + 19 *x^9 + 40 *x^8 + 35 *x^7 + 18 *x^6 + 2 *x^5 + 32 *x^4 + 3 *x^3 + 11 *x^2 + 10 *x + 36 C = 20 *x^127 + 31 *x^126 + 21 *x^125 + 19 *x^124 + 30 *x^123 + 4 *x^122 + 32 *x^121 + 19 *x^120 + 24 *x^119 + 33 *x^118 + 40 *x^117 + 39 *x^116 + 3 *x^115 + 32 *x^113 + 24 *x^112 + 31 *x^111 + 15 *x^110 + 7 *x^109 + 25 *x^108 + 16 *x^107 + 13 *x^106 + 5 *x^105 + 11 *x^104 + 38 *x^103 + 38 *x^102 + 28 *x^101 + 33 *x^100 + 32 *x^99 + 24 *x^98 + 26 *x^97 + 36 *x^96 + 32 *x^95 + 38 *x^94 + 26 *x^93 + 28 *x^91 + 37 *x^90 + 35 *x^89 + 25 *x^88 + 14 *x^87 + 9 *x^86 + 33 *x^85 + 15 *x^84 + 18 *x^83 + 12 *x^82 + 34 *x^81 + 12 *x^80 + 35 *x^79 + 40 *x^78 + 9 *x^77 + 23 *x^76 + 23 *x^75 + 12 *x^74 + 7 *x^73 + 27 *x^72 + 7 *x^71 + 14 *x^69 + 40 *x^68 + 34 *x^66 + 39 *x^65 + 30 *x^64 + 23 *x^63 + 8 *x^62 + 28 *x^61 + 37 *x^60 + 34 *x^59 + 35 *x^58 + 33 *x^57 + 3 *x^56 + 28 *x^55 + 39 *x^54 + 13 *x^53 + 31 *x^52 + 7 *x^51 + 38 *x^49 + 40 *x^48 + 11 *x^47 + 30 *x^46 + 19 *x^45 + 38 *x^44 + 37 *x^43 + 21 *x^42 + 9 *x^41 + 8 *x^40 + 31 *x^39 + 22 *x^38 + 24 *x^37 + 8 *x^36 + 17 *x^35 + 16 *x^34 + 29 *x^33 + 32 *x^32 + 17 *x^31 + 39 *x^30 + 20 *x^29 + 4 *x^27 + 40 *x^26 + 6 *x^24 + 27 *x^23 + 25 *x^22 + 4 *x^21 + 5 *x^20 + 8 *x^19 + 28 *x^18 + 21 *x^17 + x^16 + 12 *x^15 + 19 *x^14 + 29 *x^13 + 2 *x^12 + 9 *x^11 + 34 *x^10 + 16 *x^9 + 12 *x^8 + 21 *x^7 + 8 *x^6 + 23 *x^5 + 37 *x^4 + 31 *x^3 + 25 *x^2 + 20 *x + 21 cipher=b'\xc9\xe2\xcdzo\xa1\xcc\xe1\x0e(\x98W\xd3\xb9\x85X\xa3!P\xab\x00\x1cR r\xb4\xb8\xed\x8f\x83\x15r' k2 = GF(q^n, name = 'b' , modulus = F1) b = k2.gen() core1 = 22 *b^126 + 37 *b^125 + 33 *b^124 + 23 *b^123 + 9 *b^122 + 12 *b^121 + 22 *b^120 + 7 *b^119 + 12 *b^118 + 23 *b^117 + 22 *b^116 + 16 *b^115 + 12 *b^114 + 6 *b^113 + 23 *b^112 + 9 *b^111 + 9 *b^110 + 23 *b^109 + 27 *b^108 + 38 *b^107 + 21 *b^106 + 38 *b^105 + 19 *b^103 + 12 *b^102 + 20 *b^101 + b^100 + 36 *b^99 + 15 *b^98 + 26 *b^97 + 14 *b^96 + 4 *b^95 + 39 *b^94 + 29 *b^93 + 13 *b^92 + 11 *b^91 + 24 *b^90 + 28 *b^89 + 40 *b^88 + 6 *b^87 + b^86 + 30 *b^85 + 33 *b^84 + 21 *b^83 + 38 *b^82 + 24 *b^81 + 3 *b^80 + 29 *b^79 + 32 *b^78 + 14 *b^77 + 28 *b^76 + 19 *b^75 + 21 *b^74 + 16 *b^73 + 32 *b^72 + 4 *b^71 + 24 *b^70 + 30 *b^69 + 18 *b^68 + 19 *b^67 + 16 *b^66 + 12 *b^65 + 24 *b^64 + 26 *b^63 + 10 *b^62 + 25 *b^61 + 15 *b^60 + 22 *b^59 + 35 *b^58 + 27 *b^57 + 35 *b^56 + 25 *b^55 + 3 *b^54 + 4 *b^53 + 27 *b^52 + 12 *b^51 + 20 *b^50 + 29 *b^49 + 29 *b^48 + 11 *b^47 + 34 *b^46 + 13 *b^45 + 5 *b^44 + 5 *b^43 + 26 *b^42 + 29 *b^41 + 15 *b^40 + 21 *b^39 + 24 *b^38 + 26 *b^37 + 2 *b^36 + 22 *b^35 + 40 *b^34 + 14 *b^33 + b^32 + 28 *b^31 + 28 *b^30 + 29 *b^29 + 31 *b^28 + 12 *b^27 + 10 *b^26 + 35 *b^25 + 5 *b^24 + 18 *b^23 + 23 *b^22 + 33 *b^21 + 21 *b^20 + 37 *b^19 + 30 *b^18 + 19 *b^17 + 37 *b^16 + 8 *b^15 + 34 *b^14 + 25 *b^13 + 29 *b^12 + 29 *b^11 + 8 *b^10 + 19 *b^9 + 40 *b^8 + 35 *b^7 + 18 *b^6 + 2 *b^5 + 32 *b^4 + 3 *b^3 + 11 *b^2 + 10 *b + 36 M1 = matrix([(core1**i).list () for i in range (n)]) m = (vector(GF(q), C.list ())*M1^(-1 )).list () m = [int (i) % 2 for i in m] key = int ('' .join(str (i) for i in m) , 2 ) aes = AES.new(long_to_bytes(key), mode=AES.MODE_ECB) flag = aes.decrypt(cipher) print (flag)
然而还是没有用到$F_2$,确实也没有想到要怎么才能用上。
revenge @peigong在NSSCTF上了一个revenge:
ZMJ4396]piff_revenge | NSSCTF
题目如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 from sage.rings.finite_rings.hom_finite_field import FiniteFieldHomomorphism_genericfrom Crypto.Util.number import *from Crypto.Cipher import AESfrom secret import flagimport randomdef pad (msg ): return msg + bytes ([16 - len (msg) % 16 ]) * (16 - len (msg) % 16 ) def generate_irreducible_polynomial (R, n ): while True : f = R.random_element(degree=n) while f.degree() != n: f = R.random_element(degree=n) if f.is_irreducible(): return f def get_phi (R, t, strj, stri ): t_str = str (t).split(f"{strj} |--> " )[1 ].replace(stri,"x" ) return R(t_str) q = 41 n = 128 F = GF(q) R = PolynomialRing(F,'x' ) x = R.gen() f = generate_irreducible_polynomial(R,n).monic() F1 = generate_irreducible_polynomial(R,n).monic() F2 = generate_irreducible_polynomial(R,n).monic() k1 = GF(q^n, name = 'a' , modulus = f) k2 = GF(q^n, name = 'b' , modulus = F1) k3 = GF(q^n, name = 'c' , modulus = F2) t1 = FiniteFieldHomomorphism_generic(Hom(k1, k2)) t2 = FiniteFieldHomomorphism_generic(Hom(k2, k3)) phi1 = get_phi(R, t1, "a" , "b" ) phi2 = get_phi(R, t2, "b" , "c" ) k1 = [random.choice([0 ,1 ]) for _ in range (128 )] r1 = [random.choice([0 ,1 ]) for _ in range (128 )] m1,r1 = R(k1),R(r1) k2 = [random.choice([0 ,1 ]) for _ in range (128 )] r2 = [random.choice([0 ,1 ]) for _ in range (128 )] m2,r2 = R(k2),R(r2) p = 2 C1 = (p*phi1(x)*r1(phi1(x)) + m1(phi1(x))) % F1(x) C2 = (p*phi2(x)*r2(phi2(x)) + m2(phi2(x))) % F2(x) key1 = int ('' .join(str (i) for i in k1) , 2 ) aes = AES.new(long_to_bytes(key1), mode=AES.MODE_ECB) cipher1 = aes.encrypt(pad(flag[:len (flag)//2 ])) key2 = int ('' .join(str (i) for i in k2) , 2 ) aes = AES.new(long_to_bytes(key2), mode=AES.MODE_ECB) cipher2 = aes.encrypt(pad(flag[len (flag)//2 :])) print ("F1 = {}" .format (F1))print ("φ1 = {}" .format (phi1))print ("φ2 = {}" .format (phi2))print ("C1={}" .format (C1))print ("C2={}" .format (C2))print ("cipher1={}" .format (cipher1))print ("cipher2={}" .format (cipher2))""" F1 = x^128 + 13*x^127 + 25*x^126 + 12*x^125 + 36*x^124 + x^123 + 40*x^122 + 33*x^121 + 29*x^120 + 13*x^119 + 24*x^117 + 36*x^116 + 14*x^114 + 14*x^113 + 14*x^112 + 14*x^111 + 39*x^110 + 32*x^109 + 29*x^108 + 13*x^107 + 14*x^106 + 36*x^105 + 11*x^104 + 38*x^103 + 11*x^102 + 13*x^101 + 22*x^100 + 31*x^99 + 17*x^98 + 16*x^97 + 18*x^96 + 8*x^95 + 6*x^94 + 17*x^93 + 40*x^92 + 17*x^91 + 38*x^90 + 5*x^89 + 16*x^88 + 33*x^87 + 17*x^86 + 4*x^85 + 14*x^84 + 34*x^83 + 17*x^82 + 22*x^81 + 18*x^80 + 12*x^79 + 9*x^78 + 9*x^77 + 20*x^76 + 2*x^75 + 38*x^74 + 12*x^73 + 39*x^72 + 36*x^71 + x^70 + 15*x^69 + 28*x^68 + 27*x^67 + x^66 + x^65 + 14*x^64 + 21*x^63 + 28*x^62 + 12*x^61 + 34*x^60 + 12*x^59 + 11*x^58 + 29*x^57 + 34*x^56 + 10*x^55 + 11*x^54 + 22*x^53 + 28*x^52 + 12*x^51 + 9*x^50 + 4*x^49 + 8*x^48 + 30*x^47 + 21*x^46 + 8*x^45 + 13*x^44 + 29*x^43 + 2*x^42 + 11*x^41 + 13*x^40 + 31*x^39 + 35*x^38 + 22*x^37 + 13*x^36 + 33*x^35 + 33*x^34 + 21*x^33 + 4*x^32 + 18*x^31 + x^30 + 12*x^29 + 34*x^28 + 29*x^27 + 37*x^26 + 14*x^24 + 26*x^23 + 31*x^22 + 38*x^21 + 5*x^20 + 21*x^19 + 23*x^18 + 40*x^17 + 37*x^16 + 12*x^15 + 26*x^14 + 39*x^13 + 12*x^12 + 17*x^11 + 21*x^10 + 18*x^9 + 9*x^8 + 39*x^7 + 35*x^6 + 2*x^5 + 15*x^4 + 38*x^3 + 6*x^2 + 36*x + 12 φ1 = 36*x^126 + 2*x^125 + 15*x^123 + 9*x^122 + 12*x^121 + 27*x^120 + 34*x^119 + 22*x^118 + 12*x^117 + 16*x^116 + 8*x^115 + 19*x^114 + 29*x^113 + x^112 + 11*x^111 + 18*x^110 + 21*x^109 + 19*x^108 + 13*x^107 + 21*x^106 + 38*x^105 + 21*x^104 + 3*x^103 + 15*x^102 + 26*x^101 + 28*x^100 + 36*x^99 + 29*x^98 + 22*x^97 + 15*x^96 + 14*x^95 + 13*x^94 + 25*x^93 + 10*x^92 + 28*x^91 + 10*x^90 + 36*x^89 + 31*x^88 + 9*x^87 + 7*x^86 + 18*x^85 + 23*x^84 + 27*x^83 + 20*x^82 + 3*x^81 + 20*x^80 + 20*x^79 + 22*x^78 + 20*x^76 + 15*x^75 + 18*x^74 + 4*x^73 + 35*x^72 + 28*x^71 + 39*x^70 + 28*x^69 + 30*x^68 + x^67 + 17*x^66 + 20*x^65 + 26*x^64 + 7*x^63 + 13*x^62 + 32*x^61 + 40*x^60 + 39*x^59 + 6*x^58 + 24*x^57 + 19*x^56 + 15*x^55 + 21*x^54 + 25*x^53 + 31*x^52 + 35*x^51 + 19*x^50 + 38*x^49 + 35*x^48 + 4*x^47 + 13*x^46 + 5*x^44 + 17*x^43 + 3*x^42 + 4*x^41 + 36*x^40 + 15*x^39 + 22*x^38 + 26*x^37 + 11*x^36 + 18*x^35 + 3*x^34 + x^33 + 31*x^32 + 18*x^31 + 37*x^30 + 29*x^29 + 30*x^28 + 36*x^27 + 9*x^26 + 26*x^25 + 31*x^24 + 10*x^23 + 40*x^22 + 31*x^21 + 30*x^20 + 10*x^19 + 5*x^18 + 5*x^17 + 36*x^16 + 12*x^15 + x^14 + x^13 + 8*x^12 + 3*x^11 + 14*x^10 + 4*x^9 + 17*x^8 + 33*x^7 + 28*x^6 + 20*x^5 + 24*x^4 + 19*x^3 + 38*x^2 + 38*x + 35 φ2 = 27*x^126 + 14*x^125 + 15*x^124 + 24*x^123 + 2*x^122 + 33*x^121 + 25*x^120 + 18*x^119 + 18*x^118 + 27*x^117 + 25*x^116 + 26*x^115 + 20*x^114 + 36*x^113 + 30*x^112 + 34*x^111 + 9*x^110 + 28*x^109 + 21*x^108 + 17*x^107 + 25*x^106 + 7*x^105 + 19*x^104 + 2*x^103 + 12*x^102 + 14*x^101 + 29*x^100 + x^99 + 2*x^98 + 29*x^97 + 17*x^96 + 6*x^95 + 38*x^94 + 20*x^93 + 7*x^92 + 7*x^91 + 13*x^90 + 28*x^89 + x^88 + 6*x^87 + 38*x^85 + 27*x^84 + 25*x^83 + 24*x^82 + 6*x^81 + 34*x^80 + 6*x^79 + 6*x^78 + 33*x^77 + x^76 + 11*x^75 + 20*x^74 + 28*x^73 + 8*x^72 + 29*x^71 + 38*x^70 + 18*x^69 + 9*x^68 + 34*x^67 + 3*x^66 + 26*x^65 + 21*x^64 + 25*x^63 + 12*x^62 + 35*x^61 + 15*x^60 + 40*x^59 + 36*x^58 + 5*x^57 + 30*x^56 + 25*x^55 + 19*x^54 + 39*x^53 + 18*x^52 + 35*x^51 + 11*x^50 + 22*x^49 + 28*x^48 + 13*x^47 + 40*x^46 + 27*x^45 + 31*x^44 + 19*x^43 + 15*x^42 + 8*x^41 + 36*x^40 + 12*x^39 + 30*x^38 + 23*x^37 + 2*x^36 + 17*x^35 + 11*x^34 + 37*x^33 + 31*x^32 + 7*x^31 + 11*x^30 + 32*x^29 + 22*x^28 + 13*x^27 + 22*x^26 + 33*x^25 + 25*x^24 + 5*x^23 + 26*x^22 + 5*x^21 + 37*x^20 + 35*x^19 + 14*x^18 + 18*x^16 + 29*x^15 + 16*x^14 + 25*x^13 + 19*x^12 + 25*x^11 + 35*x^10 + 15*x^9 + 15*x^8 + 6*x^7 + 29*x^6 + 33*x^5 + 10*x^4 + 20*x^3 + 11*x^2 + 24*x + 11 C1=5*x^127 + 21*x^126 + 38*x^125 + 30*x^124 + 23*x^123 + 36*x^122 + 35*x^121 + 2*x^120 + 26*x^119 + 32*x^118 + 3*x^117 + 26*x^116 + 13*x^115 + 11*x^114 + 17*x^113 + 3*x^112 + 35*x^111 + 23*x^110 + 36*x^109 + 28*x^108 + 20*x^107 + 28*x^106 + 22*x^105 + 2*x^104 + 40*x^103 + 8*x^102 + 9*x^101 + 8*x^100 + 10*x^99 + 6*x^98 + 36*x^97 + 13*x^96 + x^95 + 5*x^93 + 21*x^91 + 11*x^90 + 27*x^89 + 26*x^88 + 27*x^87 + 25*x^86 + 4*x^85 + 17*x^84 + 21*x^83 + 28*x^82 + 23*x^81 + 14*x^80 + 2*x^79 + 2*x^78 + 30*x^77 + 30*x^76 + 14*x^75 + 38*x^74 + 11*x^73 + 30*x^72 + 7*x^71 + 26*x^70 + 11*x^69 + 25*x^68 + 30*x^67 + 3*x^66 + 39*x^65 + 10*x^64 + 15*x^63 + 27*x^62 + 36*x^61 + 4*x^60 + 22*x^59 + 14*x^58 + 32*x^57 + 37*x^56 + 22*x^55 + 12*x^54 + 19*x^53 + 26*x^52 + 34*x^51 + 14*x^50 + 35*x^49 + 31*x^48 + 20*x^47 + 40*x^46 + 9*x^45 + 23*x^44 + 19*x^43 + 29*x^41 + 3*x^40 + 33*x^39 + 5*x^38 + 33*x^37 + 27*x^36 + 28*x^35 + 3*x^34 + 33*x^33 + 31*x^32 + x^31 + 19*x^30 + 22*x^29 + 23*x^28 + 27*x^27 + 40*x^26 + 22*x^25 + 40*x^24 + 14*x^23 + 16*x^22 + 32*x^21 + 12*x^20 + 29*x^19 + 34*x^18 + 7*x^17 + 33*x^16 + 14*x^15 + 17*x^14 + 4*x^13 + 9*x^12 + 9*x^11 + 27*x^10 + 28*x^9 + 20*x^8 + 36*x^7 + 16*x^6 + 9*x^5 + 40*x^4 + 10*x^3 + 32*x^2 + 16 C2=6*x^127 + 16*x^126 + 8*x^125 + 32*x^124 + x^123 + 16*x^122 + 19*x^121 + 35*x^120 + 5*x^119 + 15*x^118 + 4*x^117 + 13*x^116 + 26*x^115 + 24*x^114 + 2*x^113 + 32*x^112 + 4*x^111 + 2*x^110 + 25*x^109 + 14*x^108 + 19*x^107 + 14*x^106 + 37*x^105 + 36*x^104 + 16*x^103 + 7*x^102 + 37*x^101 + 24*x^100 + 9*x^99 + 20*x^98 + 29*x^97 + 8*x^96 + 32*x^95 + 39*x^94 + 36*x^93 + 32*x^92 + 30*x^91 + 32*x^90 + 34*x^89 + 7*x^88 + 15*x^87 + 13*x^86 + 40*x^85 + 15*x^84 + 12*x^83 + 22*x^82 + 37*x^81 + 33*x^80 + 20*x^79 + 31*x^78 + 9*x^77 + 21*x^76 + 27*x^74 + 7*x^73 + 29*x^72 + 18*x^71 + 40*x^70 + 10*x^69 + 33*x^68 + 4*x^67 + 9*x^66 + 28*x^65 + 24*x^64 + 29*x^63 + 37*x^62 + 2*x^61 + 23*x^60 + 29*x^59 + 35*x^58 + 10*x^57 + 13*x^56 + 10*x^55 + 30*x^54 + 8*x^53 + 21*x^52 + 6*x^51 + 26*x^50 + 6*x^49 + 27*x^48 + 33*x^47 + 34*x^46 + 40*x^45 + 39*x^44 + 32*x^43 + 32*x^42 + 33*x^41 + 20*x^40 + 17*x^39 + 39*x^38 + 5*x^37 + 18*x^36 + 35*x^35 + 5*x^34 + 40*x^33 + 15*x^32 + 39*x^31 + 2*x^30 + 20*x^29 + 12*x^28 + 23*x^27 + 36*x^26 + 3*x^25 + 33*x^24 + 39*x^23 + 25*x^22 + 32*x^21 + 39*x^20 + 18*x^19 + 4*x^17 + 31*x^16 + 9*x^15 + 26*x^14 + 12*x^13 + 10*x^12 + 7*x^11 + 2*x^10 + 8*x^9 + 37*x^8 + 17*x^7 + 2*x^6 + 36*x^5 + 4*x^4 + 34*x^3 + 10*x^2 + 18*x + 38 cipher1=b'\xddH\xa3\xad\r\x1c\xe0\x83\xf0\xbe:}\xd6\x01\xa8\xbb\x0e%#V\x94FT\xe6)\x82~y\xe9\x9d\x8e ' cipher2=b's\x15z2\x10t\x0c\x16E\x7fW\x99\x8c\xcf\xd5,D\xb8\x00>\xbe[s\xe5\xa8N\x81\xa6%tA#' """
主要改变的地方在于:
$\phi_2$变成了从$k_2$到$k_3$的同态
没有给出$F_2$
有两个分别用$\phi_1,\phi_2$计算的密文$C_1,C_2$
既然有两个密文,所以肯定要用上$F_2$和$\phi_2$了,而相比于上一个题目来说可以发现会多一个步骤,就是要求解出$F_2$才行。
强网杯那篇文章有提过,对于$k_2$中的多项式$t(x)$,计算$\phi_2(t(x))$的本质步骤是:
把$k_2$的模多项式,也就是$F_1$放在$F_2$下求根,得到core,这个core其实也就是$\phi_2(x)$
在$k_3$下计算$t(core)$,结果就是$\phi_2(t(x))$
所以在$k_3$中有:
这也就代表着:
所以我们分解$F_1(\phi_1(x))$,其中度为128且不可约的多项式就可能是$F_2(x)$,逐个解密即可。
exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 from sage.rings.finite_rings.hom_finite_field import FiniteFieldHomomorphism_genericfrom Crypto.Util.number import *from Crypto.Cipher import AESq = 41 n = 128 F = GF(q) R = PolynomialRing(F,'x' ) x = R.gen() F1 = x^128 + 13 *x^127 + 25 *x^126 + 12 *x^125 + 36 *x^124 + x^123 + 40 *x^122 + 33 *x^121 + 29 *x^120 + 13 *x^119 + 24 *x^117 + 36 *x^116 + 14 *x^114 + 14 *x^113 + 14 *x^112 + 14 *x^111 + 39 *x^110 + 32 *x^109 + 29 *x^108 + 13 *x^107 + 14 *x^106 + 36 *x^105 + 11 *x^104 + 38 *x^103 + 11 *x^102 + 13 *x^101 + 22 *x^100 + 31 *x^99 + 17 *x^98 + 16 *x^97 + 18 *x^96 + 8 *x^95 + 6 *x^94 + 17 *x^93 + 40 *x^92 + 17 *x^91 + 38 *x^90 + 5 *x^89 + 16 *x^88 + 33 *x^87 + 17 *x^86 + 4 *x^85 + 14 *x^84 + 34 *x^83 + 17 *x^82 + 22 *x^81 + 18 *x^80 + 12 *x^79 + 9 *x^78 + 9 *x^77 + 20 *x^76 + 2 *x^75 + 38 *x^74 + 12 *x^73 + 39 *x^72 + 36 *x^71 + x^70 + 15 *x^69 + 28 *x^68 + 27 *x^67 + x^66 + x^65 + 14 *x^64 + 21 *x^63 + 28 *x^62 + 12 *x^61 + 34 *x^60 + 12 *x^59 + 11 *x^58 + 29 *x^57 + 34 *x^56 + 10 *x^55 + 11 *x^54 + 22 *x^53 + 28 *x^52 + 12 *x^51 + 9 *x^50 + 4 *x^49 + 8 *x^48 + 30 *x^47 + 21 *x^46 + 8 *x^45 + 13 *x^44 + 29 *x^43 + 2 *x^42 + 11 *x^41 + 13 *x^40 + 31 *x^39 + 35 *x^38 + 22 *x^37 + 13 *x^36 + 33 *x^35 + 33 *x^34 + 21 *x^33 + 4 *x^32 + 18 *x^31 + x^30 + 12 *x^29 + 34 *x^28 + 29 *x^27 + 37 *x^26 + 14 *x^24 + 26 *x^23 + 31 *x^22 + 38 *x^21 + 5 *x^20 + 21 *x^19 + 23 *x^18 + 40 *x^17 + 37 *x^16 + 12 *x^15 + 26 *x^14 + 39 *x^13 + 12 *x^12 + 17 *x^11 + 21 *x^10 + 18 *x^9 + 9 *x^8 + 39 *x^7 + 35 *x^6 + 2 *x^5 + 15 *x^4 + 38 *x^3 + 6 *x^2 + 36 *x + 12 φ1 = 36 *x^126 + 2 *x^125 + 15 *x^123 + 9 *x^122 + 12 *x^121 + 27 *x^120 + 34 *x^119 + 22 *x^118 + 12 *x^117 + 16 *x^116 + 8 *x^115 + 19 *x^114 + 29 *x^113 + x^112 + 11 *x^111 + 18 *x^110 + 21 *x^109 + 19 *x^108 + 13 *x^107 + 21 *x^106 + 38 *x^105 + 21 *x^104 + 3 *x^103 + 15 *x^102 + 26 *x^101 + 28 *x^100 + 36 *x^99 + 29 *x^98 + 22 *x^97 + 15 *x^96 + 14 *x^95 + 13 *x^94 + 25 *x^93 + 10 *x^92 + 28 *x^91 + 10 *x^90 + 36 *x^89 + 31 *x^88 + 9 *x^87 + 7 *x^86 + 18 *x^85 + 23 *x^84 + 27 *x^83 + 20 *x^82 + 3 *x^81 + 20 *x^80 + 20 *x^79 + 22 *x^78 + 20 *x^76 + 15 *x^75 + 18 *x^74 + 4 *x^73 + 35 *x^72 + 28 *x^71 + 39 *x^70 + 28 *x^69 + 30 *x^68 + x^67 + 17 *x^66 + 20 *x^65 + 26 *x^64 + 7 *x^63 + 13 *x^62 + 32 *x^61 + 40 *x^60 + 39 *x^59 + 6 *x^58 + 24 *x^57 + 19 *x^56 + 15 *x^55 + 21 *x^54 + 25 *x^53 + 31 *x^52 + 35 *x^51 + 19 *x^50 + 38 *x^49 + 35 *x^48 + 4 *x^47 + 13 *x^46 + 5 *x^44 + 17 *x^43 + 3 *x^42 + 4 *x^41 + 36 *x^40 + 15 *x^39 + 22 *x^38 + 26 *x^37 + 11 *x^36 + 18 *x^35 + 3 *x^34 + x^33 + 31 *x^32 + 18 *x^31 + 37 *x^30 + 29 *x^29 + 30 *x^28 + 36 *x^27 + 9 *x^26 + 26 *x^25 + 31 *x^24 + 10 *x^23 + 40 *x^22 + 31 *x^21 + 30 *x^20 + 10 *x^19 + 5 *x^18 + 5 *x^17 + 36 *x^16 + 12 *x^15 + x^14 + x^13 + 8 *x^12 + 3 *x^11 + 14 *x^10 + 4 *x^9 + 17 *x^8 + 33 *x^7 + 28 *x^6 + 20 *x^5 + 24 *x^4 + 19 *x^3 + 38 *x^2 + 38 *x + 35 φ2 = 27 *x^126 + 14 *x^125 + 15 *x^124 + 24 *x^123 + 2 *x^122 + 33 *x^121 + 25 *x^120 + 18 *x^119 + 18 *x^118 + 27 *x^117 + 25 *x^116 + 26 *x^115 + 20 *x^114 + 36 *x^113 + 30 *x^112 + 34 *x^111 + 9 *x^110 + 28 *x^109 + 21 *x^108 + 17 *x^107 + 25 *x^106 + 7 *x^105 + 19 *x^104 + 2 *x^103 + 12 *x^102 + 14 *x^101 + 29 *x^100 + x^99 + 2 *x^98 + 29 *x^97 + 17 *x^96 + 6 *x^95 + 38 *x^94 + 20 *x^93 + 7 *x^92 + 7 *x^91 + 13 *x^90 + 28 *x^89 + x^88 + 6 *x^87 + 38 *x^85 + 27 *x^84 + 25 *x^83 + 24 *x^82 + 6 *x^81 + 34 *x^80 + 6 *x^79 + 6 *x^78 + 33 *x^77 + x^76 + 11 *x^75 + 20 *x^74 + 28 *x^73 + 8 *x^72 + 29 *x^71 + 38 *x^70 + 18 *x^69 + 9 *x^68 + 34 *x^67 + 3 *x^66 + 26 *x^65 + 21 *x^64 + 25 *x^63 + 12 *x^62 + 35 *x^61 + 15 *x^60 + 40 *x^59 + 36 *x^58 + 5 *x^57 + 30 *x^56 + 25 *x^55 + 19 *x^54 + 39 *x^53 + 18 *x^52 + 35 *x^51 + 11 *x^50 + 22 *x^49 + 28 *x^48 + 13 *x^47 + 40 *x^46 + 27 *x^45 + 31 *x^44 + 19 *x^43 + 15 *x^42 + 8 *x^41 + 36 *x^40 + 12 *x^39 + 30 *x^38 + 23 *x^37 + 2 *x^36 + 17 *x^35 + 11 *x^34 + 37 *x^33 + 31 *x^32 + 7 *x^31 + 11 *x^30 + 32 *x^29 + 22 *x^28 + 13 *x^27 + 22 *x^26 + 33 *x^25 + 25 *x^24 + 5 *x^23 + 26 *x^22 + 5 *x^21 + 37 *x^20 + 35 *x^19 + 14 *x^18 + 18 *x^16 + 29 *x^15 + 16 *x^14 + 25 *x^13 + 19 *x^12 + 25 *x^11 + 35 *x^10 + 15 *x^9 + 15 *x^8 + 6 *x^7 + 29 *x^6 + 33 *x^5 + 10 *x^4 + 20 *x^3 + 11 *x^2 + 24 *x + 11 C1=5 *x^127 + 21 *x^126 + 38 *x^125 + 30 *x^124 + 23 *x^123 + 36 *x^122 + 35 *x^121 + 2 *x^120 + 26 *x^119 + 32 *x^118 + 3 *x^117 + 26 *x^116 + 13 *x^115 + 11 *x^114 + 17 *x^113 + 3 *x^112 + 35 *x^111 + 23 *x^110 + 36 *x^109 + 28 *x^108 + 20 *x^107 + 28 *x^106 + 22 *x^105 + 2 *x^104 + 40 *x^103 + 8 *x^102 + 9 *x^101 + 8 *x^100 + 10 *x^99 + 6 *x^98 + 36 *x^97 + 13 *x^96 + x^95 + 5 *x^93 + 21 *x^91 + 11 *x^90 + 27 *x^89 + 26 *x^88 + 27 *x^87 + 25 *x^86 + 4 *x^85 + 17 *x^84 + 21 *x^83 + 28 *x^82 + 23 *x^81 + 14 *x^80 + 2 *x^79 + 2 *x^78 + 30 *x^77 + 30 *x^76 + 14 *x^75 + 38 *x^74 + 11 *x^73 + 30 *x^72 + 7 *x^71 + 26 *x^70 + 11 *x^69 + 25 *x^68 + 30 *x^67 + 3 *x^66 + 39 *x^65 + 10 *x^64 + 15 *x^63 + 27 *x^62 + 36 *x^61 + 4 *x^60 + 22 *x^59 + 14 *x^58 + 32 *x^57 + 37 *x^56 + 22 *x^55 + 12 *x^54 + 19 *x^53 + 26 *x^52 + 34 *x^51 + 14 *x^50 + 35 *x^49 + 31 *x^48 + 20 *x^47 + 40 *x^46 + 9 *x^45 + 23 *x^44 + 19 *x^43 + 29 *x^41 + 3 *x^40 + 33 *x^39 + 5 *x^38 + 33 *x^37 + 27 *x^36 + 28 *x^35 + 3 *x^34 + 33 *x^33 + 31 *x^32 + x^31 + 19 *x^30 + 22 *x^29 + 23 *x^28 + 27 *x^27 + 40 *x^26 + 22 *x^25 + 40 *x^24 + 14 *x^23 + 16 *x^22 + 32 *x^21 + 12 *x^20 + 29 *x^19 + 34 *x^18 + 7 *x^17 + 33 *x^16 + 14 *x^15 + 17 *x^14 + 4 *x^13 + 9 *x^12 + 9 *x^11 + 27 *x^10 + 28 *x^9 + 20 *x^8 + 36 *x^7 + 16 *x^6 + 9 *x^5 + 40 *x^4 + 10 *x^3 + 32 *x^2 + 16 C2=6 *x^127 + 16 *x^126 + 8 *x^125 + 32 *x^124 + x^123 + 16 *x^122 + 19 *x^121 + 35 *x^120 + 5 *x^119 + 15 *x^118 + 4 *x^117 + 13 *x^116 + 26 *x^115 + 24 *x^114 + 2 *x^113 + 32 *x^112 + 4 *x^111 + 2 *x^110 + 25 *x^109 + 14 *x^108 + 19 *x^107 + 14 *x^106 + 37 *x^105 + 36 *x^104 + 16 *x^103 + 7 *x^102 + 37 *x^101 + 24 *x^100 + 9 *x^99 + 20 *x^98 + 29 *x^97 + 8 *x^96 + 32 *x^95 + 39 *x^94 + 36 *x^93 + 32 *x^92 + 30 *x^91 + 32 *x^90 + 34 *x^89 + 7 *x^88 + 15 *x^87 + 13 *x^86 + 40 *x^85 + 15 *x^84 + 12 *x^83 + 22 *x^82 + 37 *x^81 + 33 *x^80 + 20 *x^79 + 31 *x^78 + 9 *x^77 + 21 *x^76 + 27 *x^74 + 7 *x^73 + 29 *x^72 + 18 *x^71 + 40 *x^70 + 10 *x^69 + 33 *x^68 + 4 *x^67 + 9 *x^66 + 28 *x^65 + 24 *x^64 + 29 *x^63 + 37 *x^62 + 2 *x^61 + 23 *x^60 + 29 *x^59 + 35 *x^58 + 10 *x^57 + 13 *x^56 + 10 *x^55 + 30 *x^54 + 8 *x^53 + 21 *x^52 + 6 *x^51 + 26 *x^50 + 6 *x^49 + 27 *x^48 + 33 *x^47 + 34 *x^46 + 40 *x^45 + 39 *x^44 + 32 *x^43 + 32 *x^42 + 33 *x^41 + 20 *x^40 + 17 *x^39 + 39 *x^38 + 5 *x^37 + 18 *x^36 + 35 *x^35 + 5 *x^34 + 40 *x^33 + 15 *x^32 + 39 *x^31 + 2 *x^30 + 20 *x^29 + 12 *x^28 + 23 *x^27 + 36 *x^26 + 3 *x^25 + 33 *x^24 + 39 *x^23 + 25 *x^22 + 32 *x^21 + 39 *x^20 + 18 *x^19 + 4 *x^17 + 31 *x^16 + 9 *x^15 + 26 *x^14 + 12 *x^13 + 10 *x^12 + 7 *x^11 + 2 *x^10 + 8 *x^9 + 37 *x^8 + 17 *x^7 + 2 *x^6 + 36 *x^5 + 4 *x^4 + 34 *x^3 + 10 *x^2 + 18 *x + 38 cipher1=b'\xddH\xa3\xad\r\x1c\xe0\x83\xf0\xbe:}\xd6\x01\xa8\xbb\x0e%#V\x94FT\xe6)\x82~y\xe9\x9d\x8e ' cipher2=b's\x15z2\x10t\x0c\x16E\x7fW\x99\x8c\xcf\xd5,D\xb8\x00>\xbe[s\xe5\xa8N\x81\xa6%tA#' k2 = GF(q^n, name = 'b' , modulus = F1) b = k2.gen() core1 = 36 *b^126 + 2 *b^125 + 15 *b^123 + 9 *b^122 + 12 *b^121 + 27 *b^120 + 34 *b^119 + 22 *b^118 + 12 *b^117 + 16 *b^116 + 8 *b^115 + 19 *b^114 + 29 *b^113 + b^112 + 11 *b^111 + 18 *b^110 + 21 *b^109 + 19 *b^108 + 13 *b^107 + 21 *b^106 + 38 *b^105 + 21 *b^104 + 3 *b^103 + 15 *b^102 + 26 *b^101 + 28 *b^100 + 36 *b^99 + 29 *b^98 + 22 *b^97 + 15 *b^96 + 14 *b^95 + 13 *b^94 + 25 *b^93 + 10 *b^92 + 28 *b^91 + 10 *b^90 + 36 *b^89 + 31 *b^88 + 9 *b^87 + 7 *b^86 + 18 *b^85 + 23 *b^84 + 27 *b^83 + 20 *b^82 + 3 *b^81 + 20 *b^80 + 20 *b^79 + 22 *b^78 + 20 *b^76 + 15 *b^75 + 18 *b^74 + 4 *b^73 + 35 *b^72 + 28 *b^71 + 39 *b^70 + 28 *b^69 + 30 *b^68 + b^67 + 17 *b^66 + 20 *b^65 + 26 *b^64 + 7 *b^63 + 13 *b^62 + 32 *b^61 + 40 *b^60 + 39 *b^59 + 6 *b^58 + 24 *b^57 + 19 *b^56 + 15 *b^55 + 21 *b^54 + 25 *b^53 + 31 *b^52 + 35 *b^51 + 19 *b^50 + 38 *b^49 + 35 *b^48 + 4 *b^47 + 13 *b^46 + 5 *b^44 + 17 *b^43 + 3 *b^42 + 4 *b^41 + 36 *b^40 + 15 *b^39 + 22 *b^38 + 26 *b^37 + 11 *b^36 + 18 *b^35 + 3 *b^34 + b^33 + 31 *b^32 + 18 *b^31 + 37 *b^30 + 29 *b^29 + 30 *b^28 + 36 *b^27 + 9 *b^26 + 26 *b^25 + 31 *b^24 + 10 *b^23 + 40 *b^22 + 31 *b^21 + 30 *b^20 + 10 *b^19 + 5 *b^18 + 5 *b^17 + 36 *b^16 + 12 *b^15 + b^14 + b^13 + 8 *b^12 + 3 *b^11 + 14 *b^10 + 4 *b^9 + 17 *b^8 + 33 *b^7 + 28 *b^6 + 20 *b^5 + 24 *b^4 + 19 *b^3 + 38 *b^2 + 38 *b + 35 M1 = matrix([(core1**i).list () for i in range (n)]) m1 = (vector(GF(q), C1.list ())*M1^(-1 )).list () m1 = [int (i) % 2 for i in m1] key1 = int ('' .join(str (i) for i in m1) , 2 ) aes1 = AES.new(long_to_bytes(key1), mode=AES.MODE_ECB) flag1 = aes1.decrypt(cipher1) print (flag1)temp = list (F1(φ2 ).factor()) for i in temp: if (i[0 ].degree() == 128 and i[0 ].is_irreducible()): F2 = i[0 ] k3 = GF(q^n, name = 'c' , modulus = F2) c = k3.gen() core2 = 27 *c^126 + 14 *c^125 + 15 *c^124 + 24 *c^123 + 2 *c^122 + 33 *c^121 + 25 *c^120 + 18 *c^119 + 18 *c^118 + 27 *c^117 + 25 *c^116 + 26 *c^115 + 20 *c^114 + 36 *c^113 + 30 *c^112 + 34 *c^111 + 9 *c^110 + 28 *c^109 + 21 *c^108 + 17 *c^107 + 25 *c^106 + 7 *c^105 + 19 *c^104 + 2 *c^103 + 12 *c^102 + 14 *c^101 + 29 *c^100 + c^99 + 2 *c^98 + 29 *c^97 + 17 *c^96 + 6 *c^95 + 38 *c^94 + 20 *c^93 + 7 *c^92 + 7 *c^91 + 13 *c^90 + 28 *c^89 + c^88 + 6 *c^87 + 38 *c^85 + 27 *c^84 + 25 *c^83 + 24 *c^82 + 6 *c^81 + 34 *c^80 + 6 *c^79 + 6 *c^78 + 33 *c^77 + c^76 + 11 *c^75 + 20 *c^74 + 28 *c^73 + 8 *c^72 + 29 *c^71 + 38 *c^70 + 18 *c^69 + 9 *c^68 + 34 *c^67 + 3 *c^66 + 26 *c^65 + 21 *c^64 + 25 *c^63 + 12 *c^62 + 35 *c^61 + 15 *c^60 + 40 *c^59 + 36 *c^58 + 5 *c^57 + 30 *c^56 + 25 *c^55 + 19 *c^54 + 39 *c^53 + 18 *c^52 + 35 *c^51 + 11 *c^50 + 22 *c^49 + 28 *c^48 + 13 *c^47 + 40 *c^46 + 27 *c^45 + 31 *c^44 + 19 *c^43 + 15 *c^42 + 8 *c^41 + 36 *c^40 + 12 *c^39 + 30 *c^38 + 23 *c^37 + 2 *c^36 + 17 *c^35 + 11 *c^34 + 37 *c^33 + 31 *c^32 + 7 *c^31 + 11 *c^30 + 32 *c^29 + 22 *c^28 + 13 *c^27 + 22 *c^26 + 33 *c^25 + 25 *c^24 + 5 *c^23 + 26 *c^22 + 5 *c^21 + 37 *c^20 + 35 *c^19 + 14 *c^18 + 18 *c^16 + 29 *c^15 + 16 *c^14 + 25 *c^13 + 19 *c^12 + 25 *c^11 + 35 *c^10 + 15 *c^9 + 15 *c^8 + 6 *c^7 + 29 *c^6 + 33 *c^5 + 10 *c^4 + 20 *c^3 + 11 *c^2 + 24 *c + 11 M2 = matrix([(core2**i).list () for i in range (n)]) m2 = (vector(GF(q), C2.list ())*M2^(-1 )).list () m2 = [int (i) % 2 for i in m2] key2 = int ('' .join(str (i) for i in m2) , 2 ) aes2 = AES.new(long_to_bytes(key2), mode=AES.MODE_ECB) flag2 = aes2.decrypt(cipher2) print (flag2)