using System; using System.Globalization; using System.Numerics; namespace Amazon.Extensions.CognitoAuthentication.Util { internal static class BigIntegerExtensions { /// /// Turn a hex string into a BigInteger assuming it's an unsigned, little endian hex string. /// /// /// public static BigInteger FromUnsignedLittleEndianHex(string hex) => BigInteger.Parse("0" + hex, NumberStyles.HexNumber); /// /// If the sign of the remainder of self % other is < 0 then add other so that the answer is always positive. /// /// /// /// public static BigInteger TrueMod(this BigInteger self, BigInteger other) { var remainder = self % other; return remainder.Sign >= 0 ? remainder : remainder + other; } /// /// Return a big endian byte array that's equivalent to this BigInteger. /// /// /// public static byte[] ToBigEndianByteArray(this BigInteger self) => self.ToByteArray().Reverse(); /// /// Turn a byte array into a BigInteger, assuming it's an unsigned big endian integer. /// /// /// public static BigInteger FromUnsignedBigEndian(byte[] bytes) { var reverse = bytes.Reverse(); //Need to end with a zero byte to force positive var ensurePos = new byte[reverse.Length + 1]; Array.Copy(reverse, ensurePos, reverse.Length); return new BigInteger(ensurePos); } private static T[] Reverse(this T[] array) { var reverse = new T[array.Length]; for(int rev = array.Length - 1, index = 0; rev >= 0; rev--, index++) { reverse[index] = array[rev]; } return reverse; } } }