docs: public int engineDigest(byte[] hashvalue, int offset, final int len)
              throws DigestException {
          if (len >= HASH_LENGTH) {
              if (hashvalue.length - offset >= HASH_LENGTH) {
                  /* Flush the trailing bytes, adding padding bytes into last
                   * blocks. */
                  int i;
                  /* Add padding null bytes but replace the last 8 padding bytes
                   * by the little-endian 64-bit digested message bit-length. */
                  pad[i = padding] = (byte)0x80; /* required 1st padding byte */
                  /* Check if 8 bytes available in pad to store the total
                   * message size */
                  switch (i) { /* INVARIANT: i must be in [0..63] */
                  case 52: pad[53] = (byte)0x00; /* no break; falls thru */
                  case 53: pad[54] = (byte)0x00; /* no break; falls thru */
                  case 54: pad[55] = (byte)0x00; /* no break; falls thru */
                  case 55: break;
                  case 56: pad[57] = (byte)0x00; /* no break; falls thru */
                  case 57: pad[58] = (byte)0x00; /* no break; falls thru */
                  case 58: pad[59] = (byte)0x00; /* no break; falls thru */
                  case 59: pad[60] = (byte)0x00; /* no break; falls thru */
                  case 60: pad[61] = (byte)0x00; /* no break; falls thru */
                  case 61: pad[62] = (byte)0x00; /* no break; falls thru */
                  case 62: pad[63] = (byte)0x00; /* no break; falls thru */
                  case 63:
                      computeBlock(pad, 0);
                      /* Clear the 56 first bytes of pad[]. */
                      i = 52;
                      do {
                          pad[i    ] = (byte)0x00;
                          pad[i + 1] = (byte)0x00;
                          pad[i + 2] = (byte)0x00;
                          pad[i + 3] = (byte)0x00;
                      } while ((i -= 4) >= 0);
                      break;
                  default:
                      /* Clear the rest of 56 first bytes of pad[]. */
                      switch (i & 3) {
                      case 3: i++;
                              break;
                      case 2: pad[(i += 2) - 1] = (byte)0x00;
                              break;
                      case 1: pad[(i += 3) - 2] = (byte)0x00;
                              pad[ i       - 1] = (byte)0x00;
                              break;
                      case 0: pad[(i += 4) - 3] = (byte)0x00;
                              pad[ i       - 2] = (byte)0x00;
                              pad[ i       - 1] = (byte)0x00;
                      }
                      do {
                          pad[i    ] = (byte)0x00;
                          pad[i + 1] = (byte)0x00;
                          pad[i + 2] = (byte)0x00;
                          pad[i + 3] = (byte)0x00;
                      } while ((i += 4) < 56);
                  }
                  /* Convert the message size from bytes to big-endian bits. */
                  pad[56] = (byte)((i = (int)(bytes >>> 29)) >> 24);
                  pad[57] = (byte)(i >>> 16);
                  pad[58] = (byte)(i >>> 8);
                  pad[59] = (byte)i;
                  pad[60] = (byte)((i = (int)bytes << 3) >> 24);
                  pad[61] = (byte)(i >>> 16);
                  pad[62] = (byte)(i >>> 8);
                  pad[63] = (byte)i;
                  computeBlock(pad, 0);
                  /* Return the computed digest in big-endian byte order. */
                  hashvalue[offset     ] = (byte)((i = hA) >>> 24);
                  hashvalue[offset +  1] = (byte)(i >>> 16);
                  hashvalue[offset +  2] = (byte)(i >>> 8);
                  hashvalue[offset +  3] = (byte)i;
                  hashvalue[offset +  4] = (byte)((i = hB) >>> 24);
                  hashvalue[offset += 5] = (byte)(i >>> 16);
                  hashvalue[offset +  1] = (byte)(i >>> 8);
                  hashvalue[offset +  2] = (byte)i;
                  hashvalue[offset +  3] = (byte)((i = hC) >>> 24);
                  hashvalue[offset +  4] = (byte)(i >>> 16);
                  hashvalue[offset += 5] = (byte)(i >>> 8);
                  hashvalue[offset +  1] = (byte)i;
                  hashvalue[offset +  2] = (byte)((i = hD) >>> 24);
                  hashvalue[offset +  3] = (byte)(i >>> 16);
                  hashvalue[offset +  4] = (byte)(i >>> 8);
                  hashvalue[offset += 5] = (byte)i;
                  hashvalue[offset +  1] = (byte)((i = hE) >>> 24);
                  hashvalue[offset +  2] = (byte)(i >>> 16);
                  hashvalue[offset +  3] = (byte)(i >>> 8);
                  hashvalue[offset +  4] = (byte)i;
                  engineReset(); /* clear the evidence */
                  return HASH_LENGTH;
              }
              throw new DigestException(
                  "insufficient space in output buffer to store the digest");
          }
          throw new DigestException("partial digests not returned");
      }