42 lines
1.4 KiB
Python
42 lines
1.4 KiB
Python
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 |