A C# implementation of the Fortuna Cryptographic Pseudo Random Number Generator (CPRNG), with added extras.
- NuGet:
install-package Terninger
Terninger requires some time to gather initial entropy before it will produce random numbers.
You can either a) start the generator and await
every call to it, or b) await
starting the generator.
using MurrayGrant.Terninger;
using MurrayGrant.Terninger.Random;
public class RandomnessRequired {
public static readonly PooledEntropyCprngGenerator PooledGenerator =
RandomGenerator.CreateTerninger().StartNoWait();
public async Task UseRandomness() {
using (var random =
await PooledGenerator.CreateCypherBasedGeneratorAsync())
{
var randomInt = random.GetRandomInt32();
}
}
}
using MurrayGrant.Terninger;
using MurrayGrant.Terninger.Random;
public class RandomnessRequired {
public async Task UseTerninger() {
var randomGenerator =
await RandomGenerator.CreateTerninger().StartAndWaitForSeedAsync();
using (var random =
RandomService.PooledGenerator.CreateCypherBasedGenerator())
{
var randomInt = random.GetRandomInt32();
}
}
}
Terninger will save internal state to a file, so that previously accumulated entropy continues to feed into the random number generator.
You should pass a file path to CreateTerninger()
to activate this feature.
using MurrayGrant.Terninger;
using MurrayGrant.Terninger.Random;
public class RandomnessRequired {
public async Task UseTerninger() {
var randomGenerator =
await RandomGenerator.CreateTerninger(persistancePath: "/path/to/terninger.state")
.StartAndWaitForSeedAsync();
...
}
}
Out of the box, Terninger gathers entropy from your system random number generator (/dev/random
or CryptGenRandom
), plus timing and garbage collector stats.
There are additional NuGet packages Terninger.EntropySources.*
which expose additional sources of entropy.
Adds entropy based on current running processes and passive network statistics (eg: bytes sent / received).
using MurrayGrant.Terninger;
using MurrayGrant.Terninger.Random;
public class RandomnessRequired {
public async Task UseTerninger() {
var randomGenerator =
await RandomGenerator.CreateTerninger()
.With(ExtendedSources.All())
.StartAndWaitForSeedAsync();
...
}
}
Adds entropy based active network requests (HTTP content, other sites generating random numbers, ping statistics). It is recommended to set a user-agent identifier for HTTP requests (in case something goes wrong, and fingers need to be pointed).
using MurrayGrant.Terninger;
using MurrayGrant.Terninger.Random;
public class RandomnessRequired {
public async Task UseTerninger() {
var randomGenerator =
await RandomGenerator.CreateTerninger()
.With(NetworkSources.All(
userAgent: NetworkSources.UserAgent("some.identifier.com")
)
.StartAndWaitForSeedAsync();
...
}
}
- Your
PooledEntropyCprngGenerator
should be a singleton. - You MUST
await
the first seed (or checkReseedCount
property is greater than one). - You should derive a
CypherBasedPrngGenerator
from the pooled generator for actual random numbers.
Terninger supports a high quality pseudo random number generator based on a 256 bit seed: Terninger.CreateCypherBasedGenerator()
.
This may be useful as a System.Random
on steroids.
Terninger has extension methods to produce [U]Int32
, [U]Int64
, Boolean
, Single
, Double
, Decimal
and Guid
primitives.
Terninger has an IRandomNumberGenerator
interface, which lets you use any random number generator in c# in the same way.
Any generator which can produce a byte[]
can be easily adapted.
0.5.0:
- IMPORTANT: configuration changes are required for PingStatsSource. Please check your configuration.
- Add net80 target.
- Enhance PingStatsSource to save working targets to persistent state.
- Enhance PingStatsSource to discover new targets at random.
- Add support for Entropy Sources to use Persistent State in PooledEntropyCprngGenerator.
0.4.0:
- Removed HotBits network source due to retirement of true random source.
0.3.0:
- Target frameworks: net48, netcoreapp3.1, net60.
- Persistent state support for
PooledEntropyCprngGenerator
. - Improved pooling of async entropy sources, time to first seed should be much faster.
- Configuration support in console application.
- Additional network entropy sources: qrng.ethz.ch, drand.cloudflare.com.
- Update entropy source quantumnumbers.anu.edu.au to require an API key.
- Update external web content sources, and ping stats servers.
0.2.0:
- Various things.... lost to time.
0.1.1:
- Fixed an issue in
NetworkStatsSource
which generated exceptions repeatedly on Debian.
0.1.0:
- Initial release!
See my blog series about building Turninger and a CPRNG.
Terninger is licensed under the Apache License, copyright Murray Grant.
It may be used freely under the terms of the above license.
Summary: it may be used in any project (commercial or otherwise) as long as you attribute copyright to me somewhere and indicate its licensed under the Apache License.