Ejemplo n.º 1
0
        public Curve GenerateMontgomeryCurve(BigInteger mod, out BigInteger gcd)
        {
            gcd = 0;
            BigInteger     u          = 0;
            BigInteger     v          = 0;
            BigInteger     x          = 0;
            BigInteger     z          = 0;
            BigInteger     T1         = 0;
            BigInteger     sigma      = 0;
            ModularInverse modInverse = new ModularInverse();

            while (gcd == 0)
            {
                sigma = _rnd.Next(7, int.MaxValue);
                u     = sigma * sigma - 5;
                v     = 4 * sigma;
                x     = u * u * u;
                z     = v * v * v;

                T1 = modInverse.Inverse(4 * u * u * u * v, mod, out gcd);

                if (gcd != 1 && gcd != 0)
                {
                    return(new Curve(0, 0, 0, new ProjectivePoint(0, 0, 0)));
                }
            }
            var T2 = (v - u);
            var a  = T2 * T2 * T2 * (3 * u + v) * T1 - 2;

            return(new Curve(a % mod, 0, mod, new ProjectivePoint(x % mod, 0, z % mod)));
        }
Ejemplo n.º 2
0
        public Polynomial Rem(Polynomial firstArg, Polynomial secondArg)
        {
            if (secondArg.Deg == -1)
            {
                throw new DivideByZeroException();
            }
            if (firstArg.Deg < secondArg.Deg)
            {
                return(new Polynomial(firstArg.Coefficients));
            }

            var firstDeg  = firstArg.Deg;
            var secondDeg = secondArg.Deg;
            var newDeg    = firstDeg - secondDeg;
            var result    = new BigInteger[newDeg + 1];
            var reminder  = (BigInteger[])firstArg.Coefficients.Clone();



            BigInteger firstLc;
            BigInteger secondLc = secondArg[secondDeg];

            if (Mod < 2)
            {
                if (secondLc != 1)
                {
                    throw new InvalidOperationException();
                }
            }
            else
            {
                var inverse = new ModularInverse();
                secondLc = inverse.Inverse(secondLc, Mod);
            }



            for (int i = 0; i <= newDeg; i++)
            {
                firstLc            = reminder[firstDeg - i];
                result[newDeg - i] = (firstLc * secondLc);
                for (int j = 0; j <= secondDeg; j++)
                {
                    reminder[firstDeg - secondDeg + j - i] =
                        (reminder[firstDeg - secondDeg + j - i] + (-(result[newDeg - i] * secondArg[j])));
                }
            }
            return(new Polynomial(reminder, Mod));
        }
Ejemplo n.º 3
0
        public Polynomial Normalize(Polynomial poly)
        {
            if (Mod == -1)
            {
                throw new NotImplementedException();
            }
            var coefficient = poly[poly.Deg];

            if (coefficient == 1)
            {
                return(poly);
            }
            var inverse = new ModularInverse();

            coefficient = inverse.Inverse(coefficient, Mod);
            var newPoly = new BigInteger[poly.Deg + 1];

            for (int i = 0; i <= poly.Deg; i++)
            {
                newPoly[i] = poly[i] * coefficient;
            }
            return(new Polynomial(newPoly, Mod));
        }
Ejemplo n.º 4
0
        void Roots(Polynomial polynomial, long mod, List <long> roots)
        {
            if (polynomial.Deg < 1)
            {
                return;
            }
            if (polynomial.Deg == 2)
            {
                if (mod % 2 == 0)
                {
                    for (long i = 0; i < mod; i++)
                    {
                        if (polynomial.Value(i) % mod == 0)
                        {
                            roots.Add(i);
                        }
                    }
                }
                else
                {
                    var a = polynomial[2];
                    var b = polynomial[1];
                    var c = polynomial[0];

                    var sqrt    = new ModularSqrt();
                    var inverse = new ModularInverse();
                    var inv2A   = inverse.Inverse(2 * a, mod);

                    var tmp  = inv2A * b;
                    var root = sqrt.Sqrt(tmp * tmp - inverse.Inverse(a, mod) * c, mod);
                    roots.Add((long)((-tmp + root) % mod));
                    roots.Add((long)((-tmp - root) % mod));
                }
                return;
            }
            if (polynomial.Deg == 1)
            {
                var lc = (polynomial[1] + mod) % mod;
                if (lc == 1)
                {
                    roots.Add((long)(-polynomial[0]));
                }
                else if (lc == mod - 1)
                {
                    roots.Add((long)(polynomial[0]));
                }
                else
                {
                    var inverse = new ModularInverse();

                    roots.Add((long)(-polynomial[0] * inverse.Inverse(polynomial[1], mod)));
                }
                return;
            }
            var polyMath = new PolynomialMath(mod);
            var arr      = new BigInteger[2];

            arr[0] = _random.Next() % mod;
            arr[1] = 1;
            var h = new Polynomial(arr);

            h    = polyMath.ModPow(h, (mod - 1) / 2, polynomial);
            h[0] = h[0] - 1;
            var gcd = new PolynomialGcd();
            var g   = gcd.Calculate(polynomial, h, mod);

            while (g.Deg == 0 || g == h)
            {
                arr[0] = _random.Next() % mod;
                h      = new Polynomial(arr);
                h      = polyMath.ModPow(h, (mod - 1) / 2, polynomial);
                h[0]  -= 1;
                g      = gcd.Calculate(polynomial, h, mod);
            }
            Roots(g, mod, roots);
            Roots(polyMath.Div(polynomial, g), mod, roots);
        }
