internal static unsafe void GetRandomBytes(byte *buffer, int length) { Debug.Assert(buffer != null); Debug.Assert(length >= 0); BCrypt.NTSTATUS status = BCrypt.BCryptGenRandom(IntPtr.Zero, buffer, length, BCrypt.BCRYPT_USE_SYSTEM_PREFERRED_RNG); if (status != BCrypt.NTSTATUS.STATUS_SUCCESS) { if (status == BCrypt.NTSTATUS.STATUS_NO_MEMORY) { throw new OutOfMemoryException(); } else { throw new InvalidOperationException(); } } }
}//GetRandomInt() /// <summary> /// Gets one random signed 64bit integer in a thread safe manner. /// </summary> long GetRandomLong() { lock (_byteCache) { if (_byteCachePosition + sizeof(long) <= BYTE_CACHE_SIZE) { var result = BitConverter.ToInt64(_byteCache, _byteCachePosition); _byteCachePosition += sizeof(long); return result; } BCrypt.NTSTATUS status = BCrypt.BCryptGenRandom(_byteCache, BYTE_CACHE_SIZE); if (status == BCrypt.NTSTATUS.STATUS_SUCCESS) { _byteCachePosition = sizeof(long); return BitConverter.ToInt64(_byteCache, 0); } throw new CryptographicException((int)status); }// lock }//GetRandomLong()
}//NextBytesInternal() /// <summary> /// Gets one random signed 32bit integer in a thread safe manner. /// </summary> int GetRandomInt() { lock (_byteCache) { if (_byteCachePosition + sizeof(int) <= BYTE_CACHE_SIZE) { var result = Unsafe.As<byte, int>(ref _byteCache[_byteCachePosition]);//BitConverter.ToInt32(_byteCache, _byteCachePosition); _byteCachePosition += sizeof(int); return result; } BCrypt.NTSTATUS status = BCrypt.BCryptGenRandom(_byteCache, BYTE_CACHE_SIZE); if (status == BCrypt.NTSTATUS.STATUS_SUCCESS) { _byteCachePosition = sizeof(int); return Unsafe.As<byte, int>(ref _byteCache[0]);//BitConverter.ToInt32(_byteCache, 0); } return ThrowNewCryptographicException((int)status); }// lock }//GetRandomInt()