GoeaLabs.Chaos 2.0.1

The ID prefix of this package has been reserved for one of the owners of this package by NuGet.org. Prefix Reserved
Additional Details

Obsolete.

The owner has unlisted this package. This could mean that the package is deprecated, has security vulnerabilities or shouldn't be used anymore.
dotnet add package GoeaLabs.Chaos --version 2.0.1
NuGet\Install-Package GoeaLabs.Chaos -Version 2.0.1
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="GoeaLabs.Chaos" Version="2.0.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add GoeaLabs.Chaos --version 2.0.1
#r "nuget: GoeaLabs.Chaos, 2.0.1"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install GoeaLabs.Chaos as a Cake Addin
#addin nuget:?package=GoeaLabs.Chaos&version=2.0.1

// Install GoeaLabs.Chaos as a Cake Tool
#tool nuget:?package=GoeaLabs.Chaos&version=2.0.1

GoeaLabs.Caos

GitHub GitHub release (latest SemVer) Nuget (with prereleases)

Project Description

  • A cryptographically secure deterministic random number generator (CSDRNG) for .NET6+, based on RFC8439 ChaCha.
  • Chaos and ChaCha are algorithmically indistinguishable, but Chaos includes additional features that make it distinct enough to merit a separate name.
  • To provide clarity and facilitate comparison, a comparison table is often the best approach:
ChaCha Chaos
Uses one UInt32 as block counter and three UInt32 as nonce. Uses one UInt64 as block counter and one UInt64 as stream counter.
Exposes one function chacha20_block(key, counter, nonce);, suitable for encryption only. Exposes 53 methods catering to encryption and general purpose usage.
Allows for 20 rounds only. Allows for any even number of rounds in the arithmetic interval [2, 254].
Does not have a standard coordinate system. Has a standard coordinate system allowing for arbitrary jumps.

Technical summary

For any given kernel (seed), Chaos is capable of producing $2^{64}$ streams, each stream containing $2^{64}$ pebbles (blocks), each pebble being composed out of 16 UInt32(s) or 64 UInt8(s).

Features

  • The software is licensed under the Apache 2.0 license, which is a commercially-friendly open-source license.
  • The algorithm has been rigorously tested and validated against all test vectors provided in RFC8439, a widely recognized standard for cryptographic algorithms
  • Chaos's CSDRNG offers a rich set of APIs that enable developers to easily integrate random number generation into their applications.
  • The library is designed to be endian-neutral, ensuring consistent behavior and results across both Little Endian and Big Endian systems.
  • With support for min-max scaling, developers can easily adjust the output of number producing methods to fit within a specific range, without having to perform manual scaling calculations.
  • The library has undergone rigorous testing, including hundreds of automated tests covering a wide range of scenarios and use cases.
  • With a focus on simplicity and ease of use, the API is free from unnecessary restrictions or complications.

Compatibility

The library is fully integrated with .NET6 and .NET7, offering advanced functionality and operations on the latest numeric types, including UInt128 and Int128.

Terminology

  • kernel means the generator's seed (or key as per RFC8439 parlance);
  • pebble means the index of a Chaos block;
  • stream means the index of a Chaos stream;

API

The IChaos interface provides several methods for generating random numbers, including next(s), fill(s), load(s), and the logistic method GoTo(ulong?, ulong?). Additionally, all number-generating methods (as opposed to block-generating methods) include an optional min-max scaling feature, which allows the user to specify the range of values produced by the method in any sub-interval using arithmetic notation [minVal, maxVal]. This powerful feature makes it easy to generate random numbers with specific properties or constraints.

Next(s)

These methods produce random blocks or numbers while automatically advancing the engine's coordinates.

