def keygen(nbits): a = [randint(2**160, 2**200)] for x in range(nbits-1): a.append(randint(2*a[-1], 3*a[-1])) p = getPrime(1024) w = getPrime(30) b = [i*w % p for i in a] sk = [w] pk = [b,p] return sk,pk
w乘以a充其量是2的230次方,不可能超过p,因此b仍然是超递增序列,于是用贪心算法破解
1 2 3 4 5 6 7 8 9 10 11 12 13
defdecrypt_attack(pk,c): b,p = pk m = '' for i inrange(len(b)-1,-1,-1): if c >= b[i]: #大于说明背包里有,为1 c-= b[i] m = "1" + m else: #背包里没有 m = "0" + m m = int(m,2) return long_to_bytes(m) m = decrypt_attack(pk,c) print(m)
注:这道题里,被加密的是m的二进制位,即将m转为01序列,和前面的x对应
且本题的w是可以求出来的,求出w还原a,再用贪心算法也可以
exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
from functools import reduce from Crypto.Util.number import * b,p = pk w = reduce(GCD,b) a = [ bi*inverse(w,p) % p for bi in b] m = '' c = c*inverse(w,p) % p for i in range(len(a)-1,-1,-1): if c >= a[i]: c-= a[i] m = "1" + m else: m = "0" + m m = int(m,2) print(long_to_bytes(m))
5.ez_bag_revenge
1 2 3 4 5 6
defencrypt(m,bags,module) -> int: m = bin(m)[2:].rjust(624, "0") res = 0 for i inrange(len(m)): res += bags[i] * int(m[i]) return res % module
from Crypto.Util.number import * from pwn import * from tqdm import * from functools import * p = remote("10.102.32.141",40286) p.recvuntil(b"Input > ") m = [i for i in range(100)] p.send(str(2**624-1).encode()) p.recvuntil(b"= ") cij = int(p.recvline().strip().decode()) kq = [] for i in trange(len(m)): p.send(str(i).encode()) p.recvuntil(b"= ") ci = int(p.recvline().strip().decode()) p.send(str(2**624-1-i).encode()) p.recvuntil(b"= ") cj = int(p.recvline().strip().decode()) if ci+cj-cij != 0: kq.append(ci+cj-cij) mod = reduce(GCD,kq) print(mod) p.interactive()