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); }
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); }
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); }
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)); }