Method Available Summary
void Next(Span<uint>); NET6+ Writes the next block as UInt32(s).
void Next(Span<byte>); NET6+ Writes the next block as UInt8(s).
byte NextUInt8(byte?, byte?); NET6+ Computes the next random UInt8, with optional custom min-max scaling.
sbyte NextInt8(sbyte?, sbyte?); NET6+ Computes the next random Int8, with optional custom min-max scaling.
ushort NextUInt16(ushort?, ushort?); NET6+ Computes the next random UInt16, with optional custom min-max scaling.
short NextInt16(short?, short?); NET6+ Computes the next random Int16, with optional custom min-max scaling.
uint NextUInt32(uint?, uint?); NET6+ Computes the next random UInt32, with optional custom min-max scaling.
int NextInt32(int?, int?); NET6+ Computes the next random Int32, with optional custom min-max scaling.
ulong NextUInt64(ulong?, ulong?); NET6+ Computes the next random UInt64, with optional custom min-max scaling.
long NextInt64(long?, long?); NET6+ Computes the next random Int64, with optional custom min-max scaling.
BigInteger NextBigUInt128(BigInteger?, BigInteger?); NET6+ Computes the next random 128 bit unsigned BigInteger, with optional custom min-max scaling.
BigInteger NextBigInt128(BigInteger?, BigInteger?); NET6+ Computes the next random 128 bit signed BigInteger, with optional custom min-max scaling.
BigInteger NextBigUInt256(BigInteger?, BigInteger?); NET6+ Computes the next random 256 bit unsigned BigInteger, with optional custom min-max scaling.
BigInteger NextBigInt256(BigInteger?, BigInteger?); NET6+ Computes the next random 256 bit signed BigInteger, with optional custom min-max scaling.
BigInteger NextBigUInt512(BigInteger?, BigInteger?); NET6+ Computes the next random 512 bit unsigned BigInteger, with optional custom min-max scaling.
BigInteger NextBigInt512(BigInteger?, BigInteger?); NET6+ Computes the next random 512 bit signed BigInteger, with optional custom min-max scaling.
UInt128 NextUInt128(UInt128?, UInt128?); NET7+ Computes the next random UInt128, with optional custom min-max scaling.
Int128 NextInt128(Int128?, Int128?); NET7+ Computes the next random Int128, with optional custom min-max scaling.

Fill(s)

These methods fill buffers with random numbers while automatically advancing the engine's coordinates.

Method Available Summary
FillUInt8(Span<byte>, byte?, byte?) NET6+ Fills a buffer with random UInt8(s), with optional custom min-max scaling.
FillInt8(Span<sbyte>, sbyte?, sbyte?); NET6+ Fills a buffer with random Int8(s), with optional custom min-max scaling.
FillUInt16(Span<ushort>, ushort?, ushort?); NET6+ Fills a buffer with random UInt16(s), with optional custom min-max scaling.
FillInt16(Span<short>, short?, short?); NET6+ Fills a buffer with random Int16(s), with optional custom min-max scaling.
FillUInt32(Span<uint>, uint?, uint?); NET6+ Fills a buffer with random UInt32(s), with optional custom min-max scaling.
FillInt32(Span<int>, int?, int?); NET6+ Fills a buffer with random Int32(s), with optional custom min-max scaling.
void FillUInt64(Span<ulong>, ulong? minVal, ulong?); NET6+ Fills a buffer with random UInt64(s), with optional custom min-max scaling.
void FillInt64(Span<long>, long?, long?); NET6+ Fills a buffer with random Int64(s), with optional custom min-max scaling.
void FillBigUInt128(Span<BigInteger>, BigInteger?, BigInteger?); NET6+ Fills a buffer with random 128 bit unsigned BigInteger(s), with optional custom min-max scaling.
void FillBigInt128(Span<BigInteger>, BigInteger?, BigInteger?); NET6+ Fills a buffer with random 128 bit signed BigInteger(s), with optional custom min-max scaling.
void FillBigUInt256(Span<BigInteger>, BigInteger?, BigInteger?); NET6+ Fills a buffer with random 256 bit unsigned BigInteger(s), with optional custom min-max scaling.
void FillBigInt256(Span<BigInteger>, BigInteger?, BigInteger?); NET6+ Fills a buffer with random 256 bit signed BigInteger(s), with optional custom min-max scaling.
void FillBigUInt512(Span<BigInteger>, BigInteger?, BigInteger?); NET6+ Fills a buffer with random 512 bit unsigned BigInteger(s), with optional custom min-max scaling.
void FillBigInt512(Span<BigInteger>, BigInteger?, BigInteger?); NET6+ Fills a buffer with random 512 bit signed BigInteger(s), with optional custom min-max scaling.
void FillUInt128(Span<UInt128>, UInt128?, UInt128?); NET7+ Fills a buffer with random UInt128(s), with optional custom min-max scaling.
void FillInt128(Span<Int128>, Int128?, Int128?); NET7+ Fills a buffer with random Int128(s), with optional custom min-max scaling.

