/// <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) }); }
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); } }
/// <summary> /// Явные Параметры кривых полученных комплексным умножением /// </summary> /// <param name="D">Фундаментальный дискриминант</param> /// <returns></returns> private static List <BigInteger[]> GetClearCurveComplexMultiply(int D) { Task <BigInteger> t1 = Task <BigInteger> .Factory.StartNew(delegate() { return(GetNonQuadr()); }); List <BigInteger[]> paramCurve = new List <BigInteger[]>(); switch (D) { case (-7): BigInteger r = 125; BigInteger s = 189; paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * r * BigInteger.ModPow(s, 3, Number), Number), BigInteger.Remainder(2 * r * BigInteger.ModPow(s, 5, Number), Number) }); t1.Wait(); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * r * BigInteger.ModPow(s, 3, Number) * BigInteger.ModPow(t1.Result, 2, Number), Number), BigInteger.Remainder(2 * r * BigInteger.ModPow(s, 5, Number) * BigInteger.ModPow(t1.Result, 3, Number), Number) }); break; case (-8): BigInteger r0 = 125; BigInteger s0 = 98; paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * r0 * BigInteger.ModPow(s0, 3, Number), Number), BigInteger.Remainder(2 * r0 * BigInteger.ModPow(s0, 5, Number), Number) }); t1.Wait(); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * r0 * BigInteger.ModPow(s0, 3, Number) * BigInteger.ModPow(t1.Result, 2, Number), Number), BigInteger.Remainder(2 * r0 * BigInteger.ModPow(s0, 5, Number) * BigInteger.ModPow(t1.Result, 3, Number), Number) }); break; case (-11): BigInteger r1 = 512; BigInteger s1 = 539; paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * r1 * BigInteger.ModPow(s1, 3, Number), Number), BigInteger.Remainder(2 * r1 * BigInteger.ModPow(s1, 5, Number), Number) }); t1.Wait(); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * r1 * BigInteger.ModPow(s1, 3, Number) * BigInteger.ModPow(t1.Result, 2, Number), Number), BigInteger.Remainder(2 * r1 * BigInteger.ModPow(s1, 5, Number) * BigInteger.ModPow(t1.Result, 3, Number), Number) }); break; case (-19): BigInteger r2 = 512; BigInteger s2 = 512; paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * r2 * BigInteger.ModPow(s2, 3, Number), Number), BigInteger.Remainder(2 * r2 * BigInteger.ModPow(s2, 5, Number), Number) }); t1.Wait(); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * r2 * BigInteger.ModPow(s2, 3, Number) * BigInteger.ModPow(t1.Result, 2, Number), Number), BigInteger.Remainder(2 * r2 * BigInteger.ModPow(s2, 5, Number) * BigInteger.ModPow(t1.Result, 3, Number), Number) }); break; case (-43): BigInteger r3 = 512000; BigInteger s3 = 512001; paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * r3 * BigInteger.ModPow(s3, 3, Number), Number), BigInteger.Remainder(2 * r3 * BigInteger.ModPow(s3, 5, Number), Number) }); t1.Wait(); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * r3 * BigInteger.ModPow(s3, 3, Number) * BigInteger.ModPow(t1.Result, 2, Number), Number), BigInteger.Remainder(2 * r3 * BigInteger.ModPow(s3, 5, Number) * BigInteger.ModPow(t1.Result, 3, Number), Number) }); break; case (-67): BigInteger r4 = 85184000; BigInteger s4 = 85184001; paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * r4 * BigInteger.ModPow(s4, 3, Number), Number), BigInteger.Remainder(2 * r4 * BigInteger.ModPow(s4, 5, Number), Number) }); t1.Wait(); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * r4 * BigInteger.ModPow(s4, 3, Number) * BigInteger.ModPow(t1.Result, 2, Number), Number), BigInteger.Remainder(2 * r4 * BigInteger.ModPow(s4, 5, Number) * BigInteger.ModPow(t1.Result, 3, Number), Number) }); break; case (-163): BigInteger r5 = 151931373056000; BigInteger s5 = 151931373056001; paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * r5 * BigInteger.ModPow(s5, 3, Number), Number), BigInteger.Remainder(2 * r5 * BigInteger.ModPow(s5, 5, Number), Number) }); t1.Wait(); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * r5 * BigInteger.ModPow(s5, 3, Number) * BigInteger.ModPow(t1.Result, 2, Number), Number), BigInteger.Remainder(2 * r5 * BigInteger.ModPow(s5, 5, Number) * BigInteger.ModPow(t1.Result, 3, Number), Number) }); break; case (-15): BigInteger r6 = 1225 - 2080 * Extension.SquareRootModPrime(5, Number); BigInteger s6 = 5929; paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * r6 * BigInteger.ModPow(s6, 3, Number), Number), BigInteger.Remainder(2 * r6 * BigInteger.ModPow(s6, 5, Number), Number) }); t1.Wait(); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * r6 * BigInteger.ModPow(s6, 3, Number) * BigInteger.ModPow(t1.Result, 2, Number), Number), BigInteger.Remainder(2 * r6 * BigInteger.ModPow(s6, 5, Number) * BigInteger.ModPow(t1.Result, 3, Number), Number) }); break; case (-20): BigInteger r7 = 108250 + 29835 * Extension.SquareRootModPrime(5, Number); BigInteger s7 = 174724; paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * r7 * BigInteger.ModPow(s7, 3, Number), Number), BigInteger.Remainder(2 * r7 * BigInteger.ModPow(s7, 5, Number), Number) }); t1.Wait(); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * r7 * BigInteger.ModPow(s7, 3, Number) * BigInteger.ModPow(t1.Result, 2, Number), Number), BigInteger.Remainder(2 * r7 * BigInteger.ModPow(s7, 5, Number) * BigInteger.ModPow(t1.Result, 3, Number), Number) }); break; case (-24): BigInteger r8 = 1757 - 494 * Extension.SquareRootModPrime(2, Number); BigInteger s8 = 1058; paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * r8 * BigInteger.ModPow(s8, 3, Number), Number), BigInteger.Remainder(2 * r8 * BigInteger.ModPow(s8, 5, Number), Number) }); t1.Wait(); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * r8 * BigInteger.ModPow(s8, 3, Number) * BigInteger.ModPow(t1.Result, 2, Number), Number), BigInteger.Remainder(2 * r8 * BigInteger.ModPow(s8, 5, Number) * BigInteger.ModPow(t1.Result, 3, Number), Number) }); break; case (-35): BigInteger r9 = -1126400 - 1589760 * Extension.SquareRootModPrime(5, Number); BigInteger s9 = 2428447; paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * r9 * BigInteger.ModPow(s9, 3, Number), Number), BigInteger.Remainder(2 * r9 * BigInteger.ModPow(s9, 5, Number), Number) }); t1.Wait(); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * r9 * BigInteger.ModPow(s9, 3, Number) * BigInteger.ModPow(t1.Result, 2, Number), Number), BigInteger.Remainder(2 * r9 * BigInteger.ModPow(s9, 5, Number) * BigInteger.ModPow(t1.Result, 3, Number), Number) }); break; case (-40): BigInteger r11 = 54175 - 1020 * Extension.SquareRootModPrime(5, Number); BigInteger s11 = 51894; paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * r11 * BigInteger.ModPow(s11, 3, Number), Number), BigInteger.Remainder(2 * r11 * BigInteger.ModPow(s11, 5, Number), Number) }); t1.Wait(); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * r11 * BigInteger.ModPow(s11, 3, Number) * BigInteger.ModPow(t1.Result, 2, Number), Number), BigInteger.Remainder(2 * r11 * BigInteger.ModPow(s11, 5, Number) * BigInteger.ModPow(t1.Result, 3, Number), Number) }); break; case (-51): BigInteger r12 = 75520 - 7936 * Extension.SquareRootModPrime(17, Number); BigInteger s12 = 108241; paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * r12 * BigInteger.ModPow(s12, 3, Number), Number), BigInteger.Remainder(2 * r12 * BigInteger.ModPow(s12, 5, Number), Number) }); t1.Wait(); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * r12 * BigInteger.ModPow(s12, 3, Number) * BigInteger.ModPow(t1.Result, 2, Number), Number), BigInteger.Remainder(2 * r12 * BigInteger.ModPow(s12, 5, Number) * BigInteger.ModPow(t1.Result, 3, Number), Number) }); break; case (-52): BigInteger rq = 1778750 + 5125 * Extension.SquareRootModPrime(13, Number); BigInteger sq = 1797228; paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * rq * BigInteger.ModPow(sq, 3, Number), Number), BigInteger.Remainder(2 * rq * BigInteger.ModPow(sq, 5, Number), Number) }); t1.Wait(); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * rq * BigInteger.ModPow(sq, 3, Number) * BigInteger.ModPow(t1.Result, 2, Number), Number), BigInteger.Remainder(2 * rq * BigInteger.ModPow(sq, 5, Number) * BigInteger.ModPow(t1.Result, 3, Number), Number) }); break; case (-88): BigInteger rw = 181713125 - 44250 * Extension.SquareRootModPrime(2, Number); BigInteger sw = 181650546; paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * rw * BigInteger.ModPow(sw, 3, Number), Number), BigInteger.Remainder(2 * rw * BigInteger.ModPow(sw, 5, Number), Number) }); t1.Wait(); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * rw * BigInteger.ModPow(sw, 3, Number) * BigInteger.ModPow(t1.Result, 2, Number), Number), BigInteger.Remainder(2 * rw * BigInteger.ModPow(sw, 5, Number) * BigInteger.ModPow(t1.Result, 3, Number), Number) }); break; case (-91): BigInteger re = 74752 - 36352 * Extension.SquareRootModPrime(13, Number); BigInteger se = 205821; paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * re * BigInteger.ModPow(se, 3, Number), Number), BigInteger.Remainder(2 * re * BigInteger.ModPow(se, 5, Number), Number) }); t1.Wait(); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * re * BigInteger.ModPow(se, 3, Number) * BigInteger.ModPow(t1.Result, 2, Number), Number), BigInteger.Remainder(2 * re * BigInteger.ModPow(se, 5, Number) * BigInteger.ModPow(t1.Result, 3, Number), Number) }); break; case (-115): BigInteger ra = 269593600 - 89157120 * Extension.SquareRootModPrime(5, Number); BigInteger sa = 468954981; paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * ra * BigInteger.ModPow(sa, 3, Number), Number), BigInteger.Remainder(2 * ra * BigInteger.ModPow(sa, 5, Number), Number) }); t1.Wait(); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * ra * BigInteger.ModPow(sa, 3, Number) * BigInteger.ModPow(t1.Result, 2, Number), Number), BigInteger.Remainder(2 * ra * BigInteger.ModPow(sa, 5, Number) * BigInteger.ModPow(t1.Result, 3, Number), Number) }); break; case (-123): BigInteger rs = 1025058304000 - 1248832000 * Extension.SquareRootModPrime(41, Number); BigInteger ss = 1033054730449; paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * rs * BigInteger.ModPow(ss, 3, Number), Number), BigInteger.Remainder(2 * rs * BigInteger.ModPow(ss, 5, Number), Number) }); t1.Wait(); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * rs * BigInteger.ModPow(ss, 3, Number) * BigInteger.ModPow(t1.Result, 2, Number), Number), BigInteger.Remainder(2 * rs * BigInteger.ModPow(ss, 5, Number) * BigInteger.ModPow(t1.Result, 3, Number), Number) }); break; case (-148): BigInteger rd = 499833128054750 + 356500625 * Extension.SquareRootModPrime(37, Number); BigInteger sd = 499835296563372; paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * rd * BigInteger.ModPow(sd, 3, Number), Number), BigInteger.Remainder(2 * rd * BigInteger.ModPow(sd, 5, Number), Number) }); t1.Wait(); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * rd * BigInteger.ModPow(sd, 3, Number) * BigInteger.ModPow(t1.Result, 2, Number), Number), BigInteger.Remainder(2 * rd * BigInteger.ModPow(sd, 5, Number) * BigInteger.ModPow(t1.Result, 3, Number), Number) }); break; case (-187): BigInteger rz = 91878880000 - 1074017568000 * Extension.SquareRootModPrime(17, Number); BigInteger sz = 4520166756633; paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * rz * BigInteger.ModPow(sz, 3, Number), Number), BigInteger.Remainder(2 * rz * BigInteger.ModPow(sz, 5, Number), Number) }); t1.Wait(); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * rz * BigInteger.ModPow(sz, 3, Number) * BigInteger.ModPow(t1.Result, 2, Number), Number), BigInteger.Remainder(2 * rz * BigInteger.ModPow(sz, 5, Number) * BigInteger.ModPow(t1.Result, 3, Number), Number) }); break; case (-232): BigInteger rx = 1728371226151263375 - 11276414500 * Extension.SquareRootModPrime(29, Number); BigInteger sx = 1728371165425912854; paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * rx * BigInteger.ModPow(sx, 3, Number), Number), BigInteger.Remainder(2 * rx * BigInteger.ModPow(sx, 5, Number), Number) }); t1.Wait(); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * rx * BigInteger.ModPow(sx, 3, Number) * BigInteger.ModPow(t1.Result, 2, Number), Number), BigInteger.Remainder(2 * rx * BigInteger.ModPow(sx, 5, Number) * BigInteger.ModPow(t1.Result, 3, Number), Number) }); break; case (-267): BigInteger rc = BigInteger.Parse("3632253349307716000000") - 12320504793376000 * Extension.SquareRootModPrime(89, Number); BigInteger sc = BigInteger.Parse("3632369580717474122449"); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * rc * BigInteger.ModPow(sc, 3, Number), Number), BigInteger.Remainder(2 * rc * BigInteger.ModPow(sc, 5, Number), Number) }); t1.Wait(); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * rc * BigInteger.ModPow(sc, 3, Number) * BigInteger.ModPow(t1.Result, 2, Number), Number), BigInteger.Remainder(2 * rc * BigInteger.ModPow(sc, 5, Number) * BigInteger.ModPow(t1.Result, 3, Number), Number) }); break; case (-403): BigInteger rcq = BigInteger.Parse("16416107434811840000") - 4799513373120384000 * Extension.SquareRootModPrime(13, Number); BigInteger scq = BigInteger.Parse("33720998998872514077"); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * rcq * BigInteger.ModPow(scq, 3, Number), Number), BigInteger.Remainder(2 * rcq * BigInteger.ModPow(scq, 5, Number), Number) }); t1.Wait(); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * rcq * BigInteger.ModPow(scq, 3, Number) * BigInteger.ModPow(t1.Result, 2, Number), Number), BigInteger.Remainder(2 * rcq * BigInteger.ModPow(scq, 5, Number) * BigInteger.ModPow(t1.Result, 3, Number), Number) }); break; case (-427): BigInteger rcqa = BigInteger.Parse("564510997315289728000") - 5784785611102784000 * Extension.SquareRootModPrime(61, Number); BigInteger scqa = BigInteger.Parse("609691617259594724421"); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * rcqa * BigInteger.ModPow(scqa, 3, Number), Number), BigInteger.Remainder(2 * rcqa * BigInteger.ModPow(scqa, 5, Number), Number) }); t1.Wait(); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(-3 * rcqa * BigInteger.ModPow(scqa, 3, Number) * BigInteger.ModPow(t1.Result, 2, Number), Number), BigInteger.Remainder(2 * rcqa * BigInteger.ModPow(scqa, 5, Number) * BigInteger.ModPow(t1.Result, 3, Number), Number) }); break; } return(paramCurve); }