예제 #1
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);
        }