Load(s)

These methods enable the retrieval of any block or number at arbitrary coordinates.

Method Available Summary
void Load(ulong, ulong, Span<uint>); NET6+ Retrieves the block at given coordinates as UInt32(s).
void Load(ulong, ulong, Span<byte>); NET6+ Retrieves the block at given coordinates as UInt8(s).
byte LoadUInt8(ulong, ulong, byte?, byte?); NET6+ Retrieves the UInt8 at given coordinates, with optional custom min-max scaling.
sbyte LoadInt8(ulong, ulong, sbyte?, sbyte?); NET6+ Retrieves the Int8 at given coordinates, with optional custom min-max scaling.
ushort LoadUInt16(ulong, ulong, ushort?, ushort?); NET6+ Retrieves the UInt16 at given coordinates, with optional custom min-max scaling.
short LoadInt16(ulong, ulong, short?, short?); NET6+ Retrieves the Int16 at given coordinates, with optional custom min-max scaling.
uint LoadUInt32(ulong, ulong, uint?, uint?); NET6+ Retrieves the UInt32 at given coordinates, with optional custom min-max scaling.
int LoadInt32(ulong, ulong, int?, int?); NET6+ Retrieves the Int32 at given coordinates, with optional custom min-max scaling.
ulong LoadUInt64(ulong, ulong, ulong?, ulong?); NET6+ Retrieves the UInt64 at given coordinates, with optional custom min-max scaling.
long LoadInt64(ulong, ulong, long?, long?); NET6+ Retrieves the Int64 at given coordinates, with optional custom min-max scaling.
BigInteger LoadBigUInt128(ulong, ulong, BigInteger?, BigInteger?); NET6+ Retrieves the 128 bit unsigned BigInteger at given coordinates, with optional custom min-max scaling.
BigInteger LoadBigInt128(ulong, ulong, BigInteger?, BigInteger?); NET6+ Retrieves the 128 bit signed BigInteger at given coordinates, with optional custom min-max scaling.
BigInteger LoadBigUInt256(ulong, ulong, BigInteger?, BigInteger?); NET6+ Retrieves the 256 bit unsigned BigInteger at given coordinates, with optional custom min-max scaling.
BigInteger LoadBigInt256(ulong, ulong, BigInteger?, BigInteger?); NET6+ Retrieves the 256 bit signed BigInteger at given coordinates, with optional custom min-max scaling.
BigInteger LoadBigUInt512(ulong, ulong, BigInteger?, BigInteger?); NET6+ Retrieves the 512 bit unsigned BigInteger at given coordinates, with optional custom min-max scaling.
BigInteger LoadBigInt512(ulong, ulong, BigInteger?, BigInteger?); NET6+ Retrieves the 512 bit signed BigInteger at given coordinates, with optional custom min-max scaling.
UInt128 LoadUInt128(ulong, ulong, UInt128?, UInt128?); NET7+ Retrieves the UInt128 at given coordinates, with optional custom min-max scaling.
Int128 LoadInt128(ulong, ulong, Int128?, Int128?); NET7+ Retrieves the Int128 at given coordinates, with optional custom min-max scaling.

Logistics

Chaos provides 1 logistic method GoTo(ulong?, ulong?) enabling arbitrary positioning of the enigene's coordinate system.

  • A call to GoTo(null, null) effectively resets the engine's coordinates;
  • A call to GoTo(null, 9000) positions the engine at the very beginning of stream 9000. Doing GoTo(0, 9000) will result in a call to next(s) or fill(s) to skip the pebble at index 0 due to the fact that these methods first advance the coordinates and then do their work;
  • Use load(s) for arbitrary jumps at various coordinates. Use GoTo(ulong?, ulong?) for positioning the engine before further calls to next(s) or fill(s).

