def aes128_cbc_decrypt(iv, key, ciphertext): init_global_sbox() plaintext = "" cblocks = [ ciphertext[i:i + BLKSZ] for i in xrange(0, len(ciphertext), BLKSZ) ] for i in xrange(len(cblocks) - 1, 0, -1): t = aes128_decrypt_block(key, cblocks[i]) pb = xor_str(t, cblocks[i - 1]) plaintext = pb + plaintext t = aes128_decrypt_block(key, cblocks[0]) pb = xor_str(t, iv) plaintext = pb + plaintext return plaintext
def decrypt(self, ciphertext, nonce): if not ciphertext: return "" keystream = self._gen_keystream(len(ciphertext), nonce) assert len(keystream) == len(ciphertext) plaintext = xor_str(keystream, ciphertext) return plaintext
def encrypt(self, plaintext, nonce): if not plaintext: return "" keystream = self._gen_keystream(len(plaintext), nonce) assert len(keystream) == len(plaintext) ciphertext = xor_str(keystream, plaintext) return ciphertext
def aes128_cbc_encrypt(iv, key, msg): init_global_sbox() ciphertext = "" mblocks = [msg[i:i + BLKSZ] for i in xrange(0, len(msg), BLKSZ)] assert (len(iv) == BLKSZ) prev = iv for mb in mblocks: xmb = xor_str(prev, mb) cb = aes128_encrypt_block(key, xmb) prev = cb ciphertext += cb return ciphertext
def edit(self, ciphertext, nonce, offset, newtext): unmodified = ciphertext block_offset = (offset / BLKSZ) block_count = (len(newtext) / BLKSZ) + 1 keystream = "" for i in xrange(block_offset, block_offset + block_count): keystream += self.ECB.encrypt(struct.pack('<QQ', nonce, i)) keystream = keystream[(offset % BLKSZ):( offset + len(newtext))] # only need enough keystream for new ciphertext new_ciphertext = xor_str(keystream, newtext) ciphertext = ciphertext[:offset] + new_ciphertext + ciphertext[ offset + len(new_ciphertext):] assert (len(unmodified) == len(ciphertext)) return ciphertext