$update method

  1. @override
void $update([
  1. List<int>? block,
  2. int offset = 0,
  3. bool last = false
])
override

Internal method to update the message-digest with a single block.

The method starts reading the block from offset index

Implementation

@override
void $update([List<int>? block, int offset = 0, bool last = false]) {
  var m = sbuffer;
  int w0, w1, w2, w3, w4, w5, w6, w7;
  int w8, w9, w10, w11, w12, w13, w14, w15;

  // first half from state
  w0 = state[0];
  w1 = state[1];
  w2 = state[2];
  w3 = state[3];
  w4 = state[4];
  w5 = state[5];
  w6 = state[6];
  w7 = state[7];

  // second half from IV
  w8 = _seed[0];
  w9 = _seed[1];
  w10 = _seed[2];
  w11 = _seed[3];
  w12 = _seed[4] ^ (messageLength & _mask32);
  w13 = _seed[5] ^ (messageLength >>> 32);
  w14 = _seed[6];
  w15 = _seed[7];

  if (last) {
    w14 ^= _mask32; // invert bits
  }

  // Cryptographic mixing
  for (int i = 0; i < 10; i++) {
    var s = _sigma[i];

    // _G(v, 0, 4, 8, 12, m[s[0]], m[s[1]]);
    w0 += w4 + m[s[0]];
    w12 = _rotr(w12 ^ w0, _r1);
    w8 += w12;
    w4 = _rotr(w4 ^ w8, _r2);
    w0 += w4 + m[s[1]];
    w12 = _rotr(w12 ^ w0, _r3);
    w8 += w12;
    w4 = _rotr(w4 ^ w8, _r4);

    // _G(v, 1, 5, 9, 13, m[s[2]], m[s[3]]);
    w1 += w5 + m[s[2]];
    w13 = _rotr(w13 ^ w1, _r1);
    w9 += w13;
    w5 = _rotr(w5 ^ w9, _r2);
    w1 += w5 + m[s[3]];
    w13 = _rotr(w13 ^ w1, _r3);
    w9 += w13;
    w5 = _rotr(w5 ^ w9, _r4);

    // _G(v, 2, 6, 10, 14, m[s[4]], m[s[5]]);
    w2 += w6 + m[s[4]];
    w14 = _rotr(w14 ^ w2, _r1);
    w10 += w14;
    w6 = _rotr(w6 ^ w10, _r2);
    w2 += w6 + m[s[5]];
    w14 = _rotr(w14 ^ w2, _r3);
    w10 += w14;
    w6 = _rotr(w6 ^ w10, _r4);

    // _G(v, 3, 7, 11, 15, m[s[6]], m[s[7]]);
    w3 += w7 + m[s[6]];
    w15 = _rotr(w15 ^ w3, _r1);
    w11 += w15;
    w7 = _rotr(w7 ^ w11, _r2);
    w3 += w7 + m[s[7]];
    w15 = _rotr(w15 ^ w3, _r3);
    w11 += w15;
    w7 = _rotr(w7 ^ w11, _r4);

    // _G(v, 0, 5, 10, 15, m[s[8]], m[s[9]]);
    w0 += w5 + m[s[8]];
    w15 = _rotr(w15 ^ w0, _r1);
    w10 += w15;
    w5 = _rotr(w5 ^ w10, _r2);
    w0 += w5 + m[s[9]];
    w15 = _rotr(w15 ^ w0, _r3);
    w10 += w15;
    w5 = _rotr(w5 ^ w10, _r4);

    // _G(v, 1, 6, 11, 12, m[s[10]], m[s[11]]);
    w1 += w6 + m[s[10]];
    w12 = _rotr(w12 ^ w1, _r1);
    w11 += w12;
    w6 = _rotr(w6 ^ w11, _r2);
    w1 += w6 + m[s[11]];
    w12 = _rotr(w12 ^ w1, _r3);
    w11 += w12;
    w6 = _rotr(w6 ^ w11, _r4);

    // _G(v, 2, 7, 8, 13, m[s[12]], m[s[13]]);
    w2 += w7 + m[s[12]];
    w13 = _rotr(w13 ^ w2, _r1);
    w8 += w13;
    w7 = _rotr(w7 ^ w8, _r2);
    w2 += w7 + m[s[13]];
    w13 = _rotr(w13 ^ w2, _r3);
    w8 += w13;
    w7 = _rotr(w7 ^ w8, _r4);

    // _G(v, 3, 4, 9, 14, m[s[14]], m[s[15]]);
    w3 += w4 + m[s[14]];
    w14 = _rotr(w14 ^ w3, _r1);
    w9 += w14;
    w4 = _rotr(w4 ^ w9, _r2);
    w3 += w4 + m[s[15]];
    w14 = _rotr(w14 ^ w3, _r3);
    w9 += w14;
    w4 = _rotr(w4 ^ w9, _r4);
  }

  // XOR the two halves for new state
  state[0] ^= w0 ^ w8;
  state[1] ^= w1 ^ w9;
  state[2] ^= w2 ^ w10;
  state[3] ^= w3 ^ w11;
  state[4] ^= w4 ^ w12;
  state[5] ^= w5 ^ w13;
  state[6] ^= w6 ^ w14;
  state[7] ^= w7 ^ w15;
}