import secrets def xor(a: bytes, b: bytes): if len(a)!=len(b): raise Exception("Bad Length") return bytes([a[i]^b[i] for i in range(len(a))]) def cbcXor(blocks, key: bytes, iv: bytes = None, BS=16): if len(key)!=BS: raise Exception("Bad key len") if not iv: iv = secrets.token_bytes(16) lastBlock = iv res = [] for block in blocks: if len(block)!=BS: raise Exception("Bad block length") mid = xor(block, lastBlock) enc = xor(mid, key) lastBlock = enc res.append(enc) return res def decCbcXor(blocks, key: bytes, iv: bytes = None, BS=16): if len(key)!=BS: raise Exception("Bad key len") if not iv: iv = secrets.token_bytes(16) lastBlock = iv res = [] for block in blocks: if len(block)!=BS: raise Exception("Bad block length") mid = xor(block, key) enc = xor(mid, lastBlock) lastBlock = block res.append(enc) return res def randBlocks(num: int = 64): return [secrets.token_bytes(16) for i in range(num)]