chachaRounds static method
void
chachaRounds(
- Uint32List state,
- int si,
- Uint32List initialState, {
- required int rounds,
- bool addAndXor = true,
Computes Chacha20 rounds.
Parameter state
is the state that will be XORrred with the key stream.
If addAndXor
is false, it will receive the state variables.
Parameter si
is the index of the first state element.
Parameter initialState
is the initial state.
Parameter addAndXor
is for DartXchacha20.
Implementation
static void chachaRounds(
Uint32List state,
int si,
Uint32List initialState, {
required int rounds,
bool addAndXor = true,
}) {
// -------------------------------------------------------------------------
// Step 1: Initialize
// -------------------------------------------------------------------------
var v0 = initialState[0],
v1 = initialState[1],
v2 = initialState[2],
v3 = initialState[3],
v4 = initialState[4],
v5 = initialState[5],
v6 = initialState[6],
v7 = initialState[7],
v8 = initialState[8],
v9 = initialState[9],
v10 = initialState[10],
v11 = initialState[11],
v12 = initialState[12],
v13 = initialState[13],
v14 = initialState[14],
v15 = initialState[15];
assert(v0 == 0x61707865);
assert(v1 == 0x3320646e);
assert(v2 == 0x79622d32);
assert(v3 == 0x6b206574);
// -------------------------------------------------------------------------
// Step 2: Do ROUNDS column/diagonal rounds
//
// We inlined the 'quarterRound' function because benchmarks showed
// significant enough difference to non-inlined version.
// -------------------------------------------------------------------------
final roundsDividedByTwo = rounds ~/ 2;
for (var i = 0; i < roundsDividedByTwo; i++) {
// -------
// Columns
// -------
v0 = uint32mask & (v0 + v4);
v12 = rotateLeft32(v12 ^ v0, 16);
v8 = uint32mask & (v8 + v12);
v4 = rotateLeft32(v4 ^ v8, 12);
v0 = uint32mask & (v0 + v4);
v12 = rotateLeft32(v12 ^ v0, 8);
v8 = uint32mask & (v8 + v12);
v4 = rotateLeft32(v4 ^ v8, 7);
v1 = uint32mask & (v1 + v5);
v13 = rotateLeft32(v13 ^ v1, 16);
v9 = uint32mask & (v9 + v13);
v5 = rotateLeft32(v5 ^ v9, 12);
v1 = uint32mask & (v1 + v5);
v13 = rotateLeft32(v13 ^ v1, 8);
v9 = uint32mask & (v9 + v13);
v5 = rotateLeft32(v5 ^ v9, 7);
v2 = uint32mask & (v2 + v6);
v14 = rotateLeft32(v14 ^ v2, 16);
v10 = uint32mask & (v10 + v14);
v6 = rotateLeft32(v6 ^ v10, 12);
v2 = uint32mask & (v2 + v6);
v14 = rotateLeft32(v14 ^ v2, 8);
v10 = uint32mask & (v10 + v14);
v6 = rotateLeft32(v6 ^ v10, 7);
v3 = uint32mask & (v3 + v7);
v15 = rotateLeft32(v15 ^ v3, 16);
v11 = uint32mask & (v11 + v15);
v7 = rotateLeft32(v7 ^ v11, 12);
v3 = uint32mask & (v3 + v7);
v15 = rotateLeft32(v15 ^ v3, 8);
v11 = uint32mask & (v11 + v15);
v7 = rotateLeft32(v7 ^ v11, 7);
// ---------
// Diagonals
// ---------
v0 = uint32mask & (v0 + v5);
v15 = rotateLeft32(v15 ^ v0, 16);
v10 = uint32mask & (v10 + v15);
v5 = rotateLeft32(v5 ^ v10, 12);
v0 = uint32mask & (v0 + v5);
v15 = rotateLeft32(v15 ^ v0, 8);
v10 = uint32mask & (v10 + v15);
v5 = rotateLeft32(v5 ^ v10, 7);
v1 = uint32mask & (v1 + v6);
v12 = rotateLeft32(v12 ^ v1, 16);
v11 = uint32mask & (v11 + v12);
v6 = rotateLeft32(v6 ^ v11, 12);
v1 = uint32mask & (v1 + v6);
v12 = rotateLeft32(v12 ^ v1, 8);
v11 = uint32mask & (v11 + v12);
v6 = rotateLeft32(v6 ^ v11, 7);
v2 = uint32mask & (v2 + v7);
v13 = rotateLeft32(v13 ^ v2, 16);
v8 = uint32mask & (v8 + v13);
v7 = rotateLeft32(v7 ^ v8, 12);
v2 = uint32mask & (v2 + v7);
v13 = rotateLeft32(v13 ^ v2, 8);
v8 = uint32mask & (v8 + v13);
v7 = rotateLeft32(v7 ^ v8, 7);
v3 = uint32mask & (v3 + v4);
v14 = rotateLeft32(v14 ^ v3, 16);
v9 = uint32mask & (v9 + v14);
v4 = rotateLeft32(v4 ^ v9, 12);
v3 = uint32mask & (v3 + v4);
v14 = rotateLeft32(v14 ^ v3, 8);
v9 = uint32mask & (v9 + v14);
v4 = rotateLeft32(v4 ^ v9, 7);
}
// -------------------------------------------------------------------------
// Step 3: Addition (not done by Hchacha20)
// -------------------------------------------------------------------------
if (addAndXor) {
state[si + 0] = (0xFFFFFFFF & (v0 + initialState[0])) ^ state[si + 0];
state[si + 1] = (0xFFFFFFFF & (v1 + initialState[1])) ^ state[si + 1];
state[si + 2] = (0xFFFFFFFF & (v2 + initialState[2])) ^ state[si + 2];
state[si + 3] = (0xFFFFFFFF & (v3 + initialState[3])) ^ state[si + 3];
state[si + 4] = (0xFFFFFFFF & (v4 + initialState[4])) ^ state[si + 4];
state[si + 5] = (0xFFFFFFFF & (v5 + initialState[5])) ^ state[si + 5];
state[si + 6] = (0xFFFFFFFF & (v6 + initialState[6])) ^ state[si + 6];
state[si + 7] = (0xFFFFFFFF & (v7 + initialState[7])) ^ state[si + 7];
state[si + 8] = (0xFFFFFFFF & (v8 + initialState[8])) ^ state[si + 8];
state[si + 9] = (0xFFFFFFFF & (v9 + initialState[9])) ^ state[si + 9];
state[si + 10] = (0xFFFFFFFF & (v10 + initialState[10])) ^ state[si + 10];
state[si + 11] = (0xFFFFFFFF & (v11 + initialState[11])) ^ state[si + 11];
state[si + 12] = (0xFFFFFFFF & (v12 + initialState[12])) ^ state[si + 12];
state[si + 13] = (0xFFFFFFFF & (v13 + initialState[13])) ^ state[si + 13];
state[si + 14] = (0xFFFFFFFF & (v14 + initialState[14])) ^ state[si + 14];
state[si + 15] = (0xFFFFFFFF & (v15 + initialState[15])) ^ state[si + 15];
} else {
state[si + 0] = v0;
state[si + 1] = v1;
state[si + 2] = v2;
state[si + 3] = v3;
state[si + 4] = v4;
state[si + 5] = v5;
state[si + 6] = v6;
state[si + 7] = v7;
state[si + 8] = v8;
state[si + 9] = v9;
state[si + 10] = v10;
state[si + 11] = v11;
state[si + 12] = v12;
state[si + 13] = v13;
state[si + 14] = v14;
state[si + 15] = v15;
}
}