public static bool VerificarFirmaElectronica(Punto publicKey, byte[] message, byte[] signature)
        {
            var parsed = ASN1_Generator.ASN1_Generator.Parse(signature);

            var r = ((ASN1_Integer)((ASN1_Sequence)parsed
                                    .Elements[0])
                     .content[0])
                    .Value;

            var s = ((ASN1_Integer)((ASN1_Sequence)parsed
                                    .Elements[0])
                     .content[1])
                    .Value;

            if (!(0 < r && r < Params.n))
            {
                return(false);
            }
            if (!(0 < s && s < Params.n))
            {
                return(false);
            }

            var eHash = FirmaElectronica.ObtenerHash(message);

            var e = new BigInteger(eHash);

            if (e.Sign == -1)
            {
                e = BigInteger.Negate(e);
            }

            var w = Arithmetic.Inversion_ExtendedEuclidean(s, Params.n);

            var u1 = Arithmetic.Mod(e * w, Params.n);

            var u2 = Arithmetic.Mod(r * w, Params.n);

            var X = u1 * Params.G + u2 * publicKey;

            if (X.EsInfinito || X.EsCero)
            {
                return(false);
            }

            var v = Arithmetic.Mod(X.x, Params.n);

            if (v == r)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
        private static Punto Zadd_2007_m(Punto P, Punto Q)
        {
            BigInteger A, B, C, D, X3, Y3, Z3;

            A  = BigInteger.Pow(Q.X - P.X, 2);
            B  = P.X * A;
            C  = Q.X * A;
            D  = BigInteger.Pow(Q.Y - P.Y, 2);
            X3 = D - B - C;
            Y3 = (Q.Y - P.Y) * (B - X3) - P.Y * (C - B);
            Z3 = P.Z * (Q.X - P.X);

            return(new Punto()
            {
                X = Arithmetic.Mod(X3, Params.p), Y = Arithmetic.Mod(Y3, Params.p), Z = Arithmetic.Mod(Z3, Params.p)
            });
        }
Example #3
0
        /// <summary>
        /// Algorithm 3.30: Computing the NAF of a positive integer
        /// </summary>
        /// <param name="k"></param>
        /// <returns></returns>
        public static List <BigInteger> computeNAF(BigInteger k)
        {
            List <BigInteger> NAF = new List <BigInteger>();

            while (k >= 1)
            {
                BigInteger ki = 0;
                if (!k.IsEven)
                {
                    ki = 2 - (Arithmetic.Mod(k, 4));
                    k -= ki;
                }
                NAF.Add(ki);
                k /= 2;
            }
            return(NAF);
        }
Example #4
0
        public static Punto FixedBaseWindowing(BigInteger k)
        {
            Punto A = Punto.Infinito;
            Punto B = Punto.Infinito;

            List <BigInteger> kBase = Base(k, (int)Math.Pow(2, Precompute.Instance.w));

            //for (int j = (int)Math.Pow(2, Precompute.Instance.w) - 1; j >= 1; j--) {
            //    for (int i = Precompute.Instance.d - 1; i >= 0; i--)
            //        if (kBase[i] == j) B = B + Precompute.Instance.Pi[i];


            //    A = A + B;
            //}

            var add = Precompute.Instance.d - kBase.Count;

            if (add > 0)
            {
                for (int l = 0; l < add; l++)
                {
                    kBase.Add(0);
                }
            }


            for (int j = (int)Math.Pow(2, Precompute.Instance.w) - 1; j >= 1; j--)
            {
                for (int i = Precompute.Instance.d - 1; i >= 0; i--)
                {
                    if (kBase[i] == j)
                    {
                        B = B + Precompute.Instance.Pi[i];
                    }
                }
                A = A + B;
            }



            return(new Punto()
            {
                X = Arithmetic.Mod(A.X, Params.p), Y = Arithmetic.Mod(A.Y, Params.p), Z = Arithmetic.Mod(A.Z, Params.p)
            });
        }
        public static byte[] GenerarFirmaElectronica(byte[] message, BigInteger privateKey)
        {
            while (true)
            {
                //Genero un valor 'k' aleatorio
                BigInteger k = Helper.Random(Params.n);

                //Calculo el punto P = k*G
                Punto kP = k * Params.G;

                BigInteger r = Arithmetic.Mod(kP.x, Params.n);

                if (r.IsZero)
                {
                    continue;
                }

                var eHash = FirmaElectronica.ObtenerHash(message);
                var e     = new BigInteger(eHash);
                if (e.Sign == -1)
                {
                    e = BigInteger.Negate(e);
                }

                BigInteger s = Arithmetic.Mod(
                    Arithmetic.Inversion_ExtendedEuclidean(k, Params.n) * (e + privateKey * r), Params.n
                    );

                var asn1 = new ASN1_Generator.ASN1_Generator();
                var seq  = new ASN1_Generator.ASN1_Sequence();

                seq.content.Add(new ASN1_Generator.ASN1_Integer()
                {
                    Value = r
                });
                seq.content.Add(new ASN1_Generator.ASN1_Integer()
                {
                    Value = s
                });

                asn1.Elements.Add(seq);

                return(asn1.GetBytes());
            }
        }
Example #6
0
        public static Punto Jacobian_PointDoubling(Punto P)
        {
            if (P.EsInfinito)
            {
                return(Punto.Infinito);
            }
            BigInteger T1 = 3 * BigInteger.Pow(P.X, 2) + Params.a * BigInteger.Pow(P.Z, 4);
            BigInteger T2 = P.X * BigInteger.Pow(P.Y, 2);
            BigInteger T3 = 4 * T2;
            BigInteger X3 = Arithmetic.Mod(BigInteger.Pow(T1, 2) - 2 * T3, Params.p);
            BigInteger Y3 = Arithmetic.Mod((T1)*(T3 - X3) - 8 * BigInteger.Pow(P.Y, 4), Params.p);
            BigInteger Z3 = Arithmetic.Mod(2 * P.Y * P.Z, Params.p);

            return(new Punto()
            {
                X = X3, Y = Y3, Z = Z3
            });
        }
        private static Punto Bernstein_Lange_11M_5S_Addition(Punto P, Punto Q)
        {
            if (Q.EsInfinito || Q.EsCero)
            {
                return(P);
            }
            if (P.EsInfinito || P.EsCero)
            {
                return(Q);
            }
            if ((P.EsInfinito && Q.EsInfinito))
            {
                return(Punto.Infinito);
            }

            if (P.X == Q.X && P.Y == Q.Y && P.Z == Q.Z)
            {
                return(dbl_2005_dl(P));
            }
            BigInteger Z1Z1, Z2Z2, U1, U2, S1, S2, H, I, J, r, V, X3, Y3, Z3;

            Z1Z1 = P.Z * P.Z;
            Z2Z2 = Q.Z * Q.Z;
            U1   = P.X * Z2Z2;
            U2   = Q.X * Z1Z1;
            S1   = P.Y * Q.Z * Z2Z2;
            S2   = Q.Y * P.Z * Z1Z1;
            H    = U2 - U1;
            I    = BigInteger.Pow(2 * H, 2);
            J    = H * I;
            r    = 2 * (S2 - S1);
            V    = U1 * I;
            X3   = BigInteger.Pow(r, 2) - J - 2 * V;
            Y3   = r * (V - X3) - 2 * S1 * J;
            Z3   = (BigInteger.Pow(P.Z + Q.Z, 2) - Z1Z1 - Z2Z2) * H;
            return(new Punto()
            {
                X = Arithmetic.Mod(X3, Params.p), Y = Arithmetic.Mod(Y3, Params.p), Z = Arithmetic.Mod(Z3, Params.p)
            });
        }
Example #8
0
        public static Punto dbl_2005_dl(Punto P)
        {
            if (P.EsInfinito)
            {
                return(Punto.Infinito);
            }
            BigInteger XX = 0, YY = 0, YYYY, ZZ, S, M, T, X3, Y3, Z3;

            XX   = BigInteger.Pow(P.X, 2);
            YY   = BigInteger.Pow(P.Y, 2);
            YYYY = BigInteger.Pow(YY, 2);
            ZZ   = BigInteger.Pow(P.Z, 2);
            S    = 2 * (BigInteger.Pow(P.X + YY, 2) - XX - YYYY);
            M    = 3 * XX + Params.a * BigInteger.Pow(ZZ, 2);
            T    = BigInteger.Pow(M, 2) - 2 * S;
            X3   = T;
            Y3   = M * (S - T) - 8 * YYYY;
            Z3   = BigInteger.Pow(P.Y + P.Z, 2) - YY - ZZ;
            return(new Punto()
            {
                X = Arithmetic.Mod(X3, Params.p), Y = Arithmetic.Mod(Y3, Params.p), Z = Arithmetic.Mod(Z3, Params.p)
            });
        }
        private static Punto GenericAddition(Punto P, Punto Q)
        {
            if (P.EsCero && !Q.EsCero)
            {
                return(Q);
            }
            if (!P.EsCero && Q.EsCero)
            {
                return(P);
            }
            if (P.EsCero && Q.EsCero)
            {
                return(P);
            }

            if (P.EsInfinito && !Q.EsInfinito)
            {
                return(Q);
            }
            if (!P.EsInfinito && Q.EsInfinito)
            {
                return(P);
            }

            if (P.EsInfinito && Q.EsInfinito)
            {
                return(Punto.Infinito);
            }
            if (P.y == BigInteger.Negate(Q.y))
            {
                return(Punto.Infinito);
            }

            if (P.x.Sign == -1 || P.y.Sign == -1 || Q.x.Sign == -1 || Q.y.Sign == -1)
            {
                throw new Exception("Something's wrong with your code dude");
            }

            BigInteger m;

            try
            {
                if (P.x == Q.x && P.y == Q.y)
                {
                    m = Arithmetic.Mod((3 * BigInteger.Pow(P.x, 2) + Params.a) * Arithmetic.Inversion_ExtendedEuclidean(2 * P.y, Params.p), Params.p);
                }
                else
                {
                    m = Arithmetic.Mod(((P.y - Q.y) * Arithmetic.Inversion_ExtendedEuclidean(P.x - Q.x, Params.p)), Params.p);
                }
            }
            catch (Arithmetic.ZeroMultiplicativeInverseException e)
            {
                return(new Punto(0, 0));
            }

            BigInteger xr = Arithmetic.Mod(BigInteger.Pow(m, 2) - P.x - Q.x, Params.p);

            BigInteger yr = Arithmetic.Mod(-P.y + m * (P.x - xr), Params.p);

            return(new Punto(xr, yr));
        }
Example #10
0
        static void Main(string[] args)
        {
            BigInteger x = BigInteger.Parse("1780819745898020903958445983817712046940526920208100261980597417995944094029596777064056093853401612609592446720592179827428830711037179095183363610369286896530377147020164486564305282834564397204864742032807451239311336678027124958183095442467202432885533412460497680631724687052136004971388767593842487219676700541041028853340921294573751002235691309531779181643421745137316858017632");

            BigInteger k = BigInteger.Parse("115792089210356248762697446949407573530086143415290314195533631308867097853951");

            //Helper.Profile("My Mod", 229230, () => {
            var mod1 = Arithmetic.Mod(x, k);
            //});

            //Helper.Profile("Barret Mod", 229230, () => {
            //   var mod2 = Arithmetic.BarretReductionAlgorithm(x, k);
            ///});

            //var mod3 = Arithmetic.BarretReductionAlgorithm(100, 98);

            List <BigInteger> RandomNumberList = new List <BigInteger>();

            //RNGCryptoServiceProvider gen = new RNGCryptoServiceProvider();

            /*
             * for (int i = 0; i < 100; i++) {
             *  RandomNumberList.Add(Helper.Random2(Params.n));
             * }*/

            BigInteger privateKey = BigInteger.Parse("94361336695759970226033743282780066403459847548114294645768255588287705655236");

            BigInteger extremelyBigNumber = BigInteger.Parse("1551461040052421630033376555637176927247652242296410672656213134199868674668982407090806310045623166501952293335446863972054254916150318019623130606042930044162267055807608625164274499130491713157653862043041846755192480788386477939774639435688740210646927594059354958526722186425583509661728559912246704339035370747853464735324155659865526249236817957209992379928407951016837355049751914048973680813110386622841414029072466793204155119949410039474434795850555640661534924144623563930525759219190180188740845965806118537410973298634016690697312160969002462761252307795051914445410837447949377761948624682900899665567231192899475473514291983333722860346363121933440060876201363493841809549535166164872948031112619975338416030325359423737371253808843126492551925149823504");

            Punto test3 = Punto.LeftToRight_BinaryMultiplication(privateKey, Params.G);



            //////
            //////
            //////

            /*
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Binary NAF Point Multiplication", 1, () => {
             *  foreach (var number in RandomNumberList) {
             *      Point.BinaryNAFPointMultiplication(number, Params.G);
             *  }
             * });
             * OperationCounter.Instance.PrintCounts();
             *
             *
             *
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Left-to-right binary method for point multiplication", 1, () => {
             *  foreach (var number in RandomNumberList)
             *  {
             *      Point.LeftToRight_BinaryMultiplication(number, Params.G);
             *  }
             * });
             * OperationCounter.Instance.PrintCounts();
             *
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Right-to-left binary method for point multiplication", 1, () => {
             *  foreach (var number in RandomNumberList)
             *  {
             *      Point.RightToLeft_BinaryMultiplication(number, Params.G);
             *  }
             * });
             * OperationCounter.Instance.PrintCounts();
             *
             *
             * WindowNAFPointMultiplication_Precompute.Instance.Initialize(2);
             * Helper.Profile("Window NAF method for point multiplication (window width = 2)", 1, () => {
             *  foreach (var number in RandomNumberList)
             *  {
             *      Point.WindowNAFPointMultiplication(number, Params.G);
             *  }
             * });
             * OperationCounter.Instance.PrintCounts();
             *
             *
             * Precompute.Instance.Initialize(2);
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Fixed-base windowing method (window width = 2)", 1, () => {
             *  foreach (var number in RandomNumberList)
             *  {
             *      FixedBaseWindowing(number);
             *  }
             * });
             * OperationCounter.Instance.PrintCounts();
             *
             * Precompute.Instance.Initialize(3);
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Fixed-base windowing method (window width = 3)", 1, () => {
             *  foreach (var number in RandomNumberList)
             *  {
             *      FixedBaseWindowing(number);
             *  }
             * });
             * OperationCounter.Instance.PrintCounts();
             *
             * Precompute.Instance.Initialize(4);
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Fixed-base windowing method (window width = 4)", 1, () => {
             *  foreach (var number in RandomNumberList)
             *  {
             *      FixedBaseWindowing(number);
             *  }
             * });
             * OperationCounter.Instance.PrintCounts();
             *
             * Precompute.Instance.Initialize(5);
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Fixed-base windowing method (window width = 5)", 1, () => {
             *  foreach (var number in RandomNumberList)
             *  {
             *      FixedBaseWindowing(number);
             *  }
             * });
             * OperationCounter.Instance.PrintCounts();
             *
             * Precompute.Instance.Initialize(6);
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Fixed-base windowing method (window width = 6)", 1, () => {
             *  foreach (var number in RandomNumberList)
             *  {
             *      FixedBaseWindowing(number);
             *  }
             * });
             * OperationCounter.Instance.PrintCounts();
             *
             *
             * WindowNAFPointMultiplication_Precompute.Instance.Initialize(2);
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Window NAF method for point multiplication (window width = 2)", 1, () =>
             * {
             *  foreach (var number in RandomNumberList)
             *  {
             *      Point.WindowNAFPointMultiplication(number, Params.G);
             *  }
             * });
             * OperationCounter.Instance.PrintCounts();
             *
             * WindowNAFPointMultiplication_Precompute.Instance.Initialize(3);
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Window NAF method for point multiplication (window width = 3)", 1, () =>
             * {
             *  foreach (var number in RandomNumberList)
             *  {
             *      Point.WindowNAFPointMultiplication(number, Params.G);
             *  }
             * });
             * OperationCounter.Instance.PrintCounts();
             *
             * WindowNAFPointMultiplication_Precompute.Instance.Initialize(4);
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Window NAF method for point multiplication (window width = 4)", 1, () =>
             * {
             *  foreach (var number in RandomNumberList)
             *  {
             *      Point.WindowNAFPointMultiplication(number, Params.G);
             *  }
             * });
             * OperationCounter.Instance.PrintCounts();
             *
             * WindowNAFPointMultiplication_Precompute.Instance.Initialize(5);
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Window NAF method for point multiplication (window width = 5)", 1, () =>
             * {
             *  foreach (var number in RandomNumberList)
             *  {
             *      Point.WindowNAFPointMultiplication(number, Params.G);
             *  }
             * });
             * OperationCounter.Instance.PrintCounts();
             *
             * WindowNAFPointMultiplication_Precompute.Instance.Initialize(6);
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Window NAF method for point multiplication (window width = 6)", 1, () =>
             * {
             *  foreach (var number in RandomNumberList)
             *  {
             *      Point.WindowNAFPointMultiplication(number, Params.G);
             *  }
             * });
             * OperationCounter.Instance.PrintCounts();
             */
            //////
            //////
            //////

            Punto publicKey = privateKey * Params.G;
            Punto test2     = Punto.RightToLeft_BinaryMultiplication(privateKey, Params.G);

            WindowNAFPointMultiplication_Precompute.Instance.Initialize(10);
            //Point test3 = Point.WindowNAFPointMultiplication(privateKey, Params.G);
            Punto test4 = FixedBaseWindowing(privateKey);


            var message = Encoding.UTF8.GetBytes("Test message");

            //var signature = ECDSA_signature_generation(message, privateKey);

            //var verification = ECDSA_signature_verification(publicKey, message, signature);

            /*
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Binary NAF Point Multiplication", 100, () => { Point.BinaryNAFPointMultiplication(privateKey, Params.G); });
             * OperationCounter.Instance.PrintCounts();
             *
             * Helper.Profile("Left-to-right binary method for point multiplication", 100, () => { Point.LeftToRight_BinaryMultiplication(privateKey, Params.G); });
             * OperationCounter.Instance.PrintCounts();
             *
             * Helper.Profile("Right-to-left binary method for point multiplication", 100, () => { Point.RightToLeft_BinaryMultiplication(privateKey, Params.G); });
             * OperationCounter.Instance.PrintCounts();
             */
            /*
             * Helper.Profile("Computing wNAF (window width = 5)", 100, () => { Point.compute_wNAF(privateKey, 5); });
             *
             * Helper.Profile("Computing wNAF (window width = 10)", 100, () => { Point.compute_wNAF(privateKey, 5); });
             *
             * Helper.Profile("Computing wNAF (window width = 100)", 100, () => { Point.compute_wNAF(privateKey, 5); });
             */
            /*
             * Precompute.Instance.Initialize(2);
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Fixed-base windowing method (window width = 2)", 100, () => { FixedBaseWindowing(privateKey); });
             * OperationCounter.Instance.PrintCounts();
             *
             * Precompute.Instance.Initialize(3);
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Fixed-base windowing method (window width = 3)", 100, () => { FixedBaseWindowing(privateKey); });
             * OperationCounter.Instance.PrintCounts();
             *
             * Precompute.Instance.Initialize(4);
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Fixed-base windowing method (window width = 4)", 100, () => { FixedBaseWindowing(privateKey); });
             * OperationCounter.Instance.PrintCounts();
             *
             * Precompute.Instance.Initialize(5);
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Fixed-base windowing method (window width = 5)", 100, () => { FixedBaseWindowing(privateKey); });
             * OperationCounter.Instance.PrintCounts();
             *
             * Precompute.Instance.Initialize(6);
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Fixed-base windowing method (window width = 6)", 100, () => { FixedBaseWindowing(privateKey); });
             * OperationCounter.Instance.PrintCounts();
             *
             * Precompute.Instance.Initialize(7);
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Fixed-base windowing method (window width = 7)", 100, () => { FixedBaseWindowing(privateKey); });
             * OperationCounter.Instance.PrintCounts();
             *
             *
             * WindowNAFPointMultiplication_Precompute.Instance.Initialize(2);
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Window NAF method for point multiplication (window width = 2)", 100, () => { Point.WindowNAFPointMultiplication(privateKey, Params.G); });
             * OperationCounter.Instance.PrintCounts();
             *
             * WindowNAFPointMultiplication_Precompute.Instance.Initialize(3);
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Window NAF method for point multiplication (window width = 3)", 100, () => { Point.WindowNAFPointMultiplication(privateKey, Params.G); });
             * OperationCounter.Instance.PrintCounts();
             *
             * WindowNAFPointMultiplication_Precompute.Instance.Initialize(4);
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Window NAF method for point multiplication (window width = 4)", 100, () => { Point.WindowNAFPointMultiplication(privateKey, Params.G); });
             * OperationCounter.Instance.PrintCounts();
             *
             * WindowNAFPointMultiplication_Precompute.Instance.Initialize(5);
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Window NAF method for point multiplication (window width = 5)", 100, () => { Point.WindowNAFPointMultiplication(privateKey, Params.G); });
             * OperationCounter.Instance.PrintCounts();
             *
             * WindowNAFPointMultiplication_Precompute.Instance.Initialize(6);
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Window NAF method for point multiplication (window width = 6)", 100, () => { Point.WindowNAFPointMultiplication(privateKey, Params.G); });
             * OperationCounter.Instance.PrintCounts();
             *
             * WindowNAFPointMultiplication_Precompute.Instance.Initialize(7);
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Window NAF method for point multiplication (window width = 7)", 100, () => { Point.WindowNAFPointMultiplication(privateKey, Params.G); });
             * OperationCounter.Instance.PrintCounts();
             *
             * WindowNAFPointMultiplication_Precompute.Instance.Initialize(10);
             * OperationCounter.Instance.Reset();
             * Helper.Profile("Window NAF method for point multiplication (window width = 10)", 100, () => { Point.WindowNAFPointMultiplication(privateKey, Params.G); });
             * OperationCounter.Instance.PrintCounts();
             *
             *
             *
             */


            var inverse = Arithmetic.Inversion_ExtendedEuclidean(-9, 23);

            //Console.WriteLine(Params.p);
            //Console.WriteLine(Params.G.x);
            //Console.WriteLine(Params.G.y);


            Console.ReadKey();
        }