其中 μi 是 B 的特征值。
可以随便取一组数据运算
2. 如果矩阵不可对角化:
- Jordan 标准形(用的不多)
- 更常见但更局限:行列式降维打击
利用:
det(Ak)=det(A)k
于是:
det(B)=det(A)k
问题瞬间降级为:
k=logdet(A)(det(B))
模 p2 下展开 (I+pX)k
case:
实际问题
unictf
1 2 3 4 5 6 7 8
from Crypto.Util.number import *
flag = b'UniCTF{???}' m = bytes_to_long(flag) n = 20416580311348568104958456290409800602076453150746674606637172527592736894552749500299570715851384304673805100612931000268540860237227126141075427447627491168 print(pow(7,m,n)) # c = 8195229101228793312160531614487746122056220479081491148455134171051226604632289610379779462628287749120056961207013231802759766535835599450864667728106141697
分析
问题就要是解方程
c≡7m(modn)
直接 discrete_log 肯定不行, n 不是一个素数,而是一个大合数
结合同余的性质,可以考虑分解因子n,拆分同余方程后再使用中国剩余定理求解
1.
from sage.allimport * from Crypto.Util.number import long_to_bytes
# ================= 题目数据 ================= n = 20416580311348568104958456290409800602076453150746674606637172527592736894552749500299570715851384304673805100612931000268540860237227126141075427447627491168 c = 8195229101228793312160531614487746122056220479081491148455134171051226604632289610379779462628287749120056961207013231802759766535835599450864667728106141697
from Crypto.Util.number import long_to_bytes, getPrime from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad from base64 import b64encode import hashlib from sage.allimport * from secret import getRandomMatrix
withopen('flag.txt', 'rb') as f: flag = pad(f.read(), AES.block_size)
# Want to factor n? I've already done it! Get it yourself. n = 144709507748526661267852152217031923282704243254105275252262414154410511284347828603240755427862752297392095652561239549522158121842455510674435510821274029842500154931546666242034086499872050823824437303603895977092291834159890433746969317535636398062008995784281741721729948231010601796589449187553147904043991226174291329 a = Matrix(Zmod(n), getRandomMatrix())
from sage.allimport * from Crypto.Cipher import AES from Crypto.Util.Padding import unpad from Crypto.Util.number import long_to_bytes import hashlib from base64 import b64decode
from Crypto.Util.number import long_to_bytes, getPrime from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad from base64 import b64encode import hashlib from sage.allimport * from secret import getRandomMatrix, get_random_prime
withopen('flag.txt', 'rb') as f: flag = pad(f.read(), AES.block_size)
p = get_random_prime() q = get_random_prime() n = p * p
from sage.allimport * import math import base64 import hashlib from Crypto.Cipher import AES from Crypto.Util.Padding import unpad from Crypto.Util.number import long_to_bytes import hashlib from base64 import b64decode
data = load('data.sobj') n = data[0] a = data[1] b = data[2]
p = math.isqrt(n) print(p) P = Zp(p, prec=2) f_A_high = a.charpoly().change_ring(ZZ).change_ring(P) f_B_high = b.charpoly().change_ring(ZZ).change_ring(P) la_high = f_A_high.roots(multiplicities=False)[0] mu_high = f_B_high.roots(multiplicities=False)[0] order = p - 1 k_=int(((mu_high**order).log() / (la_high**order).log()).lift())