private void Recurse(BigInteger p, List <BigInteger> A, ref List <BigInteger> root) { int count = 0, degreeA = A.Count - 1, degreeB = 0; BigInteger exp = 0, p1 = p - 1, D = 0, a = 0, b = 0, c = 0, e = 0; List <BigInteger> B = null, d = null; List <BigInteger> q = null, r = null, u = null; exp = p1 / 2; if (degreeA != 0) { if (degreeA == 1) { if (A[0] != 0) { a = Maths.GetInverse(A[1], p); b = A[0]; b = -b; b = Maths.MulMod(b, a, p); root.Add(b); } } else if (degreeA == 2) { a = Maths.MulMod(A[1], A[1], p); b = Maths.MulMod(A[0], A[2], p); c = Maths.MulMod(b, 4, p); D = Maths.SubMod(a, c, p); e = hcr.SquareRootModPrime(D, p); BigInteger test = (e * e) % p; if (e == 1) { return; } a = Maths.MulMod(A[2], 2, p); D = Maths.GetInverse(a, p); if (D == 0) { a = -a; a = Maths.AddMod(a, p, p); D = Maths.GetInverse(a, p); } a = Maths.SubMod(e, A[1], p); root.Add(Maths.MulMod(a, D, p)); A[1] = -A[1]; e = -e; a = Maths.AddMod(A[1], e, p); root.Add(Maths.MulMod(a, D, p)); } else { do { count++; a = hcr.RandomRange(0, p1); u = new List <BigInteger>(); u.Add(a); u.Add(1); PolyPowMod(p, exp, u, A, ref d); if (d.Count - 1 != 0) { d[0] = Maths.SubMod(d[0], 1, p); B = PolyGCDMod(p, d, A); if (B.Count == 1 && B[0] == 1) { return; } degreeB = B.Count - 1; } }while (count < 16 && degreeB == 0 || degreeB == degreeA); if (count == 16) { return; } Recurse(p, B, ref root); PolyDivMod(p, A, B, ref q, ref r); Recurse(p, q, ref root); } } }
public void PolyDivMod(BigInteger p, List <BigInteger> u, List <BigInteger> v, ref List <BigInteger> q, ref List <BigInteger> r) { int j, jk, k, nk, m = u.Count - 1, n = v.Count - 1, t, s; BigInteger a = 0, b = 0, vn = 0, qk = 0; List <BigInteger> tr = new List <BigInteger>(); r = new List <BigInteger>(); vn = v[n]; if (n == 0) { r.Add(0); q = new List <BigInteger>(); for (int i = 0; i < u.Count; i++) { q.Add(Maths.MulMod(u[i], vn, p)); } return; } for (j = 0; j <= m; j++) { r.Add(u[j]); } if (m < n) { q = new List <BigInteger>(); q.Add(0); } else { t = m - n; s = n - 1; q = new List <BigInteger>(); for (k = t; k >= 0; k--) { q.Add(0); } for (k = t; k >= 0; k--) { nk = n + k; if (k != 0) { a = BigInteger.ModPow(vn, k, p); } else { a = 1; } qk = Maths.MulMod(r[nk], a, p); q[k] = qk; for (j = nk - 1; j >= 0; j--) { jk = j - k; if (jk >= 0) { a = Maths.MulMod(vn, r[j], p); b = Maths.MulMod(r[nk], v[jk], p); r[j] = Maths.SubMod(a, b, p); } else { r[j] = Maths.MulMod(vn, r[j], p); } } } for (int i = s; i > 0; i--) { if (r[i] == 0) { s--; } else { break; } } for (int i = s; i >= 0; i--) { tr.Add(r[i]); } r = PolyRev(tr); } }
private BigInteger BabyStepGiantStep(long l, BigInteger t2, BigInteger x, BigInteger y) { long W = (long)(Math.Ceiling(Math.Sqrt(0.5 * l))); BigInteger beta = 0, gamma = 0, k = 0; BigInteger pmodl = ecs.P % l; BigInteger ps = ecs.P * ecs.P; BigInteger Ax = 0, Bx = 0, Ay = 0, By = 0, kmod2 = 0; BigInteger psil = Maths.Psi((int)l, x, y, ecs.A, ecs.B, ecs.P); List <ijPair> S = new List <ijPair>(); if (psil == 0) { return(-3); } EllipticCurve_Point P0 = new EllipticCurve_Point(), P1 = new EllipticCurve_Point(), P2 = new EllipticCurve_Point(), P3 = new EllipticCurve_Point(), P12 = new EllipticCurve_Point(), P = new EllipticCurve_Point(); List <EllipticCurve_Point> A = new List <EllipticCurve_Point>(); List <EllipticCurve_Point> B = new List <EllipticCurve_Point>(); P.X = x; P.Y = y; P0.X = BigInteger.ModPow(x, ecs.P, psil); P0.Y = BigInteger.ModPow(y, ecs.P, psil); P1.X = BigInteger.ModPow(x, ps, psil); P1.Y = BigInteger.ModPow(y, ps, psil); ecs.Mult(pmodl, P, ref P2); if (!ecs.Sum(P1, P2, ref P12)) { return(-1); } if (P12.IsNull) { return(0); } for (beta = 0; beta < W; beta++) { if (!ecs.Mult(beta, P0, ref P3)) { return(-1); } if (!ecs.Sum(P12, P3, ref P3)) { return(-1); } bool found = false; for (int i = 0; !found && i < A.Count; i++) { found = A[i].X == P3.X && A[i].Y == P3.Y; } if (!found && !P3.IsNull) { A.Add(P3); } } for (gamma = 0; gamma <= W; gamma++) { if (!ecs.Mult(gamma * W, P0, ref P3)) { return(-1); } bool found = false; for (int i = 0; !found && i < B.Count; i++) { found = B[i].X == P3.X && B[i].Y == P3.Y; } if (!found && !P3.IsNull) { B.Add(P3); } } if (A.Count != 0 && B.Count != 0) { A.Sort(); B.Sort(); for (int i = 0; i < A.Count; i++) { Ax = A[i].X; for (int j = 0; j < B.Count; j++) { Bx = B[j].X; if (Ax == Bx) { ijPair ij = new ijPair(); ij.i = i; ij.j = j; S.Add(ij); } } } if (S.Count == 1) { beta = S[0].i; gamma = S[0].j; k = beta + gamma * W; kmod2 = k % 2; if (t2 == kmod2) { Ay = A[(int)beta].Y; By = B[(int)gamma].Y; if (Ay == By) { return(k); } else { return(l - k); } } k = beta - gamma * W; kmod2 = k % 2; if (kmod2 < 0) { kmod2 += 2; } if (t2 == kmod2) { Ay = A[(int)beta].Y; By = B[(int)gamma].Y; if (Ay == By) { return(k); } else { return(l - k); } } } } return(-1); }