getProbes(hash) {
    const hashBytes = hexStringToBytes(hash),
      modulo = 8 * this.bits.byteLength
    if (hashBytes.byteLength !== 32)
      throw new RangeError(`Not a 256-bit hash: ${hash}`)
    // on the next three lines, the right shift means interpret value as unsigned
    let x =
      ((hashBytes[0] |
        (hashBytes[1] << 8) |
        (hashBytes[2] << 16) |
        (hashBytes[3] << 24)) >>>
        0) %
      modulo
    let y =
      ((hashBytes[4] |
        (hashBytes[5] << 8) |
        (hashBytes[6] << 16) |
        (hashBytes[7] << 24)) >>>
        0) %
      modulo
    let z =
      ((hashBytes[8] |
        (hashBytes[9] << 8) |
        (hashBytes[10] << 16) |
        (hashBytes[11] << 24)) >>>
        0) %
      modulo
    const probes = [x]
    for (let i = 1; i < this.numProbes; i++) {
      x = (x + y) % modulo
      y = (y + z) % modulo
      probes.push(x)
    }
    return probes
  }
Given a SHA-256 hash (as hex string), returns an array of probe indexes indicating which bits
in the Bloom filter need to be tested or set for this particular entry. We do this by
interpreting the first 12 bytes of the hash as three little-endian 32-bit unsigned integers,
and then using triple hashing to compute the probe indexes. The algorithm comes from:

Peter C. Dillinger and Panagiotis Manolios. Bloom Filters in Probabilistic Verification.
5th International Conference on Formal Methods in Computer-Aided Design (FMCAD), November 2004.
http://www.ccis.northeastern.edu/home/pete/pub/bloom-filters-verification.pdf