コード例 #1
0
        public static BigInteger SolveDLP(BigInteger g, BigInteger h, BigInteger p)
        {
            var order = p - 1;

            if (h == 1)
            {
                return(0);
            }
            if (h == g)
            {
                return(1);
            }
            var giantSteps = new Dictionary <BigInteger, BigInteger>();
            var m          = BigIntegerExtension.Sqrt(order) + 1;
            var temp       = BigInteger.ModPow(g, m, p);
            var y          = temp;

            //Console.WriteLine("g = {0}, h = {1}, p = {2}, realOrder = {3}, m = {4}",g, h, p, BigIntegerExtension.FindElementOrder(g, p), m);
            //Console.WriteLine();
            //Console.WriteLine("Table of y = g^(m*i) mod p");
            for (int i = 1; i <= m; i++)
            {
                //babySteps.Add(i, y);

                //Console.WriteLine("y = {0}, k*i = {1}", y, i * m);
                try
                {
                    giantSteps.Add(y, i);
                }
                catch (Exception e)
                {
                    //if (BigIntegerExtension.FindElementOrder(g, p) == order)
                    //    Console.WriteLine("dublicates with generators mod" + p);
                    //babySteps[y] = i;
                }
                y = (y * temp).ModPositive(p);
            }
            temp = (h * g).ModPositive(p);
            for (int j = 1; j <= m; j++)
            {
                //if (babySteps.ContainsValue(temp))
                //    return (m * babySteps[temp] - j).ModPositive(order);

                BigInteger i = -1;
                try
                {
                    i = giantSteps[temp];
                }
                catch (KeyNotFoundException e) { }
                if (i != -1)
                {
                    return((m * i - j).ModPositive(order));
                }
                temp = (temp * g).ModPositive(p);
            }
            return(-1);
        }
コード例 #2
0
        public AffinePoint GetRandomAffinePoint()
        {
            BigIntegerRandom rand = new BigIntegerRandom();
            var        start      = rand.Next(0, P);
            var        x          = start;
            BigInteger t;

            do
            {
                t = (x * (x * x + A) + B).ModPositive(P);
                if (BigIntegerExtension.JacobiSymbol(t, P) != -1)
                {
                    return(new AffinePoint(x, BigIntegerExtension.Sqrt(t).ModPositive(P), this));
                }
                if (x > P - 1)
                {
                    x = -1;
                }
                x++;
            }while (x != start);
            return(GetInfiniteAffinePoint());
        }
コード例 #3
0
        //public static BigInteger SolveDLP(AffinePoint P, AffinePoint Q)
        //{
        //    var order = P.E.HasseTheorem();
        //    var babySteps = new Dictionary<AffinePoint, BigInteger>();
        //    var m = BigIntegerExtension.Sqrt(order) + 1;
        //    AffinePoint babyStep;
        //    for (BigInteger i = 0; i < m; i++)
        //    {
        //        babyStep = (i * P.ToProjectivePoint()).ToAffinePoint();
        //        babySteps.Add(babyStep, i);
        //        Console.WriteLine(babyStep);
        //    }
        //    AffinePoint temp;
        //    ProjectivePoint giantStep = (m * P.ToProjectivePoint());
        //    for (BigInteger j = 0; j < m; j++)
        //    {
        //        temp = (Q.ToProjectivePoint() - j * giantStep).ToAffinePoint();
        //        Console.WriteLine(temp);
        //        BigInteger i = -1;
        //        try
        //        {
        //            i = babySteps[temp];
        //        }
        //        catch (KeyNotFoundException e) { }
        //        if (i != -1)
        //            return BigIntegerExtension.ModPositive(i + j * m, order);
        //    }
        //    return -1;
        //}

        public static BigInteger SolveDLP(ProjectivePoint P, ProjectivePoint Q)
        {
            var         order     = P.E.HasseTheorem();
            var         babySteps = new Dictionary <AffinePoint, BigInteger>();
            var         m         = BigIntegerExtension.Sqrt(order) + 1;
            AffinePoint babyStep;

            for (BigInteger i = 0; i <= m; i++)
            {
                babyStep = (i * P).ToAffinePoint();
                babySteps.Add(babyStep, i);
                //Console.WriteLine(babyStep);
            }
            AffinePoint     temp;
            ProjectivePoint giantStep = (m * P);

            //Console.WriteLine();
            //Console.WriteLine(giantStep.ToAffinePoint());
            //Console.WriteLine();
            for (BigInteger j = 0; j <= m; j++)
            {
                temp = (Q - j * giantStep).ToAffinePoint();
                // Console.WriteLine(temp);
                BigInteger i = -1;
                try
                {
                    i = babySteps[temp];
                }
                catch (KeyNotFoundException e) { }
                if (i != -1)
                {
                    //Console.WriteLine(temp + " dfsd");
                    return(BigIntegerExtension.ModPositive(i + j * m, order));
                }
            }
            //make modification with m/2 and +-iP
            return(-1);
        }
