Приложение б
(обязательное)
Листинг программы алгоритма Эль-Гамаля
import random
from sympy import isprime, primitive_root, mod_inverse
def generate_large_prime(start=10**5):
while True:
p = random.randint(start, start* 10)
if isprime(p):
return p
# Шифрование по Эль-Гамалю
def elgamal_encrypt(m, p, g, y):
k = random.randint(1, p - 1)
a = pow(g, k, p)
b = (m * pow(y, k, p)) % p
return a, b
# Расшифровка по Эль-Гамалю
def elgamal_decrypt(a, b, p, x):
s = pow(a, x, p)
s_inv = mod_inverse(s, p)
m = (b * s_inv) % p
return m
# Основ. логика
def elgamal_demo():
m = int(input("Введите число для шифрования (целое и меньше простого p): "))
p = generate_large_prime()
g = primitive_root(p)
x = random.randint(1, p - 1)
y = pow(g, x, p)
print(f"p = {p}, g = {g}")
print(f"Секретный ключ x = {x}")
print(f"Открытый ключ y = {y}")
if m >= p:
print("Ошибка: число должно быть меньше p.")
return
a, b = elgamal_encrypt(m, p, g, y)
print(f"Зашифровано как: a = {a}, b = {b}")
decrypted = elgamal_decrypt(a, b, p, x)
print(f"Расшифрованное число: {decrypted}")
if __name__ == "__main__":
elgamal_demo()
Приложение в
(обязательное)
Листинг программы ранцевой криптосистемы
import random
from sympy import mod_inverse
def gen_superincr_seq(n, start=2):
seq = [random.randint(start, start + 5)]
for _ in range(n - 1):
seq.append(sum(seq) + random.randint(1, 10))
return seq
def gen_keys(n=8):
priv_key = gen_superincr_seq(n)
m = sum(priv_key) + random.randint(10, 20)
w = random.randint(2, m - 1)
while True:
try:
w_inv = mod_inverse(w, m)
break
except:
w = random.randint(2, m - 1)
pub_key = [(w * x) % m for x in priv_key]
return priv_key, pub_key, w, m, w_inv
def to_bits(num, length):
return list(map(int, bin(num)[2:].zfill(length)))
def from_bits(bits):
return int("".join(map(str, bits)), 2)
def encrypt(num, pub_key):
bits = to_bits(num, len(pub_key))
print(f" ->байт {num} в битах: {bits}")
c = sum(b * pk for b, pk in zip(bits, pub_key))
return c
def decrypt(cipher, priv_key, w_inv, m):
s = (cipher * w_inv) % m
print(f" ->расшифровка суммы {cipher}: s = {s}")
bits = []
for val in reversed(priv_key):
if val <= s:
bits.append(1)
s -= val
else:
bits.append(0)
bits.reverse()
print(f" восстановленные биты: {bits}")
return from_bits(bits)
def split_to_bytes(num_str):
num = int(num_str)
bytes_list = []
while num > 0:
bytes_list.insert(0, num % 256)
num //= 256
return bytes_list
def combine_bytes(bytes_list):
num = 0
for b in bytes_list:
num = num * 256 + b
return str(num)
def backpack_demo():
num_str = input("Число: ")
priv_key, pub_key, w, m, w_inv = gen_keys(8)
print(f"\nЗакрытый ключ: {priv_key}")
print(f"Открытый ключ: {pub_key}")
print(f"w = {w}, m = {m}, w^(-1) mod m = {w_inv}\n")
byte_blocks = split_to_bytes(num_str)
print(f"Число в байтах: {byte_blocks}")
enc_blocks = []
for b in byte_blocks:
enc_blocks.append(encrypt(b, pub_key))
print(f"\nЗашифрованные блоки: {enc_blocks}")
dec_blocks = []
for c in enc_blocks:
dec_blocks.append(decrypt(c, priv_key, w_inv, m))
print(f"\nРасшифрованные байты:{dec_blocks}")
dec_str = combine_bytes(dec_blocks)
print(f"\nРасшифрованное число: {dec_str}")
if __name__ == "__main__":
backpack_demo()
