示例#1
0
        /// <summary>
        /// Check that this is correct public key.
        /// </summary>
        /// <remarks>
        /// This method can be used to verify that public and private key are on the curve.
        /// </remarks>
        public static void Validate(GXPublicKey publicKey)
        {
            if (publicKey == null)
            {
                throw new ArgumentNullException("Invalid public key.");
            }
            GXByteBuffer bb = new GXByteBuffer();

            bb.Set(publicKey.RawValue);
            int          size  = SchemeSize(publicKey.Scheme);
            GXBigInteger x     = new GXBigInteger(bb.SubArray(1, size));
            GXBigInteger y     = new GXBigInteger(bb.SubArray(1 + size, size));
            GXCurve      curve = new GXCurve(publicKey.Scheme);

            y.Multiply(y);
            y.Mod(curve.P);

            GXBigInteger tmpX = new GXBigInteger(x);

            tmpX.Multiply(x);
            tmpX.Mod(curve.P);
            tmpX.Add(curve.A);
            tmpX.Multiply(x);
            tmpX.Add(curve.B);
            tmpX.Mod(curve.P);
            if (y.Compare(tmpX) != 0)
            {
                throw new ArgumentException("Public key validate failed. Public key is not valid ECDSA public key.");
            }
        }
示例#2
0
        /// <summary>
        /// Convert ECC point to Jacobian.
        /// </summary>
        /// <param name="p">ECC point.</param>
        /// <param name="A"></param>
        /// <param name="P">Prime number.</param>
        /// <returns></returns>
        private static GXEccPoint JacobianDouble(GXEccPoint p, GXBigInteger A, GXBigInteger P)
        {
            GXBigInteger ysq = new GXBigInteger(p.y);

            ysq.Multiply(p.y);
            ysq.Mod(P);
            GXBigInteger S = new GXBigInteger(p.x);

            S.Multiply(new GXBigInteger(4));
            S.Multiply(ysq);
            S.Mod(P);
            GXBigInteger M = new GXBigInteger(p.x);

            M.Multiply(p.x);
            M.Multiply(new GXBigInteger(3));
            GXBigInteger tmp = new GXBigInteger(p.z);

            tmp.Multiply(p.z);
            tmp.Multiply(p.z);
            tmp.Multiply(p.z);
            tmp.Multiply(A);
            M.Add(tmp);
            M.Mod(P);
            //nx
            GXBigInteger nx = new GXBigInteger(M);

            nx.Multiply(M);
            tmp = new GXBigInteger(S);
            tmp.Multiply(new GXBigInteger(2));
            nx.Sub(tmp);
            nx.Mod(P);
            //ny
            GXBigInteger ny = new GXBigInteger(S);

            ny.Sub(nx);
            ny.Multiply(M);
            tmp = new GXBigInteger(ysq);
            tmp.Multiply(ysq);
            tmp.Multiply(new GXBigInteger(8));
            ny.Sub(tmp);
            ny.Mod(P);
            //nz
            GXBigInteger nz = new GXBigInteger(p.y);

            nz.Multiply(p.z);
            nz.Multiply(new GXBigInteger(2));
            nz.Mod(P);
            return(new GXEccPoint(nx, ny, nz));
        }
示例#3
0
        /// <summary>
        /// Sign given data using public and private key.
        /// </summary>
        /// <param name="data">Data to sign.</param>
        /// <returns>Signature</returns>
        public byte[] Sign(byte[] data)
        {
            if (PrivateKey == null)
            {
                throw new ArgumentException("Invalid private key.");
            }
            GXBigInteger msg;

            if (PrivateKey.Scheme == Ecc.P256)
            {
                using (SHA256 sha = new SHA256CryptoServiceProvider())
                {
                    msg = new GXBigInteger(sha.ComputeHash(data));
                }
            }
            else
            {
                using (SHA384 sha = new SHA384CryptoServiceProvider())
                {
                    msg = new GXBigInteger(sha.ComputeHash(data));
                }
            }
            GXBigInteger pk = new GXBigInteger(PrivateKey.RawValue);
            GXEccPoint   p;
            GXBigInteger n;
            GXBigInteger r;
            GXBigInteger s;

            do
            {
                n = GetRandomNumber(PrivateKey.Scheme);
                p = new GXEccPoint(curve.G.x, curve.G.y, new GXBigInteger(1));
                Multiply(p, n, curve.N, curve.A, curve.P);
                r = p.x;
                r.Mod(curve.N);
                n.Inv(curve.N);
                //s
                s = new GXBigInteger(r);
                s.Multiply(pk);
                s.Add(msg);
                s.Multiply(n);
                s.Mod(curve.N);
            } while (r.IsZero || s.IsZero);
            GXByteBuffer signature = new GXByteBuffer();

            signature.Set(r.ToArray());
            signature.Set(s.ToArray());
            return(signature.Array());
        }
示例#4
0
        /// <summary>
        /// Sign given data using public and private key.
        /// </summary>
        /// <param name="data">Data to sign.</param>
        /// <returns>Signature</returns>
        public byte[] Sign(byte[] data)
        {
            if (PrivateKey == null)
            {
                throw new ArgumentException("Invalid private key.");
            }
            GXBigInteger msg;

            using (SHA256 sha = new SHA256CryptoServiceProvider())
            {
                msg = new GXBigInteger(sha.ComputeHash(data));
            }
            GXBigInteger pk = new GXBigInteger(PrivateKey.RawValue);
            GXEccPoint   p;
            GXBigInteger n = new GXBigInteger(10);
            GXBigInteger r;
            GXBigInteger s;

            do
            {
                if (CustomRandomNumber != null)
                {
                    n = CustomRandomNumber;
                }
                else
                {
                    n = GetRandomNumber(PrivateKey.Scheme);
                }
                p = new GXEccPoint(curve.G.x, curve.G.y, new GXBigInteger(1));
                Multiply(p, n, curve.N, curve.A, curve.P);
                r = p.x;
                r.Mod(curve.N);
                n.Inv(curve.N);
                //s
                s = new GXBigInteger(r);
                s.Multiply(pk);
                s.Add(msg);
                s.Multiply(n);
                s.Mod(curve.N);
            } while (r.IsZero || s.IsZero);

            byte recoveryId;

            if (p.y.IsOne)
            {
                recoveryId = 1;
            }
            else
            {
                recoveryId = 0;
            }
            if (p.y.Compare(curve.N) == 1)
            {
                recoveryId += 2;
            }
            GXByteBuffer signature = new GXByteBuffer();

            signature.Set(r.ToArray());
            signature.Set(s.ToArray());
            return(signature.Array());
        }