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
| from itertools import product
import hashlib from Crypto.Cipher import AES from Crypto.Util.Padding import unpad from sage.all import GF, Matrix, PolynomialRing, vector
def solve(prime, outputs, ciphertext_hex): field = GF(prime) roots = [] for output in outputs: value = field(output) roots.append([value.sqrt(), -value.sqrt()] if value else [field(0)])
matrix = Matrix(field, [[0, 5], [11, 0]]) offset = vector(field, [7, 13]) identity = Matrix.identity(field, 2) step_matrix = matrix ** 10 step_offset = sum(matrix ** i for i in range(10)) * offset
coefficients = [] transform = identity translation = vector(field, [0, 0]) for _ in outputs: coefficients.append(( transform[0, 0], transform[0, 1], transform[1, 0], transform[1, 1], translation[0], translation[1], )) translation = translation + transform * step_offset transform = transform * step_matrix
ring = PolynomialRing(field, names=("x", "y")) x, y = ring.gens()
for signs in product(*roots): equations = [] for index in range(2): a, b, c, d, e, f = coefficients[index] equations.append( (a * x + b * y + e) * (c * x + d * y + f) - signs[index] )
basis = ring.ideal(equations).groebner_basis() for polynomial in basis: if len(polynomial.variables()) != 1: continue for root, _ in polynomial.univariate_polynomial().roots(): candidate_x, candidate_y = recover_other_variable( basis, polynomial, root ) if verify(candidate_x, candidate_y, coefficients, signs): key = hashlib.sha256( f"{candidate_x}{candidate_y}".encode() ).digest()[:16] plaintext = AES.new( key, AES.MODE_ECB ).decrypt(bytes.fromhex(ciphertext_hex)) return unpad(plaintext, 16).decode()
return None
|
💬 评论与讨论
分享你的想法和见解