private ulong GetDigestsFromRandomPools(ICollection <byte[]> digests) { // Based on Dodis et al sections 5.2 and 6.3. ulong randomPoolUsedMask = 0; if (_RandomPools.Length > 0) { // Create a bit mask to determine which pools to draw from. ulong randomPoolNumber = 0; ulong randomPoolMask = (1UL << (_RandomPools.Length)) - 1; var anyDigests = digests.Any(); do { // Chance of random selection is at best 1/2, and may be less, depending on the value of _RandomFactor. randomPoolNumber = _Rng.GetRandomUInt64(); for (int i = 0; i < _RandomFactor; i++) { randomPoolNumber = randomPoolNumber & _Rng.GetRandomUInt64(); } // If any random pools are defined, and there isn't already a digest, we must ensure at least one pool is drawn from. } while (!anyDigests && (randomPoolNumber & randomPoolMask) == 0); // Read from pools. for (int i = 0; i < _RandomPools.Length; i++) { if (PoolIsUsedRandom(i, randomPoolNumber)) { digests.Add(_RandomPools[i].GetDigest()); randomPoolUsedMask = randomPoolUsedMask | (1UL << i); } } } return(randomPoolUsedMask); }