Exemple #1
0
        //генерация публичного ключа (с помощью секретного).
        public CECPoint publicKeyGen(BigInteger d)
        {
            CECPoint G = gDecompression();
            CECPoint Q = CECPoint.multiply(G, d);

            return(Q);
        }
Exemple #2
0
        //восстановление координат Y из координаты X и бита четности Y.
        private CECPoint gDecompression()
        {
            byte y = xG[0];

            byte[] x = new byte[xG.Length - 1];
            Array.Copy(xG, 1, x, 0, xG.Length - 1);
            BigInteger Xcord = new BigInteger(x);
            BigInteger temp  = (Xcord * Xcord * Xcord + a * Xcord + b) % p;
            BigInteger beta  = modSqrt(temp, p);
            BigInteger Ycord = new BigInteger();

            if ((beta % 2) == (y % 2))
            {
                Ycord = beta;
            }
            else
            {
                Ycord = p - beta;
            }
            CECPoint G = new CECPoint();

            G.a         = a;
            G.b         = b;
            G.fieldChar = p;
            G.x         = Xcord;
            G.y         = Ycord;
            this.G      = G;
            return(G);
        }
Exemple #3
0
        //формирование цифровой подписи.
        public string DSGen(byte[] h, BigInteger d)
        {
            BigInteger a = new BigInteger(h);
            BigInteger e = a % n;

            if (e == 0)
            {
                e = 1;
            }
            BigInteger k = new BigInteger();
            CECPoint   C = new CECPoint();
            BigInteger r = new BigInteger();
            BigInteger s = new BigInteger();

            do
            {
                do
                {
                    k.genRandomBits(n.bitCount(), new Random());
                }while ((k < 0) || (k > n));

                C = CECPoint.multiply(G, k);
                r = C.x % n;
                s = ((r * d) + (k * e)) % n;
            }while ((r == 0) || (s == 0));

            string Rvector = padding(r.ToHexString(), n.bitCount() / 4);
            string Svector = padding(s.ToHexString(), n.bitCount() / 4);

            return(Rvector + Svector);
        }
Exemple #4
0
        //умножение точки на число.
        public static CECPoint multiply(CECPoint p, BigInteger c)
        {
            CECPoint res = p;

            c = c - 1;
            while (c != 0)
            {
                if ((c % 2) != 0)
                {
                    if ((res.x == p.x) || (res.y == p.y))
                    {
                        res = doubling(res);
                    }
                    else
                    {
                        res = res + p;
                    }
                    c = c - 1;
                }

                c = c / 2;
                p = doubling(p);
            }

            return(res);
        }
Exemple #5
0
 public CECPoint(CECPoint p)
 {
     a         = p.a;
     b         = p.b;
     x         = p.x;
     y         = p.y;
     fieldChar = p.fieldChar;
 }
Exemple #6
0
        static void Main(string[] args)
        {
            BigInteger p = new BigInteger("6277101735386680763835789423207666416083908700390324961279", 10);
            BigInteger a = new BigInteger("-3", 10);
            BigInteger b = new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16);

            byte[]     xG = fromHexStringToByte("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012");
            BigInteger n  = new BigInteger("ffffffffffffffffffffffff99def836146bc9b1b4d22831", 16);

            DS         ds   = new DS(p, a, b, n, xG);
            BigInteger d    = ds.privateKeyGen(192);
            CECPoint   Q    = ds.publicKeyGen(d);
            Stribog256 hash = new Stribog256();


            Console.WriteLine("Выберите файл содержащий сообщение: ");
            String path    = Console.ReadLine();
            String message = File.ReadAllText(path);

            byte[] H    = hash.GetHash(message);
            string sign = ds.DSGen(H, d);

            Console.WriteLine("Сообщение " + message + " имеет следующую ЭЦП: " + sign);
            Console.WriteLine("Выберите файл для сохранение ЭЦП: ");
            path = Console.ReadLine();
            File.WriteAllText(path, sign);

            Console.WriteLine("Выберите файл для верификации сообщения: ");
            path = Console.ReadLine();
            String message2 = File.ReadAllText(path);

            byte[] H2 = hash.GetHash(message2);
            Console.WriteLine("Выберите файл содержащий цифровую подпись: ");
            path = Console.ReadLine();
            string signVer = File.ReadAllText(path);

            bool result = ds.verifyDS(H2, signVer, Q);

            if (result)
            {
                Console.WriteLine("Верификация прошла успешно. Цифровая подпись верна.");
            }
            else
            {
                Console.WriteLine("Верификация не прошла! Цифровая подпись не верна.");
            }

            Console.ReadLine();
        }
Exemple #7
0
        //сложение пары точек.
        public static CECPoint operator +(CECPoint p1, CECPoint p2)
        {
            CECPoint res = new CECPoint();

            res.a         = p1.a;
            res.b         = p1.b;
            res.fieldChar = p1.fieldChar;

            BigInteger dx = p2.x - p1.x;
            BigInteger dy = p2.y - p1.y;

            if (dx < 0)
            {
                dx += p1.fieldChar;
            }
            if (dy < 0)
            {
                dy += p1.fieldChar;
            }

            BigInteger t = (dy * dx.modInverse(p1.fieldChar)) % p1.fieldChar;

            if (t < 0)
            {
                t += p1.fieldChar;
            }

            res.x = (t * t - p1.x - p2.x) % p1.fieldChar;
            res.y = (t * (p1.x - res.x) - p1.y) % p1.fieldChar;

            if (res.x < 0)
            {
                res.x += p1.fieldChar;
            }
            if (res.y < 0)
            {
                res.y += p1.fieldChar;
            }

            return(res);
        }
Exemple #8
0
        //проверка цифровой подписи.
        public bool verifyDS(byte[] H, string sign, CECPoint Q)
        {
            string     Rvector = sign.Substring(0, n.bitCount() / 4);
            string     Svector = sign.Substring(n.bitCount() / 4, n.bitCount() / 4);
            BigInteger r       = new BigInteger(Rvector, 16);
            BigInteger s       = new BigInteger(Svector, 16);

            if ((r < 1) || (r > (n - 1)) || (s < 1) || (s > (n - 1)))
            {
                return(false);
            }

            BigInteger a = new BigInteger(H);
            BigInteger e = a % n;

            if (e == 0)
            {
                e = 1;
            }

            BigInteger v  = e.modInverse(n);
            BigInteger z1 = (s * v) % n;
            BigInteger z2 = n + ((-(r * v)) % n);

            this.G = gDecompression();
            CECPoint   A = CECPoint.multiply(G, z1);
            CECPoint   B = CECPoint.multiply(Q, z2);
            CECPoint   C = A + B;
            BigInteger R = C.x % n;

            if (R == r)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemple #9
0
        //удвоение точки.
        public static CECPoint doubling(CECPoint p)
        {
            CECPoint res = new CECPoint();

            res.a         = p.a;
            res.b         = p.b;
            res.fieldChar = p.fieldChar;

            BigInteger dx = 2 * p.y;
            BigInteger dy = 3 * p.x * p.x + p.a;

            if (dx < 0)
            {
                dx += p.fieldChar;
            }
            if (dy < 0)
            {
                dy += p.fieldChar;
            }

            BigInteger t = (dy * dx.modInverse(p.fieldChar)) % p.fieldChar;

            res.x = (t * t - p.x - p.x) % p.fieldChar;
            res.y = (t * (p.x - res.x) - p.y) % p.fieldChar;

            if (res.x < 0)
            {
                res.x += p.fieldChar;
            }
            if (res.y < 0)
            {
                res.y += p.fieldChar;
            }

            return(res);
        }