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

            return(Q);
        }
Пример #4
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);
        }
Пример #5
0
 public CECPoint(CECPoint p)
 {
     a         = p.a;
     b         = p.b;
     x         = p.x;
     y         = p.y;
     fieldChar = p.fieldChar;
 }
Пример #6
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);
        }
Пример #7
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);
            }
        }
Пример #8
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);
        }