BigIntegers.cs 3.0 KB

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