public static BigInteger Solve(BigInteger a, BigInteger b, BigInteger p)
        {
            BigInteger H = BigMath.Sqrt(p) + 1;

            //c = a^H mod p
            BigInteger c = BigMath.Pow(a, H);

            c = c % p;

            //TODO sorted needed + -> change
            Dictionary <BigInteger, BigInteger> table1 = new Dictionary <BigInteger, BigInteger>();

            for (BigInteger u = 1; u <= H; u++)
            {
                table1.Add(u, BigMath.Pow(c, u) % p);
            }

            Dictionary <BigInteger, BigInteger> table2 = new Dictionary <BigInteger, BigInteger>();

            for (BigInteger v = 0; v <= H; v++)
            {
                table2.Add(v, b * BigMath.Pow(a, v) % p);
                foreach (KeyValuePair <BigInteger, BigInteger> t1 in table1)
                {
                    if (table1[t1.Key] == table2[v])
                    {
                        return((H * t1.Key - v) % (p - 1));
                    }
                }
            }
            return(-1);
        }
Пример #2
0
        public static BigInteger Solve(BigInteger _a, BigInteger _b, BigInteger p)
        {
            BigInteger r = _a, q = _b;
            BigInteger x = 1, a = 0, b = 0;
            BigInteger X = x, A = a, B = b;

            for (int iterator = 1; iterator < p; iterator++)
            {
                RefreshValues(ref x, ref a, ref b, r, q, p);
                RefreshValues(ref X, ref A, ref B, r, q, p); //2i - 2
                RefreshValues(ref X, ref A, ref B, r, q, p);

                if (x == X)
                {
                    BigInteger m = (a - A).Mod(p - 1),  // + +
                               n = (B - b).Mod(p - 1);

                    if (m == 0)
                    {
                        return(-1);
                    }

                    BigInteger gcd = BigMath.GCD_EuclideanExtended(m, p - 1, out BigInteger mu, out BigInteger pu);

                    Console.WriteLine(gcd);
                    BigInteger temp = (mu * n).Mod(p - 1);

                    for (BigInteger w = 0; w <= gcd; w++)
                    {
                        BigInteger result = ((temp + w * (p - 1)) / gcd).Mod(p - 1);
                        if (BigMath.Pow(r, result) % p == q)
                        {
                            return(result);
                        }
                        else if (w % 2 == 0 && BigMath.Pow(-r, result).Mod(p) == q)
                        {
                            return(result);
                        }
                        //if (w % 2 == 0) //sqrt(x^2y) = abs(x^y) = (+-)x^y
                        //{
                        //    result = ((temp + w * (p - 1)) / gcd).Mod(p - 1);
                        //    Console.WriteLine(result);
                        //    if (BigMath.Pow(r, result) % p == q)
                        //    {
                        //        return result;
                        //    }
                        //}
                    }

                    return(-1);
                }
            }

            return(-1);
        }
        //TODO add button on main window
        public static bool CheckResult(BigInteger a, BigInteger b, BigInteger p, BigInteger x)
        {
            if (x < 0)
            {
                return(false);
            }

            bool isSubstitutionCorrect = BigMath.Pow(a, x) % p == b;

            return(isSubstitutionCorrect);
        }
        private void GenerateNumbers(int p_digits, int a_digits, int b_digits, out BigInteger p, out BigInteger a, out BigInteger b)
        {
            do
            {
                p = BigMath.Random(p_digits);
            }while (!IsPGood(p));

            do
            {
                a = BigMath.Random(a_digits);
            }while (!IsAGood(a, p));

            b = BigMath.Random(b_digits, p);
        }
Пример #5
0
        public static BigInteger Solve(BigInteger a, BigInteger b, BigInteger p)
        {
            BigInteger counter = 0;
            BigInteger sum     = 0;

            for (int j = 1; j <= p - 2; j++)
            {
                sum += BigInteger.Pow(b, j) / (BigInteger.Pow(a, j) - 1);
                counter++;
            }

            //sum <= (sum) < sum + counter, because / is about integer division
            for (BigInteger i = 0; i <= counter; i++)
            {
                BigInteger result = (sum + i) % (p - 1);

                if (BigMath.Pow(a, result) % p == b)
                {
                    return(result);
                }
            }

            return(-1);
        }
