/// <summary> /// Случайная точка на Данной кривой. /// </summary> /// <returns></returns> BigInteger[] GetPoint() { BigInteger rnd = Extension.Random(1, P); while (Extension.Lezhandr(BigInteger.Remainder((rnd * rnd * rnd + A * rnd + B), P), P) != 1) { rnd = Extension.Random(1, P); } BigInteger xcoord = BigInteger.Remainder((rnd * rnd * rnd + A * rnd + B), P); // Правая часть уравнения кривой return(new BigInteger[] { rnd, Extension.SquareRootModPrime(xcoord, P) }); }
/// <summary> /// Случайный квадратичный невычет по модулю тестируемого числа /// </summary> /// <returns>Случайный квадратичный невычет</returns> private static BigInteger GetNonQuadr() { if (Number % 3 == 1) { BigInteger g = Extension.Random(1, Number); while ((Extension.Lezhandr(g, Number) != -1) || (BigInteger.ModPow(g, (Number - 1) / 3, Number) == 1)) { g = Extension.Random(1, Number); } return(g); } else { BigInteger g = Extension.Random(1, Number); while (Extension.Lezhandr(g, Number) != -1) { g = Extension.Random(1, Number); } return(g); } }
void Roots(Polynom g) { if (g.Degree <= 2) { // Решение уравнений вида ax^2+bx+c = 0 mod p a,b,c>=0 if (g.coefficients[0].Degree == 1) // bx + c = 0 { if (g.coefficients.Count == 1) // bx = 0 { roots.Add(0); return; } else // bx + c = 0 { BigInteger b = g.coefficients[0].Coefficient; BigInteger c = g.coefficients[1].Coefficient; BigInteger x = BigInteger.Remainder(BigInteger.Negate(c) * Extension.Inverse(b, g.Fp), g.Fp); while (x < 0) { x += g.Fp; } roots.Add(x); return; } // ошибка } else // ax^2 + bx + c = 0 { if (g.coefficients[1].Degree == 0) // ax^2 + c = 0 { BigInteger a = g.coefficients[0].Coefficient; BigInteger c = g.coefficients[1].Coefficient; BigInteger ac = BigInteger.Remainder(BigInteger.Negate(c) * Extension.Inverse(a, g.Fp), g.Fp); BigInteger r = Extension.SquareRootModPrime(ac, g.Fp); roots.Add(r); // не проверенно roots.Add(g.Fp - r); return; } else // ax^2 + bx = 0 && ax^2 = 0 && ax^2 + bx + c = 0 { if (g.coefficients.Count == 1)// ax ^ 2 = 0 { roots.Add(0); return; } else // ax^2 + bx = 0 && ax^2 + bx + c = 0 { if (g.coefficients.Count == 2) // ax^2 + bx = 0 { roots.Add(0); Polynom div = null; Polynom.Remainder(g, Parse("+x", this.Fp), out div); Roots(div); } else // ax^2 + bx + c = 0 { BigInteger a = g.coefficients[0].Coefficient; BigInteger b = g.coefficients[1].Coefficient; BigInteger c = g.coefficients[2].Coefficient; BigInteger D = Extension.SquareRootModPrime(BigInteger.Remainder(b * b - 4 * a * c, g.Fp), g.Fp); BigInteger x1 = BigInteger.Remainder((BigInteger.Negate(b) - D) * BigInteger.Remainder(Extension.Inverse(2 * a, g.Fp), g.Fp), g.Fp); BigInteger x2 = BigInteger.Remainder((BigInteger.Negate(b) + D) * BigInteger.Remainder(Extension.Inverse(2 * a, g.Fp), g.Fp), g.Fp); while (x1 < 0) { x1 += g.Fp; } while (x2 < 0) { x2 += g.Fp; } roots.Add(x1); roots.Add(x2); } } } } } else { Polynom one = Parse("+1", g.Fp); Polynom h = one; while (h.Degree == 0 || h.Eguals(g)) { BigInteger a = Extension.Random(1, g.Fp); Polynom s = ModPow(Parse(string.Format("+x-{0}", a), g.Fp), (g.Fp - 1) / 2, g); h = Polynom.GreatCommonDivisor(s - one, g); } Polynom div = null; Remainder(g, h, out div); Roots(h); Roots(div); } }