Exemple #1
0
        private static BigInteger CalculatePrimitiveRoot(BigInteger p)
        {
            // Check if p is prime or not
            if (!PrimeHelper.IsProbablePrime(p))
            {
                throw new ArgumentException($"Parameter {nameof(p)} must be a prime number.", nameof(p));
            }

            BigInteger phi = p - 1;             // The Euler Totient function phi of a prime number p is p-1
            IEnumerable <BigInteger> primeFactors = PrimeHelper.GetPrimeFactorization(phi).Distinct();
            List <BigInteger>        powersToTry  = primeFactors.Select(factor => phi / factor).ToList();

            for (int r = 2; r <= phi; r++)                                 // Check for every number from 2 to phi
            {
                if (powersToTry.All(n => BigInteger.ModPow(r, n, p) != 1)) // If there was no n such that r^n ≡ 1 (mod p)
                {
                    return(r);                                             // We found our primitive root
                }
            }

            throw new Exception($"No primitive root found for prime {p}!");             // If no primitive root found
        }