ReversedWindowGenerator.cs 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Prng
  5. {
  6. /// <remarks>
  7. /// Takes bytes generated by an underling RandomGenerator and reverses the order in
  8. /// each small window (of configurable size).
  9. /// <p>
  10. /// Access to internals is synchronized so a single one of these can be shared.
  11. /// </p>
  12. /// </remarks>
  13. public class ReversedWindowGenerator
  14. : IRandomGenerator
  15. {
  16. private readonly IRandomGenerator generator;
  17. private byte[] window;
  18. private int windowCount;
  19. public ReversedWindowGenerator(
  20. IRandomGenerator generator,
  21. int windowSize)
  22. {
  23. if (generator == null)
  24. throw new ArgumentNullException("generator");
  25. if (windowSize < 2)
  26. throw new ArgumentException("Window size must be at least 2", "windowSize");
  27. this.generator = generator;
  28. this.window = new byte[windowSize];
  29. }
  30. /// <summary>Add more seed material to the generator.</summary>
  31. /// <param name="seed">A byte array to be mixed into the generator's state.</param>
  32. public virtual void AddSeedMaterial(
  33. byte[] seed)
  34. {
  35. lock (this)
  36. {
  37. windowCount = 0;
  38. generator.AddSeedMaterial(seed);
  39. }
  40. }
  41. /// <summary>Add more seed material to the generator.</summary>
  42. /// <param name="seed">A long value to be mixed into the generator's state.</param>
  43. public virtual void AddSeedMaterial(
  44. long seed)
  45. {
  46. lock (this)
  47. {
  48. windowCount = 0;
  49. generator.AddSeedMaterial(seed);
  50. }
  51. }
  52. /// <summary>Fill byte array with random values.</summary>
  53. /// <param name="bytes">Array to be filled.</param>
  54. public virtual void NextBytes(
  55. byte[] bytes)
  56. {
  57. doNextBytes(bytes, 0, bytes.Length);
  58. }
  59. /// <summary>Fill byte array with random values.</summary>
  60. /// <param name="bytes">Array to receive bytes.</param>
  61. /// <param name="start">Index to start filling at.</param>
  62. /// <param name="len">Length of segment to fill.</param>
  63. public virtual void NextBytes(
  64. byte[] bytes,
  65. int start,
  66. int len)
  67. {
  68. doNextBytes(bytes, start, len);
  69. }
  70. private void doNextBytes(
  71. byte[] bytes,
  72. int start,
  73. int len)
  74. {
  75. lock (this)
  76. {
  77. int done = 0;
  78. while (done < len)
  79. {
  80. if (windowCount < 1)
  81. {
  82. generator.NextBytes(window, 0, window.Length);
  83. windowCount = window.Length;
  84. }
  85. bytes[start + done++] = window[--windowCount];
  86. }
  87. }
  88. }
  89. }
  90. }
  91. #pragma warning restore
  92. #endif