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 }