コード例 #4
0
 public BigInteger HasseTheorem()
 {
     return(P + 1 + (BigIntegerExtension.Sqrt(P) + 1));
 }
コード例 #5
0
        ////Функция нахождения порядка кривой в афинных координатах
        //public static BigInteger FindOrder(EllipticCurve E)
        //{
        //    var Z = E.P;
        //    var rand = new Random();
        //    var startPoint = BasePoint.RandomPoint<PointAffine>(E);
        //    // Найдем границы по теореме Хассе
        //    var leftBorder = Z + 1 - 2 * (FieldsOperations.Sqrt(Z));
        //    var rightBorder = Z + 1 + 2 * (FieldsOperations.Sqrt(Z));
        //    for (int c = 0; c < NUMBER_OF_ATTEMPTS; c++)
        //    {
        //        //Сгенерируем точку на кривой и найдем ее порядок
        //        var P = BasePoint.RandomPoint<PointAffine>(E);
        //        var M = E.FindPointOrder(P);
        //        startPoint = P;
        //        if (M == 0)
        //            continue;
        //        int countOfDevided = 0;
        //        var order = BigInteger.Zero;
        //        //Найдем число делителей порядка точки в границах
        //        for (var i = leftBorder; i < rightBorder; )
        //        {
        //            if (i % M == 0)
        //            {
        //                order = i;
        //                i += M;
        //                countOfDevided++;
        //                if (countOfDevided > 1)
        //                    break;
        //            }
        //            else
        //            {
        //                i++;
        //            }
        //        }
        //        //Если оно равно единице, то порядок кривой - делитель порядка точки
        //        if (countOfDevided == 1)
        //        {
        //            E.Order = order;
        //            return order;
        //        }
        //    }
        //    return 0;
        //}

        public static BigInteger FindPointOrder(AffinePoint P)
        {
            var point = P;
            //var rand = new Random();
            var        rand = new BigIntegerRandom();
            BigInteger M    = 0;
            //Создаем список точек
            var A = new List <AffinePoint>();
            var Q = (P.E.P + 1) * point;

            A.Add(new AffinePoint());
            A[0].X = 0;
            A[0].Y = 0;
            A[0].Z = 1;
            A[0].E = P.E;
            A.Add(point);
            var max   = BigInteger.One;
            int count = 0;

            for (; count < P.E.P; count++)
            {
                M = 0;
                // генерерируем число m
                var m = BigIntegerExtension.Sqrt(BigIntegerExtension.Sqrt(P.E.P)) + 1 + rand.Next(0, P.E.P);
                if (m > max)
                {
                    //дозаполняем список
                    for (BigInteger i = 0; i < m - max; i++)
                    {
                        A.Add(point + A[A.Count - 1]);
                    }
                    max = m;
                }
                var  k     = -m - 1;
                int  j     = 0;
                bool flag  = true;
                var  twoMP = (2 * m) * point;
                var  temp  = Q + (k * twoMP);
                k++;
                //вычисляем параметры k и j
                for (; k < m && flag; k++)
                {
                    if (k < 0 && k != -m)
                    {
                        temp = temp - twoMP;
                    }
                    else
                    {
                        temp = temp + twoMP;
                    }

                    for (j = 0; j < A.Count && flag; j++)
                    {
                        if (temp == A[j])
                        {
                            j    = -j;
                            flag = false;
                            break;
                        }
                        if (temp == (-A[j]))
                        {
                            flag = false;
                            break;
                        }
                    }
                }
                k--;
                M = (P.E.P + 1 + 2 * m * k + j);
                if ((M * point) == P.E.GetInfiniteAffinePoint() && M != 0)
                {
                    break;
                }
            }
            if (count == P.E.P)
            {
                return(0);
            }
            // Раскладываем число M ро-методом Полларда
            List <BigInteger> factorsM;

            try
            {
                factorsM = BigIntegerExtension.PollardsAlg(BigInteger.Abs(M));
            }
            catch (Exception)
            {
                return(0);
            }
            // Проверяем простые делители числа M
            for (int i = 0; i < factorsM.Count;)
            {
                BigInteger temp = M / factorsM[i];
                if (M != factorsM[i] && M % factorsM[i] == 0 && (temp * point) == P.E.GetInfiniteAffinePoint())
                {
                    M = temp;
                    i = 0;
                }
                else
                {
                    i++;
                }
            }
            //P.Order = M;
            return(M);
        }