예제 #1
1
        //формирование цифровой подписи.
        public string genDS(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;
        }
예제 #2
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);
        }
예제 #3
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);
        }
예제 #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);
        }
예제 #5
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);
        }
예제 #6
0
        //генерация публичного ключа (с помощью секретного).
        public CECPoint genPublicKey(BigInteger d)
        {
            CECPoint G = gDecompression();
            CECPoint Q = CECPoint.multiply(G, d);

            return(Q);
        }
예제 #7
0
        //формирование цифровой подписи.
        public string genDS(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);
        }
예제 #8
0
 public CECPoint(CECPoint p)
 {
     a = p.a;
     b = p.b;
     x = p.x;
     y = p.y;
     fieldChar = p.fieldChar;
 }
예제 #9
0
 public CECPoint(CECPoint p)
 {
     a         = p.a;
     b         = p.b;
     x         = p.x;
     y         = p.y;
     fieldChar = p.fieldChar;
 }
예제 #10
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);

            CDS        DS   = new CDS(p, a, b, n, xG);
            BigInteger d    = DS.genPrivateKey(192);
            CECPoint   Q    = DS.genPublicKey(d);
            CStribog   hash = new CStribog(256);

            /*
             * byte[] H = hash.GetHash(Encoding.Default.GetBytes("Message"));
             * string sign = DS.genDS(H, d);
             *
             * byte[] H2 = hash.GetHash(Encoding.Default.GetBytes("message"));
             * string sign2 = DS.genDS(H2, d);
             */

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

            byte[] H    = hash.GetHash(Encoding.Default.GetBytes(message));
            string sign = DS.genDS(H, d);

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

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

            byte[] H2 = hash.GetHash(Encoding.Default.GetBytes(message2));
            Console.WriteLine("Выберите файл содержащий цифровую подпись: ");
            path = Console.ReadLine();
            string signVer = readFile(path);
            //string sign2 = DS.genDS(H2, d);

            bool result = DS.verifDS(H2, signVer, Q);

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

            System.Console.ReadLine();
        }
예제 #11
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);
        }
예제 #12
0
        //проверка цифровой подписи.
        public bool verifDS(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);
            }
        }
예제 #13
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;
 }
예제 #14
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);
        }
예제 #15
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);
        }
예제 #16
0
        //проверка цифровой подписи.
        public bool verifDS(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);
        }