defGaussian_reduction(v1,v2): whileTrue: if mo(v2)<mo(v1): v1,v2=v2,v1 m=dot(v1,v2)//dot(v1,v1) if m == 0: return v1,v2 break v2=[v2[0]-m*v1[0],v2[1]-m*v1[1]]
defgen_pack(bound): a = [0] * bound a[0] = random.randint(0,10) c = 0 for i inrange(1,bound): c = c+a[i-1]+random.randint(10,20) a[i] = c return a
defgen_m(bound): return [1-random.randint(0,1) for _ inrange(bound) ]
defenc(pack,m): c = 0 for i inrange(len(pack)): c += pack[i]*m[i] return c
defattack(pack,c): c_=c m=[0]*len(pack) for i inrange(len(pack)-1,-1,-1): if pack[i] > c: m[i] = 0 else: m[i] = 1 c -= pack[i] print(enc(pack,m) == c_) return m
if __name__ == '__main__': b=8 pack,m = gen_pack(b),gen_m(b) c = enc(pack,m) m_=attack(pack,c) print(m_ == m)
Merkle-Hellman背包加密方案
Algorithm 2.2.1: Key Creation
Data:
Result: public key
Choose superincreasing
Choose and with and
Compute for
Publish public key , keep private
Algorithm 2.2.2: Encryption
Data: plaintext , public key
Result: ciphertext
Compute
Return S
Algorithm 2.2.3: Decryption
Data: ciphertext , secret key
: plaintext
Compute
Solve the subset-sum problem using the superincreasing sequence
import random from Crypto.Util.number import * import gmpy2 as gp
defgen(bound): r = [0] * bound r[0] = random.randint(0,10) c = 0 for i inrange(1,bound): c = c+r[i-1]+random.randint(10,20) r[i] = c b = getPrime(2*(len(bin(c))-2)) a=random.randint(1,b) m = [0]*bound for i inrange(bound): m[i] = a*r[i]%b return m,r,a,b defenc(bound,m,b): x = [1-random.randint(0,1) for _ inrange(bound) ] s = 0 for i inrange(bound): s += x[i]*m[i]%b return x,s
defattack(pack,c): c_=c m=[0]*len(pack) for i inrange(len(pack)-1,-1,-1): if pack[i] > c: m[i] = 0 else: m[i] = 1 c -= pack[i] return m
defdec(s,r,a,b): s_ = gp.invert(a,b)*s%b x = attack(r,s_) return x
defT(d1, d2): assert N >= d1+d2 s = [1]*d1 + [-1]*d2 + [0]*(N-d1-d2) shuffle(s) return R(s)
definvertModPrime(f, p): Rp = R.change_ring(Integers(p)).quotient(x^N-1) return R(lift(1 / Rp(f)))
defconvolution(f, g): return (f*g) % (x^N-1)
defliftMod(f, q): g = list(((f[i] + q//2) % q) - q//2for i inrange(N)) return R(g)
defpolyMod(f, q): g = [f[i]%q for i inrange(N)] return R(g)
definvertModPow2(f, q): assert q.is_power_of(2) g = invertModPrime(f,2) whileTrue: r = liftMod(convolution(g,f),q) if r == 1: return g g = liftMod(convolution(g,2 - r),q)
defgenMessage(): result = list(randrange(p) - 1for j inrange(N)) return R(result)