public void Regenerate20() { var rng = ChaChaSoftware.Create(new UInt32[] { 0, 0, 1, 0, 2, 0, 3, 0 }, 0, 0, 10); Span <UInt32> buffer = stackalloc UInt32[64]; rng.Regenerate(buffer); Assert.Equal(137206642u, buffer[0]); Assert.Equal(0ul, rng.Stream); }
public void Generate8() { var rng = ChaChaSoftware.Create(new UInt32[] { 0, 0, 1, 0, 2, 0, 3, 0 }, UInt64.MaxValue, 0, 4); Span <UInt32> buffer = stackalloc UInt32[64]; rng.Generate(buffer); Assert.Equal(3680296248u, buffer[0]); Assert.Equal(0ul, rng.Stream); }
public void StreamModification() { var rng = ChaChaSoftware.Create(new UInt32[] { 0, 0, 1, 0, 2, 0, 3, 0 }, 0, 0, 4); Span <UInt32> buffer = stackalloc UInt32[64]; Span <UInt32> buffer2 = stackalloc UInt32[64]; rng.Regenerate(buffer); rng.Stream = 1ul; rng.Regenerate(buffer2); for (Int32 i = 0; i < buffer.Length; i++) { Assert.NotEqual(buffer[i], buffer2[i]); } }
/// <summary> /// Creates a new instance of <see cref="ChaChaIntrinsics"/>. /// </summary> /// <param name="key">ChaCha20's key. Must have a length of 8.</param> /// <param name="counter">ChaCha's 64-bit block counter.</param> /// <param name="stream">ChaCha20's 64-bit stream id.</param> /// <param name="doubleRoundCount"> /// The number of double rounds to perform. Half the total number of rounds, /// ex. ChaCha20 has 10 double rounds and ChaCha8 has 4 double rounds. /// </param> public static ChaChaIntrinsics Create(ReadOnlySpan <UInt32> key, UInt64 counter, UInt64 stream, UInt32 doubleRoundCount) { Debug.Assert(key.Length == 8); Debug.Assert(doubleRoundCount != 0); if (Avx2.IsSupported) { return(new ChaChaIntrinsics(ChaChaAvx2.Create(key, counter, stream, doubleRoundCount))); } if (Sse2.IsSupported) { return(new ChaChaIntrinsics(ChaChaSse2.Create(key, counter, stream, doubleRoundCount))); } return(new ChaChaIntrinsics(ChaChaSoftware.Create(key, counter, stream, doubleRoundCount))); }
/// <summary> /// Creates a ChaCha RNG using the given seed and number of double rounds. /// </summary> /// <param name="seed">A seed containing the key and stream.</param> /// <param name="doubleRounds"> /// The number of double rounds to perform. Half the total number of rounds, /// ex. ChaCha20 has 10 double rounds and ChaCha8 has 4 double rounds. /// </param> /// <exception cref="ArgumentOutOfRangeException"> /// Thrown if <paramref name="doubleRounds"/> is equal to 0. /// </exception> public static ChaCha Create(Seed seed, UInt32 doubleRounds) { if (doubleRounds == 0) { throw new ArgumentOutOfRangeException(nameof(doubleRounds)); } var key = seed.Key.Length != 0 ? seed.Key.Span : stackalloc UInt32[KeyLength]; #if X86_INTRINSICS var core = ChaChaIntrinsics.Create(key, UInt64.MaxValue, seed.Stream, doubleRounds); var blockBuffer = new BlockBuffer32 <ChaChaIntrinsics, UInt64>(core); #else var core = ChaChaSoftware.Create(key, UInt64.MaxValue, seed.Stream, doubleRounds); var blockBuffer = new BlockBuffer32 <ChaChaSoftware, UInt64>(core); #endif return(new ChaCha(blockBuffer)); }
private ChaChaIntrinsics(ChaChaAvx2 avx2) { _software = null !; _sse2 = null !; _avx2 = avx2; }
private ChaChaIntrinsics(ChaChaSse2 sse2) { _software = null !; _avx2 = null !; _sse2 = sse2; }
private ChaChaIntrinsics(ChaChaSoftware software) { _sse2 = null !; _avx2 = null !; _software = software; }
public void BlockLength() { var rng = ChaChaSoftware.Create(new UInt32[] { 0, 0, 1, 0, 2, 0, 3, 0 }, UInt64.MaxValue, 0, 4); Assert.Equal(ChaCha.BufferLength, rng.BlockLength); }