BigIntegers.cs 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. using System;
  3. using Org.BouncyCastle.Math;
  4. using Org.BouncyCastle.Security;
  5. namespace Org.BouncyCastle.Utilities
  6. {
  7. /**
  8. * BigInteger utilities.
  9. */
  10. public abstract class BigIntegers
  11. {
  12. private const int MaxIterations = 1000;
  13. /**
  14. * Return the passed in value as an unsigned byte array.
  15. *
  16. * @param value value to be converted.
  17. * @return a byte array without a leading zero byte if present in the signed encoding.
  18. */
  19. public static byte[] AsUnsignedByteArray(
  20. BigInteger n)
  21. {
  22. return n.ToByteArrayUnsigned();
  23. }
  24. /**
  25. * Return the passed in value as an unsigned byte array of specified length, zero-extended as necessary.
  26. *
  27. * @param length desired length of result array.
  28. * @param n value to be converted.
  29. * @return a byte array of specified length, with leading zeroes as necessary given the size of n.
  30. */
  31. public static byte[] AsUnsignedByteArray(int length, BigInteger n)
  32. {
  33. byte[] bytes = n.ToByteArrayUnsigned();
  34. if (bytes.Length > length)
  35. throw new ArgumentException("standard length exceeded", "n");
  36. if (bytes.Length == length)
  37. return bytes;
  38. byte[] tmp = new byte[length];
  39. Array.Copy(bytes, 0, tmp, tmp.Length - bytes.Length, bytes.Length);
  40. return tmp;
  41. }
  42. /**
  43. * Return a random BigInteger not less than 'min' and not greater than 'max'
  44. *
  45. * @param min the least value that may be generated
  46. * @param max the greatest value that may be generated
  47. * @param random the source of randomness
  48. * @return a random BigInteger value in the range [min,max]
  49. */
  50. public static BigInteger CreateRandomInRange(
  51. BigInteger min,
  52. BigInteger max,
  53. // TODO Should have been just Random class
  54. SecureRandom random)
  55. {
  56. int cmp = min.CompareTo(max);
  57. if (cmp >= 0)
  58. {
  59. if (cmp > 0)
  60. throw new ArgumentException("'min' may not be greater than 'max'");
  61. return min;
  62. }
  63. if (min.BitLength > max.BitLength / 2)
  64. {
  65. return CreateRandomInRange(BigInteger.Zero, max.Subtract(min), random).Add(min);
  66. }
  67. for (int i = 0; i < MaxIterations; ++i)
  68. {
  69. BigInteger x = new BigInteger(max.BitLength, random);
  70. if (x.CompareTo(min) >= 0 && x.CompareTo(max) <= 0)
  71. {
  72. return x;
  73. }
  74. }
  75. // fall back to a faster (restricted) method
  76. return new BigInteger(max.Subtract(min).BitLength - 1, random).Add(min);
  77. }
  78. }
  79. }
  80. #endif