Cannot Decrypt the Encrypted message

I’m working on implementing a custom cryptographic algorithm and I’m encountering an issue where the output of my encryption and decryption processes doesn’t match the expected results. Specifically, I’m not able to correctly decrypt the ciphertext back to the original plaintext.

Block Size:
Input/Output Block Size: 128 bits (16 bytes)

Key Generation:
Initial Key: A 128-bit key is used to generate 16 round keys.
Round Key Generation: The initial key is processed through a key expansion algorithm to produce 16 round keys. Each round key is derived by applying a fixed transformation to the previous round key.

Encryption Process:

Initial State: The plaintext is divided into two halves (L0, R0) of 64 bits each.
Rounds: The encryption process consists of 16 rounds. In each round:
Round Key Application: The round key is XORed with the right half (R).
Feistel Function: A Feistel function is applied to the result, involving substitution and permutation.
Swap: The left and right halves are swapped for the next round.
Final State: After 16 rounds, the final output is obtained by concatenating the left and right halves.

I’m encountering issues where the decrypted output does not match the original plaintext. Despite following the algorithm and applying the round keys correctly, the decrypted text is incorrect or empty.

What I’ve Tried:
-Verified key generation and round key application.
-Checked the implementation of the substitution, permutation, and other operations.
-Debugged step-by-step to ensure each operation is applied correctly.

Thank you

def pad(plaintext, block_size):
    padding_length = block_size - (len(plaintext) % block_size)
    padding = bytes([padding_length] * padding_length)
    return plaintext + padding

def unpad(padded_plaintext):
    padding_length = padded_plaintext[-1]
    return padded_plaintext[:-padding_length]

def key_expansion(key):
    # Ensure key is 16 bytes for 128-bit key
    if len(key) != 16:
        raise ValueError("Key must be 16 bytes long for 128-bit key")

    # Convert key into an integer for processing
    K = int.from_bytes(key, byteorder='big')
    round_keys = []

    # Generate round keys
    for i in range(17):
        # Calculate round key by rotating and applying transformations
        round_key = (K ^ (i * 0x1B)) % (1 << 128) 
        round_keys.append(round_key.to_bytes(16, byteorder='big'))

    return round_keys

CP_TABLE = [0, 32, 1, 33, 2, 34, 3, 35, 4, 36, 5, 37, 6, 38, 7, 39, 8, 40, 9, 41, 10, 42, 11, 43, 12, 44, 13, 45, 14, 46, 15, 47, 16, 48, 17, 49, 18, 50, 19, 51, 20, 52, 21, 53, 22, 54, 23, 55, 24, 56, 25, 57, 26, 58, 27, 59, 28, 60, 29, 61, 30, 62, 31, 63]

FP_TABLE = [57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7, 56, 48, 40, 32, 24, 16, 8, 0, 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6]


def permute(block, table):
    permuted_block = 0
    for index, bit_pos in enumerate(table):
        permuted_block |= ((block >> bit_pos) & 1) << index
    return permuted_block


SBOX = [
    0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
    0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
    0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
    0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
    0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
    0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
    0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
    0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
    0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
    0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
    0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
]

INV_SBOX = [SBOX.index(x) for x in range(256)]
INV_CP_TABLE = [CP_TABLE.index(i) for i in range(64)]
INV_FP_TABLE = [FP_TABLE.index(i) for i in range(64)]

def sub_bytes_8(state):
    return [SBOX[b] for b in state]

def shift_rows_8(state):
    return [
        state[0], state[1], state[2], state[3],
        state[4], state[5], state[6], state[7]
    ]

def gf_mult(a, b):
    p = 0
    hi_bit_set = 0
    for _ in range(8):
        if b & 1:
            p ^= a
        hi_bit_set = a & 0x80
        a <<= 1
        if hi_bit_set:
            a ^= 0x1b
        b >>= 1
    return p % 256

def mix_columns_8(state):
    result = [0] * 8
    for c in range(2):
        col = state[c*4:(c+1)*4]
        result[c*4] = gf_mult(2, col[0]) ^ gf_mult(3, col[1]) ^ col[2] ^ col[3]
        result[c*4+1] = col[0] ^ gf_mult(2, col[1]) ^ gf_mult(3, col[2]) ^ col[3]
        result[c*4+2] = col[0] ^ col[1] ^ gf_mult(2, col[2]) ^ gf_mult(3, col[3])
        result[c*4+3] = gf_mult(3, col[0]) ^ col[1] ^ col[2] ^ gf_mult(2, col[3])
    return result

