Esempio n. 1
0
        public void AddTest()
        {
            foreach (var prime in _primes)
            {
                var firstPoly  = GeneratePoly(20, prime);
                var secondPoly = GeneratePoly(30, prime);


                var polyMath = new PolynomialMath(prime);

                Polynomial res;
                res = polyMath.Add(firstPoly, secondPoly);

                var checkPoly = polyMath.Sub(res, secondPoly);

                for (int i = 0; i <= firstPoly.Deg; i++)
                {
                    if ((firstPoly[i] + prime * prime) % prime != (checkPoly[i] + prime * prime) % prime)
                    {
                        throw new Exception();
                    }
                }
            }
        }
Esempio n. 2
0
        public Polynomial Sqrt(Polynomial sqr, Polynomial mod, Polynomial modDerivative, BigInteger sqrtNorm)
        {
            BigInteger max = 0;

            for (int i = 0; i <= sqr.Deg; i++)
            {
                if (BigInteger.Abs(sqr[i]) > max)
                {
                    max = BigInteger.Abs(sqr[i]);
                }
            }
            var        nextPrime     = new NextPrime();
            var        bound         = max * 10;
            var        primes        = new List <BigInteger>();
            var        sieve         = new EratosthenesSieve();
            var        primesToCheck = sieve.GetPrimes(100000000, 110000000);
            BigInteger bigMod        = 1;

            foreach (var primeToCheck in primesToCheck)
            {
                var irreducibilityTest = new IrreducibilityTest();
                if (!irreducibilityTest.IsIrreducible(mod, primeToCheck))
                {
                    continue;
                }
                bigMod *= primeToCheck;
                primes.Add(primeToCheck);
                if (bigMod > bound)
                {
                    break;
                }
            }
            var prime = 2 * primes[primes.Count - 1];

            while (bigMod < bound)
            {
                prime = nextPrime.GetNext(prime);
                var irreducibilityTest = new IrreducibilityTest();
                while (!irreducibilityTest.IsIrreducible(mod, prime))
                {
                    prime = nextPrime.GetNext(prime + 1);
                }
                bigMod *= prime;
                primes.Add(prime);
            }
            var sqrts = new List <Polynomial>();

            foreach (var fieldChar in primes)
            {
                var        polyMath = new PolynomialMath(fieldChar);
                var        four     = new Polynomial(new BigInteger[] { 4 });
                Polynomial b;
                var        isSqr = false;
                for (int i = 0; true; i++)
                {
                    b = new Polynomial(new BigInteger[] { i });
                    var tmp = polyMath.ModPow(polyMath.Sub(polyMath.Mul(b, b), polyMath.Mul(four, sqr)),
                                              (BigInteger.Pow(fieldChar, mod.Deg) - 1) / 2, mod);
                    isSqr = (tmp[0] == 1 || tmp[0] == -(fieldChar - 1)) && (tmp.Deg == 0);
                    if (!isSqr)
                    {
                        break;
                    }
                }
                var gfMath      = new FiniteFieldMath(mod, fieldChar);
                var modPoly     = new PolynomialOverFiniteField(new Polynomial[] { sqr, b, new Polynomial(new BigInteger[] { 1 }) });
                var y           = new PolynomialOverFiniteField(new Polynomial[] { new Polynomial(new BigInteger[] { 0 }), new Polynomial(new BigInteger[] { 1 }) });
                var sqrt        = gfMath.ModPow(y, (BigInteger.Pow(fieldChar, mod.Deg) + 1) / 2, modPoly)[0];
                var sqrtNormMod = sqrtNorm * polyMath.ModPow(modDerivative, (BigInteger.Pow(fieldChar, mod.Deg) - 1) / (fieldChar - 1), mod)[0];
                var norm        = polyMath.ModPow(sqrt, (BigInteger.Pow(fieldChar, mod.Deg) - 1) / (fieldChar - 1), mod)[0];
                sqrtNormMod %= fieldChar;
                if (sqrtNormMod < 0)
                {
                    sqrtNormMod = sqrtNormMod + fieldChar;
                }
                if (norm < 0)
                {
                    norm = norm + fieldChar;
                }
                if (norm != sqrtNormMod)
                {
                    sqrt = polyMath.ConstMul(-1, sqrt);
                }
                sqrts.Add(sqrt);
            }
            BigInteger[] result = new BigInteger[mod.Deg];
            var          crt    = new GarnerCrt();

            for (int i = 0; i < mod.Deg; i++)
            {
                var coefficients = new List <BigInteger>();
                for (int j = 0; j < primes.Count; j++)
                {
                    coefficients.Add(sqrts[j][i]);
                }
                result[i] = crt.Calculate(coefficients, primes);
            }
            var resultPoly = new Polynomial(result);

            for (int i = 0; i <= resultPoly.Deg; i++)
            {
                var coeff = BigInteger.Abs(resultPoly[i]);
                if (coeff > max)
                {
                    if (resultPoly[i] < 0)
                    {
                        resultPoly[i] += bigMod;
                    }
                    else
                    {
                        resultPoly[i] -= bigMod;
                    }
                }
            }
            return(resultPoly);
        }