function bloomFilterAdd(bloom, elemIdActor, elemIdCtr) {
  let modulo = 8 * bloom.byteLength, x = elemIdCtr % modulo, y = elemIdActor % modulo

  // Use one step of FNV-1a to compute a third value from the two inputs.
  // Taken from http://www.isthe.com/chongo/tech/comp/fnv/index.html
  // The prime is just over 2^24, so elemIdCtr can be up to about 2^29 = 500 million before the
  // result of the multiplication exceeds 2^53. And even if it does exceed 2^53 and loses precision,
  // that shouldn't be a problem as it should still be deterministic, and the Bloom filter
  // computation only needs to be internally consistent within this library.
  let z = ((elemIdCtr ^ elemIdActor) * 16777619 >>> 0) % modulo

  for (let i = 0; i < BLOOM_NUM_PROBES; i++) {
    bloom[x >>> 3] |= 1 << (x & 7)
    x = (x + y) % modulo
    y = (y + z) % modulo
  }
}
Updates Bloom filter `bloom`, given as a Uint8Array, to contain the list element ID consisting of
counter `elemIdCtr` and actor number `elemIdActor`. We don't actually bother computing a hash
function, since those two integers serve perfectly fine as input. We turn the two integers into a
sequence of probe indexes using the triple hashing algorithm from the following paper:

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