def add_round_key(state, round_key):
    round_key_bytes = list(round_key)
    return [b ^ round_key_bytes[i] for i, b in enumerate(state)]



def encrypt_block_8(block, round_keys):
    block = int.from_bytes(block, byteorder='big')
    block = permute(block, CP_TABLE)
    block = block.to_bytes(8, byteorder='big')
    state = list(block)
    print(f"Initial State: {state}")
    state = add_round_key(state, round_keys[0])
    print(f"After Add Round Key: {state}")
    for i in range(1, 17):
        state = sub_bytes_8(state)
        state = shift_rows_8(state)
        state = mix_columns_8(state)
        state = add_round_key(state, round_keys[i])
        print(f"After Round {i}: {state}")
    block = int.from_bytes(state, byteorder='big')
    block = permute(block, FP_TABLE)
    return block.to_bytes(8, byteorder='big')

def encrypt_message(message, key):
    block_size = 8  # 64-bit block size = 8 bytes
    padded_message = pad(message.encode('utf-8'), block_size)
    round_keys = key_expansion(key)
    
    ciphertext = b''
    for i in range(0, len(padded_message), block_size):
        block = padded_message[i:i+block_size]
        ciphertext += encrypt_block_8(block, round_keys)
    
    return ciphertext

def inv_mix_columns_8(state):
    result = [0] * 8
    for c in range(2):
        col = state[c*4:(c+1)*4]
        result[c*4] = gf_mult(14, col[0]) ^ gf_mult(11, col[1]) ^ gf_mult(13, col[2]) ^ gf_mult(9, col[3])
        result[c*4+1] = gf_mult(9, col[0]) ^ gf_mult(14, col[1]) ^ gf_mult(11, col[2]) ^ gf_mult(13, col[3])
        result[c*4+2] = gf_mult(13, col[0]) ^ gf_mult(9, col[1]) ^ gf_mult(14, col[2]) ^ gf_mult(11, col[3])
        result[c*4+3] = gf_mult(11, col[0]) ^ gf_mult(13, col[1]) ^ gf_mult(9, col[2]) ^ gf_mult(14, col[3])
    return result

def inv_sub_bytes_8(state):
    return [INV_SBOX[b] for b in state]

def inv_shift_rows_8(state):
    return [
        state[0], state[1], state[2], state[3],
        state[4], state[5], state[6], state[7]
    ]

def decrypt_block_8(block, round_keys):
    block = int.from_bytes(block, byteorder='big')
    block = permute(block, INV_FP_TABLE)
    block = block.to_bytes(8, byteorder='big')
    state = list(block)
    state = add_round_key(state, round_keys[16])
    for i in range(15, 0, -1):
        state = inv_mix_columns_8(state)
        state = inv_shift_rows_8(state)
        state = inv_sub_bytes_8(state)
        state = add_round_key(state, round_keys[i])
    state = add_round_key(state, round_keys[0])
    block = int.from_bytes(state, byteorder='big')
    block = permute(block, INV_CP_TABLE)
    return block.to_bytes(8, byteorder='big')

def decrypt_message(ciphertext, key):
    block_size = 8  # 64-bit block size = 8 bytes
    round_keys = key_expansion(key)
    
    plaintext = b''
    for i in range(0, len(ciphertext), block_size):
        block = ciphertext[i:i+block_size]
        plaintext += decrypt_block_8(block, round_keys)
        print("Plain Text: ", plaintext.hex)
    
    return unpad(plaintext).decode('utf-8')

key = b'x01' * 16  #128-bit key
# plaintext = b'x06' * 8  #64-bit plaintext
message = "I love cybersecurity"

round_keys = key_expansion(key)
for i, rk in enumerate(round_keys):
    print(f"Round Key {i}: {rk.hex()}")

# Encrypt
# ciphertext = encrypt_block_8(plaintext, round_keys)
ciphertext = encrypt_message(message, key)
print("Ciphertext:", ciphertext)

# Decrypt
# decrypted_text = decrypt_block_8(ciphertext, round_keys)
decrypted_text = decrypt_message(ciphertext, key)
print("Decrypted Text:", decrypted_text)




New contributor

ALEXBEET 22 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật