chachaRounds static method

void chachaRounds(
  1. Uint32List state,
  2. int si,
  3. Uint32List initialState, {
  4. required int rounds,
  5. bool addAndXor = true,
})

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;
  }
}