You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
62 lines
1.5 KiB
Python
62 lines
1.5 KiB
Python
#break cryptosystem if know a half of private key
|
|
|
|
import numpy as np
|
|
import galois
|
|
|
|
import pubkey
|
|
import privkey
|
|
import message
|
|
|
|
n = 127
|
|
k = 32
|
|
order = 2 ** 7
|
|
GF = galois.GF(order)
|
|
|
|
def main():
|
|
G_ = GF(pubkey.get()) #we need to know a public matrix
|
|
P = GF(privkey.get_P()) #and P - only one of two private matrices
|
|
S = break_S(P, G_) #to calculate S - the second part of private key
|
|
c = GF(message.get())
|
|
print(decode(S, P, c)) #and decode the message
|
|
|
|
def unpad_message(msg):
|
|
padding_byte = msg[-1]
|
|
for i in range(1, padding_byte + 1):
|
|
if msg[-i] != padding_byte:
|
|
raise ValueError("Incorrect padding!")
|
|
return msg[:-padding_byte]
|
|
|
|
def my_fix(A):
|
|
#make square matrix by deleting right columns
|
|
l = len(A)
|
|
r = GF.Zeros((l, l))
|
|
for i in range(l):
|
|
for j in range(l):
|
|
r[i][j] = A[i][j]
|
|
return r
|
|
|
|
def decode(S, P, c):
|
|
rs = galois.ReedSolomon(n, k, field=GF)
|
|
c = c @ np.linalg.inv(P)
|
|
c = rs.decode(c)
|
|
c = c @ np.linalg.inv(S)
|
|
c = [int(i) for i in c]
|
|
c = unpad_message(c)
|
|
c = bytes(c)
|
|
c = c.decode()
|
|
return c
|
|
|
|
def break_S(P, G_):
|
|
return my_fix(G_ @ np.linalg.inv(P)) #works for Reed-Solomon
|
|
#G_ = S @ G @ P
|
|
rs = galois.ReedSolomon(n, k, field=GF)
|
|
G = rs.G
|
|
G_ = G_ @ np.linalg.inv(P)
|
|
G_ = my_fix(G_)
|
|
G = my_fix(G) #returns E because we use Reed-Solomon algo
|
|
S = G_ @ np.linalg.inv(G)
|
|
return S
|
|
|
|
if __name__ == "__main__":
|
|
main()
|