Example #1
0
        public static async Task <BigInteger> GenerateAsync(BigInteger maxExclusive, IRandomProvider randomProvider)
        {
            if (randomProvider == null)
            {
                throw new ArgumentNullException(nameof(randomProvider));
            }
            if (maxExclusive == BigIntegerHelpers.Zero)
            {
                throw new ArgumentOutOfRangeException(nameof(maxExclusive), "Max exclusive must be above 0.");
            }

            if (maxExclusive == BigIntegerHelpers.One)
            {
                return(BigInteger.Zero);
            }

            if (maxExclusive < new BigInteger(int.MaxValue))
            {
                return(new BigInteger(randomProvider.NextInt((int)maxExclusive)));
            }

            var        bytes  = maxExclusive.ToByteArray();
            BigInteger result = 0;

            await Task.Run(() =>
            {
                do
                {
                    randomProvider.NextBytes(bytes);
                    if (bytes.All(v => v == 0))
                    {
                        throw new InvalidOperationException("Zero buffer returned by random provider.");
                    }

                    bytes[bytes.Length - 1] &= 0x7F;
                    result = new BigInteger(bytes);
                } while (result >= maxExclusive || result.Equals(BigIntegerHelpers.One) ||
                         result.Equals(BigIntegerHelpers.Zero));
            });

            return(result);
        }
Example #2
0
        public static async Task <BigInteger> GeneratePrime(uint bitLength, IRandomProvider randomProvider, IPrimalityTest primalityTest)
        {
            if (randomProvider == null)
            {
                throw new ArgumentNullException(nameof(randomProvider));
            }
            if (bitLength < 8)
            {
                throw new ArgumentOutOfRangeException(nameof(bitLength), "Bit length must be at least of length 8.");
            }

            var bytes = bitLength / 8;

            var randomNumberBytes = new byte[bytes];

            randomProvider.NextBytes(randomNumberBytes);

            var result = new BigInteger(randomNumberBytes);

            if (result.Sign < 0)
            {
                result = BigInteger.Negate(result);
            }

            if (result.IsEven)
            {
                result = result + 1;
            }

            while (!await primalityTest.TestAsync(result))
            {
                result = result + 2;
            }

            return(result);
        }