Пример #6
0
        public static BigInteger Solve(BigInteger a, BigInteger b, BigInteger p)
        {
            //1 find dividers of (р-1)
            Dictionary <BigInteger, int> q_alpha = BigMath.Q_Alpha(p - 1);

            //2 table r
            BigInteger q;

            // get index throught the loop
            BigInteger[][] r = new BigInteger[q_alpha.Count][];
            for (int q_index = 0; q_index < q_alpha.Count; q_index++)
            {
                q          = q_alpha.ElementAt(q_index).Key;
                r[q_index] = new BigInteger[(int)q]; //TODO change
                for (int j = 0; j < q; j++)
                {
                    r[q_index][j] = BigMath.Pow(a, (j * (p - 1) / q)) % p; // r +
                }
            }
            //3 system х
            Dictionary <BigInteger, BigInteger> q_x = new Dictionary <BigInteger, BigInteger>();

            for (int q_index = 0; q_index < q_alpha.Count; q_index++)
            {
                q = q_alpha.ElementAt(q_index).Key;
                BigInteger[] xi = new BigInteger[q_alpha[q]];
                BigInteger   temp; // b^power OR b*a^power

                for (int al = 0; al < q_alpha[q]; al++)
                {
                    if (al == 0)
                    {
                        temp = BigMath.Pow(b, (p - 1) / q) % p;
                        for (int j = 0; j < q; j++)
                        {
                            if (r[q_index][j] == temp) //search in table r
                            {
                                xi[al] = j;            //x0 +
                            }
                        }
                    }
                    else
                    {
                        BigInteger power = xi[0];
                        for (int i = 1; i < al; i++)
                        {
                            power += xi[i] * (int)BigMath.Pow(q, i);
                        }

                        if (power == 1)
                        {
                            temp = b / a;
                        }
                        else
                        {
                            temp = b * BigMath.Pow(a, -power);//a^(-x0-x1..)
                        }

                        temp = BigMath.Pow(temp, (p - 1) / (BigMath.Pow(q, al + 1))); //(b*a)^(...)
                        temp = temp % p;                                              //(mod p)
                        for (int j = 0; j < q; j++)
                        {
                            if (r[q_index][j] == temp) //search in table r
                            {
                                xi[al] = j;            //xi +
                            }
                        }
                    }
                }
                BigInteger x = xi[0];
                for (int i = 1; i < xi.Length; i++)
                {
                    x += xi[i] * BigMath.Pow(q, i);
                }

                x = x % (BigMath.Pow(q, q_alpha[q]));
                q_x.Add(q, x); // x, q +
            }

            //4 solve system х by Chinese remainder Th
            BigInteger X  = 0;
            BigInteger M0 = 1;

            BigInteger[] Mi = new BigInteger[q_x.Count];
            BigInteger[] Yi = new BigInteger[q_x.Count];
            BigInteger[] mi = new BigInteger[q_x.Count];

            int counter = 0;

            foreach (var qx in q_x)
            {
                mi[counter] = BigMath.Pow(qx.Key, q_alpha[qx.Key]);
                M0         *= mi[counter];
                counter++;
            }

            counter = 0;
            foreach (var qx in q_x)
            {
                Mi[counter] = M0 / mi[counter];
                counter++;
            }

            counter = 0;
            foreach (var qx in q_x)
            {
                for (int i = 1; i < mi[counter]; i++)
                {
                    if ((Mi[counter] * i - qx.Value) % mi[counter] == 0)
                    {
                        Yi[counter] = i;
                        break;
                    }
                }
                X += Mi[counter] * Yi[counter];
                counter++;
            }
            return(X);
        }
 private bool IsPGood(BigInteger p) //needs to be prime
 {
     return(BigMath.IsPrime(p));
 }
 private bool IsAGood(BigInteger a, BigInteger p)
 {
     return(a > 1 && BigMath.OrderOfMagnitude(a) <= BigMath.OrderOfMagnitude(p - 1));
 }