示例#1
0
        public ProjectivePoint MontgomeryMul(ProjectivePoint point, ulong power, Curve curve)
        {
            if (power == 1)
            {
                return(point);
            }
            if (power == 2)
            {
                return(Double(point, curve));
            }
            var binary = Convert.ToString((long)power, 2);
            var U      = point;
            var T      = Double(point, curve);

            for (int i = 1; i <= binary.Length - 1; i++)
            {
                if (binary[i] == '1')
                {
                    U = Add(T, U, point, curve);
                    T = Double(T, curve);
                }
                else
                {
                    T = Add(U, T, point, curve);
                    U = Double(U, curve);
                }
            }
            return(U);
        }
示例#2
0
        public ProjectivePoint Add(ProjectivePoint point1, ProjectivePoint point2, ProjectivePoint point3, Curve curve)
        {
            var T1   = (point1.X * point2.X - point1.Z * point2.Z) % curve.Mod;
            var T2   = (point1.X * point2.Z - point1.Z * point2.X) % curve.Mod;
            var newX = (point3.Z * T1 * T1);
            var newZ = (point3.X * T2 * T2);

            return(new ProjectivePoint(newX % curve.Mod, 0, newZ % curve.Mod));
        }
示例#3
0
        public ProjectivePoint Double(ProjectivePoint point, Curve curve)
        {
            var XX   = point.X * point.X;
            var ZZ   = point.Z * point.Z;
            var XZ   = point.X * point.Z;
            var newX = (XX - ZZ) % curve.Mod;

            newX = newX * newX;
            var tmp  = (XX + curve.A * XZ + ZZ) % curve.Mod;
            var newZ = 4 * XZ * tmp;

            return(new ProjectivePoint(newX % curve.Mod, 0, newZ % curve.Mod));
        }
示例#4
0
文件: Ecm.cs 项目: zzfeed/GNFS
        public BigInteger Calculate(Curve curve, ulong b1, ulong b2, ulong b3)
        {
            var        arithmetic   = new MontgomeryArithmetic();
            var        sieve        = new EratosthenesSieve();
            var        primeManager = new PrimeManager();
            var        point        = curve.Point;
            ulong      prime        = 2;
            var        mod          = curve.Mod;
            BigInteger product      = 1;

            while (prime < b1)
            {
                point   = arithmetic.Double(point, curve);
                prime   = prime * 2;
                product = (point.Z * product) % mod;
            }


            var gcd = BigInteger.GreatestCommonDivisor(product, mod);

            if (gcd > 1)
            {
                return(gcd);
            }



            ulong[] primes;
            ulong   upPrimeLimit  = 1000000;
            ulong   lowPrimeLimit = 3;
            ulong   sievestep     = 10000000;

            if (b1 < upPrimeLimit)
            {
                upPrimeLimit = b1;
            }
            ulong partCount = b1 / sievestep;



            for (ulong j = 0; j <= partCount; j++)
            {
                primes = sieve.GetPrimes(lowPrimeLimit, upPrimeLimit);
                for (int i = 0; i < primes.Length; i++)
                {
                    var p = primes[i];
                    prime = p;
                    while (prime < b1)
                    {
                        point   = arithmetic.MontgomeryMul(point, p, curve);
                        prime   = prime * p;
                        product = (point.Z * product) % mod;
                    }
                    gcd = BigInteger.GreatestCommonDivisor(product, mod);
                    if (gcd > 1)
                    {
                        return(gcd);
                    }
                }
                lowPrimeLimit = upPrimeLimit;
                upPrimeLimit += sievestep;
            }


            if (b2 % 2 == 0)
            {
                b2--;
            }


            ulong precomputedDataSize = 1000;
            var   precomputedData     = new ProjectivePoint[precomputedDataSize];

            precomputedData[0] = arithmetic.Double(point, curve);
            precomputedData[1] = arithmetic.Double(precomputedData[0], curve);
            for (ulong i = 2; i < precomputedDataSize; i++)
            {
                precomputedData[i] = arithmetic.Add(precomputedData[i - 1], precomputedData[0], precomputedData[i - 2], curve);
            }

            if (b2 <= 2 * precomputedDataSize)
            {
                b2 = precomputedDataSize + 2;
            }

            product = 1;
            var R = arithmetic.MontgomeryMul(point, b2, curve);
            var T = arithmetic.MontgomeryMul(point, b2 - 2 * precomputedDataSize, curve);

            primeManager.Init(b2 + 1);
            for (ulong i = b2; i < b3; i = i + 2 * precomputedDataSize)
            {
                for (ulong j = 0; j < precomputedDataSize; j++)
                {
                    prime = primeManager.NextPrime();
                    var delta = (prime - i) / 2;
                    if (delta >= (ulong)precomputedData.Length)
                    {
                        break;
                    }
                    product = (product * (R.X * precomputedData[delta - 1].Z - R.Z * precomputedData[delta
                                                                                                     - 1].X)) % curve.Mod;
                }



                gcd = BigInteger.GreatestCommonDivisor(curve.Mod, product);
                if (gcd > 1)
                {
                    return(gcd);
                }
                var temp = T;
                T = R;
                R = arithmetic.Add(R, precomputedData[precomputedDataSize - 1], temp, curve);
            }
            return(1);
        }