import hashlib import struct # ---------------------------- # RC5 core parameters # ---------------------------- W = 32 # word size in bits R = 12 # rounds B = 16 # key bytes (RC5-32/12/16) WORD_MASK = 0xFFFFFFFF BLOCK_SIZE = 8 # 2 * 32-bit words # ---------------------------- # Utility: Rotate left/right # ---------------------------- def rotl(x, n): return ((x << n) & WORD_MASK) | (x >> (32 - n)) def rotr(x, n): return ((x >> n) | (x << (32 - n))) & WORD_MASK # ---------------------------- # Key Expansion # ---------------------------- def expand_key(key: bytes): # Constants for RC5 with w=32 P32 = 0xB7E15163 Q32 = 0x9E3779B9 # Convert key into c 32-bit words L[0..c-1] c = max(1, B // 4) L = list(struct.unpack("<" + "I" * c, key)) # Initialize S-array t = 2 * (R + 1) S = [0] * t S[0] = P32 for i in range(1, t): S[i] = (S[i - 1] + Q32) & WORD_MASK # Mix key into S i = j = 0 A = Bv = 0 for _ in range(3 * max(t, c)): A = S[i] = rotl((S[i] + A + Bv) & WORD_MASK, 3) Bv = L[j] = rotl((L[j] + A + Bv) & WORD_MASK, (A + Bv) & 31) i = (i + 1) % t j = (j + 1) % c return S # ---------------------------- # Block Encrypt/Decrypt # ---------------------------- def rc5_encrypt_block(block: bytes, S): A, B = struct.unpack(" bytes: if len(iv) != BLOCK_SIZE: raise ValueError("IV must be 8 bytes") S = expand_key(key) blocks = [] prev = iv for i in range(0, len(plaintext), BLOCK_SIZE): block = plaintext[i:i + BLOCK_SIZE] x = bytes(a ^ b for a, b in zip(block, prev)) enc = rc5_encrypt_block(x, S) blocks.append(enc) prev = enc return b"".join(blocks) def rc5_cbc_decrypt(key: bytes, iv: bytes, ciphertext: bytes) -> bytes: if len(iv) != BLOCK_SIZE: raise ValueError("IV must be 8 bytes") if len(ciphertext) % BLOCK_SIZE != 0: raise ValueError("Ciphertext not aligned to block size") S = expand_key(key) blocks = [] prev = iv for i in range(0, len(ciphertext), BLOCK_SIZE): block = ciphertext[i:i + BLOCK_SIZE] dec = rc5_decrypt_block(block, S) x = bytes(a ^ b for a, b in zip(dec, prev)) blocks.append(x) prev = block return b"".join(blocks) KEY = bytes.fromhex("99 90 9c 9d d5 8c 81 82 91 98 94 95 dd 84 89 9a") ITERATIONS = 85454 key_bytes = hashlib.pbkdf2_hmac("sha256", KEY, b"", ITERATIONS, dklen=16) print(f"[+] Key: {key_bytes.hex()}") iv = bytes.fromhex("bb7cdd2e104c3410") with open("./output/85454_bb7cdd2e104c3410.enc", "rb") as f: ct = f.read() dec = rc5_cbc_decrypt(key_bytes, iv, ct) print("decrypted:", dec)