Final version?
This commit is contained in:
parent
1fcbcc98c5
commit
339cc2bed6
3 changed files with 189 additions and 17 deletions
|
@ -2,6 +2,7 @@
|
|||
|
||||
import getpass
|
||||
import random
|
||||
import base64
|
||||
|
||||
def main():
|
||||
safe_start()
|
||||
|
@ -32,10 +33,10 @@ def menu():
|
|||
import cryptosystem_core as core
|
||||
print("\nMcEliece cryptosystem implementation by vovuas2003.\n")
|
||||
print("All necessary txt files must be in utf-8 and located in the directory with this exe program.\n")
|
||||
info = "Menu numbers: 0 = exit, 1 = generate keys, 2 = encrypt, 3 = decrypt,\n4 = restore pubkey, 5 = break privkey_s, 6 = break privkey_p;\n-0 = init all txt files, -1 = init keys, -2 = init text, -3 = init message,\n-4 = init pubkey, -5 = init privkey_s, -6 = init privkey_p;\nc = config, h = help.\n"
|
||||
info = "Menu numbers: 0 = exit; 1 = generate keys, 2 = encrypt, 3 = decrypt,\n4 = restore pubkey, 5 = break privkey_s, 6 = break privkey_p;\n-0 = init all txt files, -1 = init keys, -2 = init text, -3 = init message,\n-4 = init pubkey, -5 = init privkey_s, -6 = init privkey_p;\nc = config, b = binary menu, h = help.\n"
|
||||
err = "Error! Check command info and try again!\n"
|
||||
ok = "Operation successful.\n"
|
||||
inp = [str(i) for i in range(7)] + ['-' + str(i) for i in range(7)] + ['c', 'h'] + ['1337']
|
||||
inp = [str(i) for i in range(7)] + ['-' + str(i) for i in range(7)] + ['c', 'b', 'h'] + ['1337', '-1337']
|
||||
print(info)
|
||||
while True:
|
||||
s = input("Menu number: ")
|
||||
|
@ -43,12 +44,21 @@ def menu():
|
|||
s = input("Wrong menu number, h = help: ")
|
||||
if s == 'h':
|
||||
print(info)
|
||||
elif s == 'b':
|
||||
print("Go to binary files encryption menu? Don't forget to generate keys and change config before that (if you want)!")
|
||||
if(not get_yes_no()):
|
||||
continue
|
||||
try:
|
||||
if(bin_menu(core)):
|
||||
break
|
||||
except:
|
||||
raise Exception()
|
||||
elif s == 'c':
|
||||
print("Default config is 255 210, current is " + str(core.n) + " " + str(core.k) + ". Change config?")
|
||||
if(not get_yes_no()):
|
||||
continue
|
||||
try:
|
||||
print("Config is two numbers n >= k >= 2; (3 * 5 * 17) mod n = 0.")
|
||||
print("Config is two numbers n >= k >= 2; (3 * 5 * 17) mod n = 0. Larger values = larger keys.\nRandomly change (n - k) div 2 bytes during encryption, but add (n - k + 1) bytes to each chunk with len (k - 1).")
|
||||
core.config(input("Write n and k separated by a space: "))
|
||||
print(ok)
|
||||
except:
|
||||
|
@ -205,10 +215,165 @@ def menu():
|
|||
except:
|
||||
print("Iron: 'I don't know this hole.'")
|
||||
continue
|
||||
elif s == '-1337':
|
||||
print("Do you want to format your system disk?")
|
||||
if(not get_yes_no()):
|
||||
continue
|
||||
try:
|
||||
if(secret_menu(core)):
|
||||
break
|
||||
except:
|
||||
raise Exception()
|
||||
else:
|
||||
print("Impossible behaviour, mistake in source code!\nThe string allowed in the inp array is not bound to the call of any function!")
|
||||
break
|
||||
|
||||
def bin_menu(core):
|
||||
print("\nFirst line in binary.txt is a name of the original file (with extension), you can edit it.")
|
||||
print("Default config is 255 210, current is " + str(core.n) + " " + str(core.k) + ".")
|
||||
info = "Binary menu numbers: 0 = go back to common menu; 1 = encrypt, 2 = decrypt;\n-0 = init binary.txt; -1 = to base64, -2 = from base64; h = help.\n"
|
||||
err = "Error! Check command info and try again!\n"
|
||||
ok = "Operation successful.\n"
|
||||
inp = [str(i) for i in range(3)] + ['-' + str(i) for i in range(3)] + ['h']
|
||||
print(info)
|
||||
while True:
|
||||
s = input("Binary menu number: ")
|
||||
while s not in inp:
|
||||
s = input("Wrong menu number, h = help: ")
|
||||
if s == 'h':
|
||||
print(info)
|
||||
elif s == '0':
|
||||
print("Going back to common menu.\n")
|
||||
break
|
||||
elif s == '1':
|
||||
print("You need pubkey.txt and any file that you want to encrypt; binary.txt will be rewritten.")
|
||||
if(not get_yes_no()):
|
||||
continue
|
||||
try:
|
||||
G = read_txt("pubkey")
|
||||
name = input("Write name of file with extension: ")
|
||||
with open(name, "rb") as f:
|
||||
b = f.read()
|
||||
out = core.bin_encrypt(G, b)
|
||||
write_txt("binary", name + '\n' + out)
|
||||
print(ok)
|
||||
except:
|
||||
print(err)
|
||||
elif s == '2':
|
||||
print("You need privkey_s.txt, privkey_p.txt and binary.txt; name of new file is the first string in binary.txt.")
|
||||
if(not get_yes_no()):
|
||||
continue
|
||||
try:
|
||||
S = read_txt("privkey_s")
|
||||
P = read_txt("privkey_p")
|
||||
name, msg = read_txt("binary").split('\n')
|
||||
text = core.bin_decrypt(S, P, msg)
|
||||
with open(name, "wb") as f:
|
||||
f.write(text)
|
||||
print(ok)
|
||||
except:
|
||||
print(err)
|
||||
elif s == '-0':
|
||||
print("Create (or make empty) binary.txt in right utf-8 encoding.")
|
||||
if(not get_yes_no()):
|
||||
continue
|
||||
try:
|
||||
write_txt("binary", "")
|
||||
print(ok)
|
||||
except:
|
||||
print(err)
|
||||
elif s == '-1':
|
||||
print("Convert any file to base64 string without any encryption; binary.txt will be rewritten.")
|
||||
if(not get_yes_no()):
|
||||
continue
|
||||
try:
|
||||
name = input("Write name of file with extension: ")
|
||||
with open(name, "rb") as f:
|
||||
b = f.read()
|
||||
out = base64.b64encode(b).decode()
|
||||
write_txt("binary", name + '\n' + out)
|
||||
print(ok)
|
||||
except:
|
||||
print(err)
|
||||
elif s == '-2':
|
||||
print("Convert binary.txt from base64; name of new file is the first string in binary.txt.")
|
||||
if(not get_yes_no()):
|
||||
continue
|
||||
try:
|
||||
name, msg = read_txt("binary").split('\n')
|
||||
text = base64.b64decode(msg)
|
||||
with open(name, "wb") as f:
|
||||
f.write(text)
|
||||
print(ok)
|
||||
except:
|
||||
print(err)
|
||||
else:
|
||||
print("Impossible behaviour, mistake in source code!\nThe string allowed in the inp array is not bound to the call of any function!")
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def secret_menu(core):
|
||||
#1qaz@WSX
|
||||
if myhash(getpass.getpass("canp: ")) == 1355332552418299328:
|
||||
print("Authorization successful.")
|
||||
else:
|
||||
print("Permission denied.")
|
||||
return 0
|
||||
print("\nHidden input from keyboard, writing to secret_message.txt.")
|
||||
print("Default config is 255 210, current is " + str(core.n) + " " + str(core.k) + ".")
|
||||
info = "Secret menu numbers: 0 = go back; 1 = encrypt, 2 = decrypt; -0 = init txt; h = help.\n"
|
||||
err = "Error! Check command info and try again!\n"
|
||||
ok = "Operation successful.\n"
|
||||
inp = [str(i) for i in range(3)] + ['-0'] + ['h']
|
||||
print(info)
|
||||
while True:
|
||||
s = input("Secret menu number: ")
|
||||
while s not in inp:
|
||||
s = input("Wrong menu number, h = help: ")
|
||||
if s == 'h':
|
||||
print(info)
|
||||
elif s == '0':
|
||||
print("Going back to common menu.\n")
|
||||
break
|
||||
elif s == '1':
|
||||
print("You need pubkey.txt; secret_message.txt will be rewritten.")
|
||||
if(not get_yes_no()):
|
||||
continue
|
||||
try:
|
||||
G = read_txt("pubkey")
|
||||
text = getpass.getpass("Secret text: ")
|
||||
msg = core.encrypt(G, text)
|
||||
write_txt("secret_message", msg)
|
||||
print(ok)
|
||||
except:
|
||||
print(err)
|
||||
elif s == '2':
|
||||
print("You need privkey_s.txt, privkey_p.txt and secret_message.txt.")
|
||||
if(not get_yes_no()):
|
||||
continue
|
||||
try:
|
||||
S = read_txt("privkey_s")
|
||||
P = read_txt("privkey_p")
|
||||
msg = read_txt("secret_message")
|
||||
text = core.decrypt(S, P, msg)
|
||||
print('\nSecret text: ' + text + '\n')
|
||||
print(ok)
|
||||
except:
|
||||
print(err)
|
||||
elif s == '-0':
|
||||
print("Create (or make empty) secret_message.txt in right utf-8 encoding.")
|
||||
if(not get_yes_no()):
|
||||
continue
|
||||
try:
|
||||
write_txt("secret_message", "")
|
||||
print(ok)
|
||||
except:
|
||||
print(err)
|
||||
else:
|
||||
print("Impossible behaviour, mistake in source code!\nThe string allowed in the inp array is not bound to the call of any function!")
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def get_yes_no():
|
||||
s = input("Confirm (0 = go back, 1 = continue): ")
|
||||
while s not in ['0', '1']:
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#all these variables are strings, so it's easy to integrate this code into any project (check GUI and console examples)
|
||||
#text must be in utf-8 encoding (e.g. force encoding when open txt files, check console example)
|
||||
#keys and messages are saved as base64 strings
|
||||
#you can use bin_encrypt and bin_decrypt functions if text is a byte array (check console example)
|
||||
|
||||
'''
|
||||
import cryptosystem_core as core
|
||||
|
@ -15,8 +16,9 @@ G = core.restore_G(S, P)
|
|||
S = core.break_S(G, P)
|
||||
P = core.break_P(G, S)
|
||||
core.config("255 210") #this is the default configuration, NO NEED TO WRITE THIS LINE FOR INITIALIZATION, it is just an example of using the function
|
||||
#these parameters n and k affect the length of the keys and the number of erroneous bytes in the message
|
||||
#see the comments below to understand the requirements for n and k
|
||||
#these parameters n and k affect the length of the keys, messages and the number of erroneous bytes in the message
|
||||
#larger values = larger keys; randomly change (n - k) div 2 bytes during encryption, but add (n - k + 1) bytes to each chunk with len (k - 1).
|
||||
#see the comments below to understand the requirements for n and k (or check console example)
|
||||
'''
|
||||
|
||||
#if you want to figure out how the code below works, keep in mind that
|
||||
|
@ -127,8 +129,13 @@ def unpad_message(msg):
|
|||
return msg[: -padding_byte]
|
||||
|
||||
def encrypt(key, text):
|
||||
return bin_encrypt(key, text.encode("utf-8"))
|
||||
|
||||
def decrypt(s, p, msg):
|
||||
return bin_decrypt(s, p, msg).decode("utf-8")
|
||||
|
||||
def bin_encrypt(key, text):
|
||||
G_ = GF(read_pubkey(key))
|
||||
text = text.encode("utf-8")
|
||||
out = bytes()
|
||||
while len(text) > k - 1:
|
||||
tmp = text[: k - 1]
|
||||
|
@ -137,6 +144,16 @@ def encrypt(key, text):
|
|||
out += encrypt_one(G_, text)
|
||||
return base64.b64encode(out).decode()
|
||||
|
||||
def bin_decrypt(s, p, msg):
|
||||
S_inv = np.linalg.inv(GF(read_privkey_s(s)))
|
||||
P_inv = GF(build_P_inv(read_privkey_p(p)))
|
||||
msg = [int(i) for i in base64.b64decode(msg)]
|
||||
msg = [msg[i - n : i] for i in range(n, len(msg) + n, n)]
|
||||
msg = [decrypt_one(S_inv, P_inv, GF(i)) for i in msg]
|
||||
msg = [i for j in msg for i in j]
|
||||
msg = bytes(msg)
|
||||
return msg
|
||||
|
||||
def encrypt_one(G_, text):
|
||||
msg = pad_message(text, k)
|
||||
m = GF(msg)
|
||||
|
@ -151,16 +168,6 @@ def encrypt_one(G_, text):
|
|||
c = c + GF(z)
|
||||
return bytes(c)
|
||||
|
||||
def decrypt(s, p, msg):
|
||||
S_inv = np.linalg.inv(GF(read_privkey_s(s)))
|
||||
P_inv = GF(build_P_inv(read_privkey_p(p)))
|
||||
msg = [int(i) for i in base64.b64decode(msg)]
|
||||
msg = [msg[i - n : i] for i in range(n, len(msg) + n, n)]
|
||||
msg = [decrypt_one(S_inv, P_inv, GF(i)) for i in msg]
|
||||
msg = [i for j in msg for i in j]
|
||||
msg = bytes(msg).decode("utf-8")
|
||||
return msg
|
||||
|
||||
def decrypt_one(S_inv, P_inv, msg):
|
||||
msg = msg @ P_inv
|
||||
msg, e = rs.decode(msg, errors = True)
|
||||
|
|
|
@ -3,7 +3,7 @@ McEliece cryptosystem implementation by vovuas2003
|
|||
Required Python libraries: numpy, galois.
|
||||
|
||||
All cryptosystem functions are implemented in cryptosystem_core.py, just import it into your project and enjoy!
|
||||
For example, I coded a console menu (that works with txt files) and a GUI app.
|
||||
For example, I coded a console menu (that works with text in txt files and also with any files in binary mode) and a GUI app (for text encryption).
|
||||
|
||||
It is possible to build portable exe with pyinstaller and run code on a computer that does not have Python installed.
|
||||
But it is NOT compilation, so exe file will be quite large.
|
||||
|
|
Loading…
Reference in a new issue