#!/usr/bin/env sage import os from hashlib import sha256 from Crypto.Cipher import AES from sage.crypto.lwe import LWE from sage.stats.distributions.discrete_gaussian_integer import DiscreteGaussianDistributionIntegerSampler as DGDIS
from secret import FLAG assert FLAG.startswith(b"X-NUCA{") and FLAG.endswith(b"}")
A = random_matrix(ZZ, 320, 5, x = 10, y = 1000) B = Matrix(A * vector([randint(1, 2^1024) for _ inrange(5)]) for _ inrange(7))
L = LWE(n = 25, q = 1000, D = DGDIS(3)) S = [L() for _ inrange(64)]
M = Matrix(64, 25, [int(i).__xor__(int(j)) for i,j inzip(A.list(), (Matrix([x for x, _ in S])).list())]) T = Matrix([randint(1, 2^1024) for _ inrange(64)]) R = T.transpose().stack(T * vector([y for _, y in S]).change_ring(ZZ))
if __name__ == "__main__": key = sha256(''.join(list(map(str, L._LWE__s))).encode()).digest() iv = os.urandom(16) cipher = AES.new(key, AES.MODE_CBC, iv) ct = cipher.encrypt(FLAG)
defBabaisClosestPlaneAlgorithm(L, w): ''' Yet another method to solve apprCVP, using a given good basis. INPUT: * "L" -- a matrix representing the LLL-reduced basis (v1, ..., vn) of a lattice. * "w" -- a target vector to approach to. OUTPUT: * "v" -- a approximate closest vector. Quoted from "An Introduction to Mathematical Cryptography": In both theory and practice, Babai's closest plane algorithm seems to yield better results than Babai's closest vertex algorithm. ''' G, _ = L.gram_schmidt() t = w i = L.nrows() - 1 while i >= 0: w -= round( (w*G[i]) / G[i].norm()^2 ) * L[i] i -= 1 return t - w
import numpy as np from sage.modules.free_module_integer import IntegerLattice
defBabaisClosestPlaneAlgorithm(L, w): ''' Yet another method to solve apprCVP, using a given good basis. INPUT: * "L" -- a matrix representing the LLL-reduced basis (v1, ..., vn) of a lattice. * "w" -- a target vector to approach to. OUTPUT: * "v" -- a approximate closest vector. Quoted from "An Introduction to Mathematical Cryptography": In both theory and practice, Babai's closest plane algorithm seems to yield better results than Babai's closest vertex algorithm. ''' G, _ = L.gram_schmidt() t = w i = L.nrows() - 1 while i >= 0: w -= round( (w*G[i]) / G[i].norm()^2 ) * L[i] i -= 1 return t - w row = 128 col = 42 p = 2129
M = Matrix(list(np.load('matrix.npy'))) R = vector(list(np.load('result.npy')))
A = [[0for _ inrange(row)] for _ inrange(row)] for i inrange(128): for j inrange(128): if i==j: A[i][j] = p A = Matrix(A) L = Matrix(A.stack(M.transpose())) lattice = IntegerLattice(L, lll_reduce=True) closest_vector = BabaisClosestPlaneAlgorithm(lattice.reduced_basis, R)
FLAG = Matrix(Zmod(p), M) flag = FLAG.solve_right(closest_vector) print(''.join( chr(i) for i in flag))
from sage.crypto.lwe import LWE from sage.stats.distributions.discrete_gaussian_integer \ import DiscreteGaussianDistributionIntegerSampler as DGDIS import uuid
FLAG = 'flag{' + str(uuid.uuid4()) + '}' FLAG = FLAG.encode().replace(b'-',b'')
assert FLAG.startswith(b'flag{') and FLAG.endswith(b'}') s = list(FLAG[5:-1])
n = len(s) q = random_prime(1<<512, proof=False, lbound=1<<511)
from sage.modules.free_module_integer import IntegerLattice defBabaisClosestPlaneAlgorithm(L, w): ''' Yet another method to solve apprCVP, using a given good basis. INPUT: * "L" -- a matrix representing the LLL-reduced basis (v1, ..., vn) of a lattice. * "w" -- a target vector to approach to. OUTPUT: * "v" -- a approximate closest vector. Quoted from "An Introduction to Mathematical Cryptography": In both theory and practice, Babai's closest plane algorithm seems to yield better results than Babai's closest vertex algorithm. ''' G, _ = L.gram_schmidt() t = w i = L.nrows() - 1 while i >= 0: w -= round( (w*G[i]) / G[i].norm()^2 ) * L[i] i -= 1 return t - w
q = 8934325385505568130914092337950620590424921674062792756625169144539462888362199042365894202712873706261308891694743761726859424971637596576879385466842113 L = [...] n = 32
Q = [[0for _ inrange(2*n)] for _ inrange(2*n)] R = [0for _ inrange(2*n)] LL = [[0for _ inrange(n)] for _ inrange(2*n)]
for i inrange(2*n): for j inrange(n): LL[i][j] = L[i][0][j] M = Matrix(LL).transpose()
for i inrange(2*n): for j inrange(2*n): if i == j: Q[i][j] = q
for i inrange(2*n): R[i] = L[i][1]
R = vector(R) L = Matrix(Q).stack(Matrix(M)) lattice = IntegerLattice(L, lll_reduce=True) closest_vector = BabaisClosestPlaneAlgorithm(lattice.reduced_basis, R)
FLAG = Matrix(Zmod(q), M.transpose()) flag = FLAG.solve_right(closest_vector) print(''.join( chr(i) for i in flag))
L = Matrix([[0for _ inrange(row+1)] for _ inrange(row+1)]) for i inrange(col): for j inrange(col): if i == j: L[i,j] = 1 for i inrange(row - col): for j inrange(row - col): if i == j: L[i+col,j+col] = p for i inrange(row-col): for j inrange(col): L[i+col,j] = A12[i,j] for i inrange(row): L[i,-1] = R[i] L[-1,-1] = 1
reduced = L.transpose().LLL() error = [] for i in reduced[0][:-1]: error.append(-i) e = vector(error) As = R - e A = Matrix(Zmod(p),M) for i in A.solve_right(As): print(chr(i),end='')