Lattice
题面
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
| from random import randint
from gmpy2 import gcd, invert
from Crypto.Util.number import bytes_to_long, long_to_bytes
from flag import flag
def genKey(_n):
_privKey = [randint(1, pow(4, _n))]
s = _privKey[0]
for i in range(1, _n):
_privKey.append(randint(s + 1, pow(4, _n + i)))
s += _privKey[i]
_q = randint(_privKey[_n - 1] + 1, 2 * _privKey[_n - 1])
_r = randint(1, _q)
while gcd(_r, _q) != 1:
_r = randint(1, _q)
_pubKey = [_r * _ % _q for _ in _privKey]
return _privKey, _q, _r, _pubKey
def encrypt(_msg, _pubKey):
cipher = 0
cnt = 0
for bit in _msg:
cipher += int(bit) * _pubKey[cnt]
cnt += 1
return bin(cipher)[2:]
def decrypt(_c, _privKey, _q, _r):
s = invert(_r, _q)
_msg = int(_c, 2) * s % _q
res = ''
for i in range(len(_privKey) - 1, -1, -1):
if _msg >= _privKey[i]:
res = '1' + res
_msg -= _privKey[i]
else:
res = '0' + res
return res
bin_msg = bin(bytes_to_long(flag))[2:]
private_key, q, r, public_key = genKey(len(bin_msg))
enc = encrypt(bin_msg, public_key)
print(f'pubKey = {public_key}')
print(f'enc = {int(enc, 2)}')
|
一个背包格,应该…
Lattice入门题,打格子
(a0,a1,…,an−1,1)⎝⎜⎜⎜⎜⎛10⋮0010000…………key0key1⋮−enc⎠⎟⎟⎟⎟⎞=(a0,a1,…,an−1,0)
不用配系数直接打就ok
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
| pubKey = [...] enc = ...
k = 1
M = matrix(ZZ,len(pubKey)+1,len(pubKey)+1)
for i in range(len(pubKey)):
M[i,i] = 1
M[i,len(pubKey)] = pubKey[i] * k
M[len(pubKey),len(pubKey)] = -int(enc)
L = M.LLL()
for i in range(len(pubKey)+1):
line = L.row(i).list()
tag = 0
for i in line:
if i != 0 and i != 1:
tag = 1
break
if tag == 0:
res = ''.join(map(str, line[:-1]))
print(long_to_bytes(int(res,2)))
|