def toBase64(raw_bytes): raw_bytes = bytearray(raw_bytes) pad_len = 0 while (len(raw_bytes) + pad_len) % 3 != 0: pad_len = pad_len + 1 raw_bytes.extend([0] * pad_len) triplets = groupByBlocks(raw_bytes, 3) new = [] for triplet in triplets: hex1, hex2, hex3 = triplet b1 = (hex1 & 0b11111100) >> 2 b2 = (hex1 & 0b00000011) b3 = (hex2 & 0b11110000) >> 4 b4 = (hex2 & 0b00001111) b5 = (hex3 & 0b11000000) >> 6 b6 = (hex3 & 0b00111111) c1 = b1 c2 = (b2 << 4) ^ b3 c3 = (b4 << 2) ^ b5 c4 = b6 d1 = dec2b64[c1] d2 = dec2b64[c2] d3 = dec2b64[c3] d4 = dec2b64[c4] new.extend([d1, d2, d3, d4]) # padding if pad_len != 0: new[-pad_len:] = ["="] * pad_len return bytearray(new)
def aes_encrypt_ctr(key, msg, nounce): assert len(key) == 16 assert len(nounce) == 8 # little endian stuff nounce = bytearray(reversed(nounce)) counter = bytearray("".join(["\x00"] * 8).encode()) output = bytearray() for block in groupByBlocks(msg, 16): stream_key = nounce + counter encrypted_stream_key = aes_encrypt_block(key, stream_key) output.extend(fixed_xor(encrypted_stream_key, block)) increment_counter(counter) return bytes(output)