Examples

Automatic engine initialization with random kernel and 20 rounds:

using GoeaLabs.Security.Random;

var engine = new Chaos();

User defined initialization with user defined kernel and rounds:

using GoeaLabs.Security.Random;

// IChaCha.KL (8 uint(s))
var kernel = new uint[] { 0, 1, 2, 3, 4, 5, 6, 7 };
var rounds = 40;
var engine = new Chaos(kernel, rounds);

The user needs 1 random byte:

using GoeaLabs.Security.Random;

var engine = new Chaos();
var number = engine.NextUInt8();

The user needs 1 random byte, but scaled to interval [1,6] (die roll):

using GoeaLabs.Security.Random;

var engine = new Chaos();
var number = engine.NextUInt8(1, 6);

The user needs to simulate a dice roll for a game with 6 dice:

using GoeaLabs.Security.Random;

var engine = new Chaos();
Span<byte> rolls = stackalloc byte[6];
engine.FillUInt8(rolls, 1, 6);

The user needs a random 128 bit unsigned integer:

using GoeaLabs.Security.Random;

var engine = new Chaos();
var number = engine.NextBigUInt128();

On NET7+, the user needs a random 128 bit unsigned integer:

using GoeaLabs.Security.Random;

var engine = new Chaos();
var number = engine.NextUInt128();

The user needs 100 random 128 bit signed integers in the interval $[-2^{80}, 2^{80}]$:

using GoeaLabs.Security.Random;

var engine = new Chaos();
var result = new BigInteger[100];

engine.FillBigInt128(result, -BigInteger.Pow(2, 80), BigInteger.Pow(2, 80));

The user needs a random 256 bit unsigned integer in the interval $[2^{130}, 2^{140}]$:

using GoeaLabs.Security.Random;

var engine = new Chaos();
var number = engine.NextUInt256(BigInteger.Pow(2, 130), BigInteger.Pow(2, 140));

The user needs 100 random 256 bit unsigned integers in the interval $[2^{130}, 2^{140}]$:

using GoeaLabs.Security.Random;

var engine = new Chaos();
var result = new BigInteger[100];

engine.FillBigUInt256(result, BigInteger.Pow(2, 130), BigInteger.Pow(2, 140));

The user needs to load the 1981th block from the 2023th stream and needs it raw, as UInt32:

using GoeaLabs.Security.Random;

var pebble = 1981;
var stream = 2023;
var engine = new Chaos();
Span<uint> result = stackalloc uint[IChaCha.SL];
engine.Load(pebble, stream, result);

The user needs to load the 1981th block from the 2023th stream and needs it as UInt8(s):

using GoeaLabs.Security.Random;

var pebble = 1981;
var stream = 2023;
var engine = new Chaos();
Span<byte> result = stackalloc byte[IChaCha.SL * sizeof(uint)];
engine.Load(pebble, stream, result);

The user needs to load the 1981th block from the 2023th as an UInt8 scaled in the interval [1,6]:

using GoeaLabs.Security.Random;

var pebble = 1981;
var stream = 2023;
var engine = new Chaos();
var number = engine.LoadUInt8(pebble, stream, 1, 6);

The user needs to retrieve 3 random UInt8(s) starting at 100th block of the 3000th stream, then reset the engine completely:

using GoeaLabs.Security.Random;

// Not a typo: we set the pebble at desired position - 1
var pebble = 99;
var stream = 3000;
Span<byte> result = stackalloc byte[3];

var engine = new Chaos().GoTo(pebble, stream);

engine.FillUInt8(result);
engine.GoTo(null, null);
// ... more work

See tests for more examples.

Installation

Install with NuGet Package Manager Console

Install-Package GoeaLabs.Chaos

Install with .NET CLI

dotnet add package GoeaLabs.Chaos
Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated