Compare commits

..

No commits in common. "de98ad42680e4c52cda7b069386d2d62c9dd99ff" and "c51f88103eb2abcde756a82f846bf39b9061a717" have entirely different histories.

2 changed files with 32 additions and 14 deletions

View file

@ -25,27 +25,34 @@ def vigenere_de(ctext, vk):
result.append(ch) result.append(ch)
return ''.join(result) return ''.join(result)
def autokey_en(ptext, ak): def autokey_en(ptext, ak):
k = ord(ak.upper()) if isinstance(ak, str) else ak result = []
out = [] ptext = ptext.upper()
for ch in ptext.upper(): current_key = ak
for ch in ptext:
if ch.isalpha(): if ch.isalpha():
out_ch = chr((ord(ch) - 65 + (k - 65)) % 26 + 65) shift = (current_key - ord('A')) % 26
out.append(out_ch); k = ord(ch) cipher_char = chr((ord(ch) - ord('A') + shift) % 26 + ord('A'))
result.append(cipher_char)
current_key = ord(cipher_char)
else: else:
out.append(ch) result.append(ch)
return ''.join(out) return ''.join(result)
def autokey_de(ctext, ak): def autokey_de(ctext, ak):
k = ord(ak.upper()) if isinstance(ak, str) else ak result = []
out = [] ctext = ctext.upper()
for ch in ctext.upper(): current_key = ak
for ch in ctext:
if ch.isalpha(): if ch.isalpha():
p = chr((ord(ch) - 65 - (k - 65)) % 26 + 65) shift = (current_key - ord('A')) % 26
out.append(p); k = ord(p) plain_char = chr((ord(ch) - ord('A') - shift) % 26 + ord('A'))
result.append(plain_char)
current_key = ord(plain_char)
else: else:
out.append(ch) result.append(ch)
return ''.join(out) return ''.join(result)
def operator(argument,ptext,ak,vk): def operator(argument,ptext,ak,vk):
match argument: match argument:

View file

@ -38,6 +38,12 @@ def int_to_fixed_length_bytes(value: int, length_bits: int) -> bytes:
def generate_keypair(p: int, g: int, private_bits: int = 256) -> tuple[int, int]: def generate_keypair(p: int, g: int, private_bits: int = 256) -> tuple[int, int]:
"""
Generate a Diffie-Hellman private/public key pair.
- private_bits controls the size of the secret exponent for performance and security.
256 bits is a common choice for Group 14.
"""
a = 0 a = 0
while a < 2: while a < 2:
a = number.getRandomNBitInteger(private_bits) a = number.getRandomNBitInteger(private_bits)
@ -46,6 +52,10 @@ def generate_keypair(p: int, g: int, private_bits: int = 256) -> tuple[int, int]
def derive_shared_key(peer_public: int, private: int, p: int, key_len: int = 32) -> bytes: def derive_shared_key(peer_public: int, private: int, p: int, key_len: int = 32) -> bytes:
"""
Compute the shared secret and derive a symmetric key using HKDF-SHA256.
Returns key_len bytes (default 32 bytes = 256-bit key).
"""
shared_secret = pow(peer_public, private, p) shared_secret = pow(peer_public, private, p)
# Use fixed-length big-endian encoding of the shared secret for KDF input # Use fixed-length big-endian encoding of the shared secret for KDF input
shared_bytes = int_to_fixed_length_bytes(shared_secret, p.bit_length()) shared_bytes = int_to_fixed_length_bytes(shared_secret, p.bit_length())
@ -53,6 +63,7 @@ def derive_shared_key(peer_public: int, private: int, p: int, key_len: int = 32)
return key return key
@dataclass
class TimingResult: class TimingResult:
alice_keygen_s: float alice_keygen_s: float
bob_keygen_s: float bob_keygen_s: float