BigIntegers.cs 3.1 KB

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