P10 = [3, 5, 2, 7, 4, 10, 1, 9, 8, 6]
P8 = [6, 3, 7, 4, 8, 5, 10, 9]
IP = [2, 6, 3, 1, 4, 8, 5, 7]
IP_INV = [4, 1, 3, 5, 7, 2, 8, 6]
EP = [4, 1, 2, 3, 2, 3, 4, 1]
P4 = [2, 4, 3, 1]
S0 = [[[1, 0], [0, 1], [3, 3], [2, 2]],
[[3, 3], [2, 2], [1, 0], [0, 1]],
[[0, 1], [2, 2], [1, 0], [3, 3]],
[[3, 3], [1, 0], [3, 3], [2, 2]]]
S1 = [[[0, 0], [1, 1], [2, 2], [3, 3]],
[[2, 2], [0, 0], [1, 1], [3, 3]],
[[3, 3], [0, 0], [1, 1], [2, 2]],
[[2, 2], [1, 1], [0, 0], [3, 3]]]
def permute(bits, pattern):
return [bits[i - 1] for i in pattern]
def left_shift(bits, n):
return bits[n:] + bits[:n]
def xor(bits1, bits2):
return [b1 ^ b2 for b1, b2 in zip(bits1, bits2)]
def sbox_lookup(bits, sbox):
row = (bits[0] << 1) | bits[3]
col = (bits[1] << 1) | bits[2]
val = sbox[row][col]
return [(val[0] >> 1) & 1, val[0] & 1]
def fk(bits, subkey):
left, right = bits[:4], bits[4:]
ep = permute(right, EP)
xor_result = xor(ep, subkey)
s0_out = sbox_lookup(xor_result[:4], S0)
s1_out = sbox_lookup(xor_result[4:], S1)
sbox_out = permute(s0_out + s1_out, P4)
return xor(left, sbox_out) + right
def switch(bits):
return bits[4:] + bits[:4]
def generate_keys(key):
key = permute(key, P10)
left, right = key[:5], key[5:]
left1, right1 = left_shift(left, 1), left_shift(right, 1)
K1 = permute(left1 + right1, P8)
left2, right2 = left_shift(left1, 2), left_shift(right1, 2)
K2 = permute(left2 + right2, P8)
return K1, K2
def sdes_encrypt(plain_bits, key_bits):
K1, K2 = generate_keys(key_bits)
bits = permute(plain_bits, IP)
bits = fk(bits, K1)
bits = switch(bits)
bits = fk(bits, K2)
return permute(bits, IP_INV)
def sdes_decrypt(cipher_bits, key_bits):
K1, K2 = generate_keys(key_bits)
bits = permute(cipher_bits, IP)
bits = fk(bits, K2)
bits = switch(bits)
bits = fk(bits, K1)
return permute(bits, IP_INV)
def str_to_bitlist(s):
return [int(b) for b in s]
def bitlist_to_str(b):
return ''.join(str(bit) for bit in b)
plaintext = "10101010"
key = "1010000010"
plain_bits = str_to_bitlist(plaintext)
key_bits = str_to_bitlist(key)
encrypted_bits = sdes_encrypt(plain_bits, key_bits)
decrypted_bits = sdes_decrypt(encrypted_bits, key_bits)
print("Plaintext: ", plaintext)
print("Encrypted: ", bitlist_to_str(encrypted_bits))
print("Decrypted: ", bitlist_to_str(decrypted_bits))