from typing import Sequence def ROTL(a,b): return (((a) << (b)) | ((a) >> (32 - (b)))) def QR(a, b, c, d): a = (a + b) & 0xffffffff d = (d ^ a) & 0xffffffff d = ROTL(d, 16) & 0xffffffff c = (c + d) & 0xffffffff b = (b ^ c) & 0xffffffff b = ROTL(b, 12) a = (a + b) & 0xffffffff d = (d ^ a) & 0xffffffff d = ROTL(d, 8) & 0xffffffff c = (c + d) & 0xffffffff b = (b ^ c) & 0xffffffff b = ROTL(b, 7) & 0xffffffff return a, b, c, d ROUNDS = 20 def chacha_block(data_in: Sequence[int]) -> Sequence[int]: # make sure to copy this list so it doesn't get modified data = data_in[:] for i in range(0, ROUNDS, 2): data[0], data[4], data[8], data[12] = QR(data[0], data[4], data[8], data[12]) data[1], data[5], data[9], data[13] = QR(data[1], data[5], data[9], data[13]) data[2], data[6], data[10], data[14] = QR(data[2], data[6], data[10], data[14]) data[3], data[7], data[11], data[15] = QR(data[3], data[7], data[11], data[15]) data[0], data[5], data[10], data[15] = QR(data[0], data[5], data[10], data[15]) data[1], data[6], data[11], data[12] = QR(data[1], data[6], data[11], data[12]) data[2], data[7], data[8], data[13] = QR(data[2], data[7], data[8], data[13]) data[3], data[4], data[9], data[14] = QR(data[3], data[4], data[9], data[14]) for i in range(16): data[i] = (data[i] + data_in[i]) & 0xffffffff return data