Ejemplo n.º 5
0
Archivo: Siqs.cs Proyecto: zzfeed/GNFS
        private List <SievePolynomial> GeneratePolynomials(BigInteger n)
        {
            var        result        = new List <SievePolynomial>();
            var        sqrt          = new IntegerSquareRoot();
            var        sizeBound     = sqrt.Sqrt(2 * n) / _sieveBound;
            var        primes        = new List <long>();
            BigInteger a             = 1;
            var        aFactorsBound = Math.Exp(BigInteger.Log(sizeBound) / 13);

            var indexes = new HashSet <int>();

            while (a < sizeBound && _polyIndex < _factorBase.Length)
            {
                if (_factorBase[_polyIndex] < aFactorsBound)
                {
                    _polyIndex++;
                    continue;
                }

                indexes.Add(_polyIndex);
                var p = _factorBase[_polyIndex++];
                a *= p;
                primes.Add(p);
            }
            var inv   = new ModularInverse();
            var B     = new BigInteger[primes.Count];
            var Bainv = new Dictionary <long, Dictionary <int, long> >();

            for (int i = 0; i < primes.Count; i++)
            {
                var q     = primes[i];
                var aq    = a / q;
                var gamma = _sqrtN[q] * inv.Inverse(aq, q);
                if (gamma > q / 2)
                {
                    gamma = q - gamma;
                }
                B[i] = aq * gamma;
            }
            var ainv = new Dictionary <long, long>();


            BigInteger b = 0;

            for (int i = 0; i < B.Length; i++)
            {
                b += B[i];
            }


            var firstSln  = new Dictionary <long, long>();
            var secondSln = new Dictionary <long, long>();

            for (int i = 0; i < _factorBase.Length; i++)
            {
                if (indexes.Contains(i))
                {
                    continue;
                }
                var p = _factorBase[i];
                ainv.Add(p, (long)inv.Inverse(a, p));
                Bainv[p] = new Dictionary <int, long>();
                for (int j = 0; j < primes.Count; j++)
                {
                    Bainv[p][j] = (long)(2 * B[j] * ainv[p] % p);
                }
                firstSln[p]  = (long)(ainv[p] * (_sqrtN[p] - b) % p);
                secondSln[p] = (long)(ainv[p] * (-_sqrtN[p] - b) % p);
            }

            if (primes.Count == 0)
            {
                return(null);
            }

            result.Add(new SievePolynomial()
            {
                A = a, B = b, C = (b * b - n) / a, FirstRoot = firstSln, SecondRoot = secondSln, InvA = ainv, MinFactorA = primes[0], MaxFactorA = primes[primes.Count - 1]
            });


            var polyCount = Math.Pow(2, primes.Count - 1) - 1;

            for (int i = 1; i <= polyCount; i++)
            {
                var v = 1;
                for (; (i & (0x1 << (v - 1))) == 0; v++)
                {
                }


                var tmp = (long)Math.Ceiling(i / Math.Pow(2, v));

                if (tmp % 2 == 0)
                {
                    b = b + 2 * B[v];
                }
                else
                {
                    b = b - 2 * B[v];
                }



                firstSln  = new Dictionary <long, long>();
                secondSln = new Dictionary <long, long>();

                for (var k = 0; k < _factorBase.Length; k++)
                {
                    if (indexes.Contains(k))
                    {
                        continue;
                    }
                    var p = _factorBase[k];
                    firstSln[p]  = (long)(ainv[p] * (_sqrtN[p] - b) % p);
                    secondSln[p] = (long)(ainv[p] * (-_sqrtN[p] - b) % p);
                }
                result.Add(new SievePolynomial()
                {
                    A = a, B = b, C = (b * b - n) / a, FirstRoot = firstSln, SecondRoot = secondSln, InvA = ainv, MinFactorA = primes[0], MaxFactorA = primes[primes.Count - 1]
                });
            }
            _polyIndex += 3 - primes.Count;
            return(result);
        }