#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) #pragma warning disable using System; namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Prng { /// /// Takes bytes generated by an underling RandomGenerator and reverses the order in /// each small window (of configurable size). ///

/// Access to internals is synchronized so a single one of these can be shared. ///

///
public class ReversedWindowGenerator : IRandomGenerator { private readonly IRandomGenerator generator; private byte[] window; private int windowCount; public ReversedWindowGenerator( IRandomGenerator generator, int windowSize) { if (generator == null) throw new ArgumentNullException("generator"); if (windowSize < 2) throw new ArgumentException("Window size must be at least 2", "windowSize"); this.generator = generator; this.window = new byte[windowSize]; } /// Add more seed material to the generator. /// A byte array to be mixed into the generator's state. public virtual void AddSeedMaterial( byte[] seed) { lock (this) { windowCount = 0; generator.AddSeedMaterial(seed); } } /// Add more seed material to the generator. /// A long value to be mixed into the generator's state. public virtual void AddSeedMaterial( long seed) { lock (this) { windowCount = 0; generator.AddSeedMaterial(seed); } } /// Fill byte array with random values. /// Array to be filled. public virtual void NextBytes( byte[] bytes) { doNextBytes(bytes, 0, bytes.Length); } /// Fill byte array with random values. /// Array to receive bytes. /// Index to start filling at. /// Length of segment to fill. public virtual void NextBytes( byte[] bytes, int start, int len) { doNextBytes(bytes, start, len); } private void doNextBytes( byte[] bytes, int start, int len) { lock (this) { int done = 0; while (done < len) { if (windowCount < 1) { generator.NextBytes(window, 0, window.Length); windowCount = window.Length; } bytes[start + done++] = window[--windowCount]; } } } } } #pragma warning restore #endif