crypto_hashblocks_hl static method

void crypto_hashblocks_hl(
  1. Uint32List iv,
  2. Uint8List m,
  3. int moff,
  4. int n,
)

Though the maximum SHA-512 message length is 2^128, we set it to the maximum 2^53-1 for javascript compatibility.

TODO: It should be tested whether it works or not.

Implementation

static void crypto_hashblocks_hl(
    Uint32List iv, Uint8List m, final int moff, int n) {
  const iteration = 80;

  final w = Uint32List(iteration * 2);

  final a = Uint32List(2),
      b = Uint32List(2),
      c = Uint32List(2),
      d = Uint32List(2),
      e = Uint32List(2),
      f = Uint32List(2),
      g = Uint32List(2),
      h = Uint32List(2),
      T1 = Uint32List(2),
      T2 = Uint32List(2),
      partial = Uint32List(4);

  var i = 0, j = 0, s0h = 0, s0l = 0, s1h = 0, s1l = 0, pos = 0;

  while (n >= 128) {
    a[0] = iv[0];
    b[0] = iv[2];
    c[0] = iv[4];
    d[0] = iv[6];
    e[0] = iv[8];
    f[0] = iv[10];
    g[0] = iv[12];
    h[0] = iv[14];
    a[1] = iv[1];
    b[1] = iv[3];
    c[1] = iv[5];
    d[1] = iv[7];
    e[1] = iv[9];
    f[1] = iv[11];
    g[1] = iv[13];
    h[1] = iv[15];

    for (j = 0; j < iteration; j++) {
      if (j < 16) {
        i = (j << 3) + pos + moff;

        w[j * 2] =
            (m[i + 0] << 24) | (m[i + 1] << 16) | (m[i + 2] << 8) | m[i + 3];
        w[j * 2 + 1] =
            (m[i + 4] << 24) | (m[i + 5] << 16) | (m[i + 6] << 8) | m[i + 7];
      } else {
        s0h = _gamma0h(w[(j - 15) * 2], w[(j - 15) * 2 + 1]);
        s0l = _gamma0l(w[(j - 15) * 2 + 1], w[(j - 15) * 2]);
        s1h = _gamma1h(w[(j - 2) * 2], w[(j - 2) * 2 + 1]);
        s1l = _gamma1l(w[(j - 2) * 2 + 1], w[(j - 2) * 2]);

        _initAdd64(partial, w, (j - 16) * 2);
        _updateAdd64(partial, s0h, s0l);
        _updateAdd64(partial, s1h, s1l);
        _updateAdd64(partial, w[(j - 7) * 2], w[(j - 7) * 2 + 1]);
        _finalizeAdd64(w, j * 2, partial);
      }

      _initAdd64(partial, h, 0);
      _updateAdd64(partial, _sigma1(e[0], e[1]), _sigma1(e[1], e[0]));
      _updateAdd64(partial, _ch32(e[0], f[0], g[0]), _ch32(e[1], f[1], g[1]));
      _updateAdd64(partial, _K[j * 2], _K[j * 2 + 1]);
      _updateAdd64(partial, w[j * 2], w[j * 2 + 1]);
      _finalizeAdd64(T1, 0, partial);

      _initAdd64(partial, T1, 0);
      _updateAdd64(partial, _sigma0(a[0], a[1]), _sigma0(a[1], a[0]));
      _updateAdd64(
          partial, _maj32(a[0], b[0], c[0]), _maj32(a[1], b[1], c[1]));
      _finalizeAdd64(T2, 0, partial);

      h[0] = g[0];
      h[1] = g[1];
      g[0] = f[0];
      g[1] = f[1];
      f[0] = e[0];
      f[1] = e[1];

      _initAdd64(partial, d, 0);
      _updateAdd64(partial, T1[0], T1[1]);
      _finalizeAdd64(e, 0, partial);

      d[0] = c[0];
      d[1] = c[1];
      c[0] = b[0];
      c[1] = b[1];
      b[0] = a[0];
      b[1] = a[1];
      a[0] = T2[0];
      a[1] = T2[1];
    }
    _initAdd64(partial, iv, 0);
    _updateAdd64(partial, a[0], a[1]);
    _finalizeAdd64(iv, 0, partial);

    _initAdd64(partial, iv, 2);
    _updateAdd64(partial, b[0], b[1]);
    _finalizeAdd64(iv, 2, partial);

    _initAdd64(partial, iv, 4);
    _updateAdd64(partial, c[0], c[1]);
    _finalizeAdd64(iv, 4, partial);

    _initAdd64(partial, iv, 6);
    _updateAdd64(partial, d[0], d[1]);
    _finalizeAdd64(iv, 6, partial);

    _initAdd64(partial, iv, 8);
    _updateAdd64(partial, e[0], e[1]);
    _finalizeAdd64(iv, 8, partial);

    _initAdd64(partial, iv, 10);
    _updateAdd64(partial, f[0], f[1]);
    _finalizeAdd64(iv, 10, partial);

    _initAdd64(partial, iv, 12);
    _updateAdd64(partial, g[0], g[1]);
    _finalizeAdd64(iv, 12, partial);

    _initAdd64(partial, iv, 14);
    _updateAdd64(partial, h[0], h[1]);
    _finalizeAdd64(iv, 14, partial);

    pos += 128;
    n -= 128;
  }
}