doFinal method

  1. @override
int doFinal(
  1. Uint8List out,
  2. int outOff
)
override

Store the MAC of previously given data in buffer out starting at offset outOff. This method returns the size of the digest.

Implementation

@override
int doFinal(Uint8List out, final int outOff) {
  if (outOff + BLOCK_SIZE > out.length) {
    throw ArgumentError('Output buffer is too short.');
  }

  if (currentBlockOffset > 0) {
    processBlock();
  }

  h1 += cshiftr32(h0, 26);
  h0 &= 0x3ffffff;
  h2 += cshiftr32(h1, 26);
  h1 &= 0x3ffffff;
  h3 += cshiftr32(h2, 26);
  h2 &= 0x3ffffff;
  h4 += cshiftr32(h3, 26);
  h3 &= 0x3ffffff;
  h0 += cshiftr32(h4, 26) * 5;
  h4 &= 0x3ffffff;
  h1 += cshiftr32(h0, 26);
  h0 &= 0x3ffffff;

  int g0, g1, g2, g3, g4, b;
  g0 = sum32(h0, 5);
  b = cshiftr32(g0, 26);
  g0 &= 0x3ffffff;
  g1 = sum32(h1, b);
  b = cshiftr32(g1, 26);
  g1 &= 0x3ffffff;
  g2 = sum32(h2, b);
  b = cshiftr32(g2, 26);
  g2 &= 0x3ffffff;
  g3 = sum32(h3, b);
  b = cshiftr32(g3, 26);
  g3 &= 0x3ffffff;
  g4 = sum32(h4, b) - shiftl32(1, 26);

  b = cshiftr32(g4, 31) - 1;
  var nb = not32(b);
  h0 = (h0 & nb) | (g0 & b);
  h1 = (h1 & nb) | (g1 & b);
  h2 = (h2 & nb) | (g2 & b);
  h3 = (h3 & nb) | (g3 & b);
  h4 = (h4 & nb) | (g4 & b);

  int f0, f1, f2, f3;
  f0 = (h0 | shiftl32(h1, 26)) + k0;
  f1 = (cshiftr32(h1, 6) | shiftl32(h2, 20)) + k1;
  f2 = (cshiftr32(h2, 12) | shiftl32(h3, 14)) + k2;
  f3 = (cshiftr32(h3, 18) | shiftl32(h4, 8)) + k3;

  var outByte = ByteData.view(out.buffer, out.offsetInBytes, out.length);
  pack32(f0 & 0xffffffff, outByte, outOff, Endian.little);
  f1 += uRS(f0, 32);
  pack32(f1 & 0xffffffff, outByte, outOff + 4, Endian.little);
  f2 += uRS(f1, 32);
  pack32(f2 & 0xffffffff, outByte, outOff + 8, Endian.little);
  f3 += uRS(f2, 32);
  pack32(f3 & 0xffffffff, outByte, outOff + 12, Endian.little);
  //End come back here chunk

  out = outByte.buffer.asUint8List();

  reset();
  return BLOCK_SIZE;
}