private void compress() {

      long t0 = t[0];
      long t1 = t[1];

      System.arraycopy(h, 0, v, 0, 8);
      System.arraycopy(IV, 0, v, 8, 8);

      v[12] ^= t0;
      v[13] ^= t1;

      if (f) {
        v[14] ^= 0xffffffffffffffffL;
      }

      for (long j = 0; j < rounds; ++j) {
        byte[] s = PRECOMPUTED[(int) (j % 10)];

        mix(m[s[0]], m[s[4]], 0, 4, 8, 12);
        mix(m[s[1]], m[s[5]], 1, 5, 9, 13);
        mix(m[s[2]], m[s[6]], 2, 6, 10, 14);
        mix(m[s[3]], m[s[7]], 3, 7, 11, 15);
        mix(m[s[8]], m[s[12]], 0, 5, 10, 15);
        mix(m[s[9]], m[s[13]], 1, 6, 11, 12);
        mix(m[s[10]], m[s[14]], 2, 7, 8, 13);
        mix(m[s[11]], m[s[15]], 3, 4, 9, 14);
      }

      // update h:
      for (int offset = 0; offset < h.length; offset++) {
        h[offset] ^= v[offset] ^ v[offset + 8];
      }
    }
F is a compression function for BLAKE2b. It takes as an argument the state vector `h`,
message block vector `m`, offset counter `t`, final block indicator flag `f`, and number of
rounds `rounds`. The state vector provided as the first parameter is modified by the
function.
crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/Blake2bfMessageDigest.java