public static BigInt GetRandBits(this Random generator, int bits) {
ContractUtils.Requires(bits > 0);
// equivalent to (bits + 7) / 8 without possibility of overflow
int count = bits % 8 == 0 ? bits / 8 : bits / 8 + 1;
// Pad the end (most significant) with zeros if we align to the byte
// to ensure that we end up with a positive value
byte[] bytes = new byte[bits % 8 == 0 ? count + 1 : count];
generator.NextBytes(bytes);
if (bits % 8 == 0) {
bytes[bytes.Length - 1] = 0;
} else {
bytes[bytes.Length - 1] = (byte)(bytes[bytes.Length - 1] & ((1 << (bits % 8)) - 1));
}
if (bits <= 32) {
return (BigInt)GetWord(bytes, 0, bits);
} else if (bits <= 64) {
ulong a = GetWord(bytes, 0, bits);
ulong b = GetWord(bytes, 32, bits);
return (BigInt)(a | (b << 32));
}
return new BigInt(bytes);
}