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);
            }
        }
        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());
            }
        }
        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));
        }
Exemple #4
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();
        }