Beispiel #1
0
        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);
                }
            }
        }
Beispiel #2
0
        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);
            }
        }
Beispiel #3
0
        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);
        }