public List <BigInteger> PolyMulMod(BigInteger p, List <BigInteger> a, List <BigInteger> b) { int i, j, k, m = a.Count - 1, n = b.Count - 1, q = m + n; BigInteger ai = 0, bj = 0, sum = 0; List <BigInteger> c = new List <BigInteger>(); for (k = 0; k <= q; k++) { sum = 0; for (i = 0; i <= k; i++) { j = k - i; if (i > m) { ai = 0; } else { ai = a[i]; } if (j > n) { bj = 0; } else { bj = b[j]; } sum = Maths.AddMod(sum, Maths.MulMod(ai, bj, p), p); } c.Add(sum); } return(c); }
public BigInteger Weierstrass(BigInteger x) { BigInteger t3 = BigInteger.ModPow(x, 3, p); BigInteger t1 = Maths.MulMod(a, x, p); BigInteger t2 = Maths.AddMod(t3, t1, p); return(Maths.AddMod(t2, b, p)); }
private BigInteger Horner(BigInteger p, BigInteger x, List <BigInteger> P) { BigInteger s = P[P.Count - 1], t = 0; for (int i = P.Count - 2; i >= 0; i--) { t = Maths.MulMod(s, x, p); s = Maths.AddMod(t, P[i], p); } return(s); }
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 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); } } }