Esempio n. 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.");
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Generate public and private key pair.
        /// </summary>
        /// <returns></returns>
        public static KeyValuePair <GXPrivateKey, GXPublicKey> GenerateKeyPair(Ecc scheme)
        {
            byte[]       raw = GetRandomNumber(scheme).ToArray();
            GXPrivateKey pk  = GXPrivateKey.FromRawBytes(raw);
            GXPublicKey  pub = pk.GetPublicKey();

            return(new KeyValuePair <GXPrivateKey, GXPublicKey>(pk, pub));
        }
Esempio n. 3
0
        /// <summary>
        /// Verify that signature matches the data.
        /// </summary>
        /// <param name="signature">Generated signature.</param>
        /// <param name="data">Data to valuate.</param>
        /// <returns></returns>
        public bool Verify(byte[] signature, byte[] data)
        {
            GXBigInteger msg;

            if (PublicKey == null)
            {
                if (PrivateKey == null)
                {
                    throw new ArgumentNullException("Invalid private key.");
                }
                PublicKey = PrivateKey.GetPublicKey();
            }
            if (PublicKey.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));
                }
            }
            GXByteBuffer pk   = new GXByteBuffer(PublicKey.RawValue);
            GXByteBuffer bb   = new GXByteBuffer(signature);
            int          size = SchemeSize(PublicKey.Scheme);
            GXBigInteger sigR = new GXBigInteger(bb.SubArray(0, size));
            GXBigInteger sigS = new GXBigInteger(bb.SubArray(size, size));
            GXBigInteger inv  = sigS;

            inv.Inv(curve.N);
            // Calculate u1 and u2.
            GXEccPoint u1 = new GXEccPoint(curve.G.x, curve.G.y, new GXBigInteger(1));
            GXEccPoint u2 = new GXEccPoint(new GXBigInteger(pk.SubArray(1, size)),
                                           new GXBigInteger(pk.SubArray(1 + size, size)), new GXBigInteger(1));
            GXBigInteger n = msg;

            n.Multiply(inv);
            n.Mod(curve.N);
            Multiply(u1, n, curve.N, curve.A, curve.P);
            n = new GXBigInteger(sigR);
            n.Multiply(inv);
            n.Mod(curve.N);
            Multiply(u2, n, curve.N, curve.A, curve.P);
            u1.z = new GXBigInteger(1);
            u2.z = new GXBigInteger(1);
            JacobianAdd(u1, u2, curve.A, curve.P);
            FromJacobian(u1, curve.P);
            return(sigR.Compare(u1.x) == 0);
        }
        /// <summary>
        /// Create the private key from DER.
        /// </summary>
        /// <param name="key">DER Base64 coded string.</param>
        /// <returns></returns>
        public static GXPrivateKey FromDer(string der)
        {
            der = der.Replace("\r\n", "");
            der = der.Replace("\n", "");
            byte[]         key = GXCommon.FromBase64(der);
            GXAsn1Sequence seq = (GXAsn1Sequence)GXAsn1Converter.FromByteArray(key);

            if ((sbyte)seq[0] > 3)
            {
                throw new ArgumentOutOfRangeException("Invalid private key version.");
            }
            List <object>      tmp   = (List <object>)seq[2];
            GXPrivateKey       value = new GXPrivateKey();
            X9ObjectIdentifier id    = X9ObjectIdentifierConverter.FromString(tmp[0].ToString());

            switch (id)
            {
            case X9ObjectIdentifier.Prime256v1:
                value.Scheme = Ecc.P256;
                break;

            case X9ObjectIdentifier.Secp384r1:
                value.Scheme = Ecc.P384;
                break;

            default:
                if (id == X9ObjectIdentifier.None)
                {
                    throw new ArgumentOutOfRangeException("Invalid private key " + tmp[0].ToString() + ".");
                }
                else
                {
                    throw new ArgumentOutOfRangeException("Invalid private key " + id + " " + tmp[0].ToString() + ".");
                }
            }
            value.RawValue = (byte[])seq[1];
            if (seq[3] is byte[])
            {
                value.publicKey = GXPublicKey.FromRawBytes((byte[])seq[3]);
            }
            else
            {
                //Open SSL PEM.
                value.publicKey = GXPublicKey.FromRawBytes(((GXAsn1BitString)((List <object>)seq[3])[0]).Value);
            }
            return(value);
        }
        /// <summary>
        /// Get public key from private key.
        /// </summary>
        /// <param name="scheme">Used scheme.</param>
        /// <param name="privateKey">Private key bytes.</param>
        /// <returns>Public key.</returns>
        public GXPublicKey GetPublicKey()
        {
            GXBigInteger secret = new GXBigInteger(RawValue);
            GXCurve      curve  = new GXCurve(Scheme);
            GXEccPoint   p      = new GXEccPoint(curve.G.x, curve.G.y, new GXBigInteger(1));

            p = GXEcdsa.JacobianMultiply(p, secret, curve.N, curve.A, curve.P);
            GXEcdsa.FromJacobian(p, curve.P);
            GXByteBuffer key = new GXByteBuffer(65);

            //Public key is un-compressed format.
            key.SetUInt8(4);
            byte[] tmp = p.x.ToArray();
            key.Set(tmp, tmp.Length % 32, 32);
            tmp = p.y.ToArray();
            key.Set(tmp, tmp.Length % 32, 32);
            return(GXPublicKey.FromRawBytes(key.Array()));
        }
        /// <summary>
        /// Create the public key from raw bytes.
        /// </summary>
        /// <param name="key">Raw data</param>
        /// <returns>Public key.</returns>
        public static GXPublicKey FromRawBytes(byte[] key)
        {
            GXPublicKey value = new GXPublicKey();

            if (key.Length == 65)
            {
                value.Scheme   = Ecc.P256;
                value.RawValue = key;
            }
            else if (key.Length == 97)
            {
                value.Scheme   = Ecc.P384;
                value.RawValue = key;
            }
            else
            {
                throw new ArgumentOutOfRangeException("Invalid public key.");
            }
            return(value);
        }
Esempio n. 7
0
        /// <summary>
        /// Verify that signature matches the data.
        /// </summary>
        /// <param name="signature">Generated signature.</param>
        /// <param name="data">Data to valuate.</param>
        /// <returns></returns>
        public bool Verify(byte[] signature, byte[] data)
        {
            GXBigInteger msg;

            using (SHA256 sha = new SHA256CryptoServiceProvider())
            {
                msg = new GXBigInteger(sha.ComputeHash(data));
            }
            if (PublicKey == null)
            {
                PublicKey = PrivateKey.GetPublicKey();
            }
            GXByteBuffer pk   = new GXByteBuffer(PublicKey.RawValue);
            GXByteBuffer bb   = new GXByteBuffer(signature);
            GXBigInteger sigR = new GXBigInteger(bb.SubArray(0, 32));
            GXBigInteger sigS = new GXBigInteger(bb.SubArray(32, 32));
            GXBigInteger inv  = sigS;

            inv.Inv(curve.N);
            // Calculate u1 and u2.
            GXEccPoint   u1 = new GXEccPoint(curve.G.x, curve.G.y, new GXBigInteger(1));
            GXEccPoint   u2 = new GXEccPoint(new GXBigInteger(pk.SubArray(1, 32)), new GXBigInteger(pk.SubArray(33, 32)), new GXBigInteger(1));
            GXBigInteger n  = msg;

            n.Multiply(inv);
            n.Mod(curve.N);
            Multiply(u1, n, curve.N, curve.A, curve.P);
            n = new GXBigInteger(sigR);
            n.Multiply(inv);
            n.Mod(curve.N);
            Multiply(u2, n, curve.N, curve.A, curve.P);
            //  add = Math.add(u1, u2, P = curve.P, A = curve.A)
            u1.z = new GXBigInteger(1);
            u2.z = new GXBigInteger(1);
            JacobianAdd(u1, u2, curve.A, curve.P);
            FromJacobian(u1, curve.P);
            return(sigR.Compare(u1.x) == 0);
        }
Esempio n. 8
0
        /// <summary>
        /// Create the public key from raw bytes.
        /// </summary>
        /// <param name="key">Raw data</param>
        /// <returns>Public key.</returns>
        public static GXPublicKey FromRawBytes(byte[] key)
        {
            GXPublicKey value = new GXPublicKey();

            if (key.Length == 65)
            {
                value.Scheme   = Ecc.P256;
                value.RawValue = key;
            }
            else if (key.Length == 97)
            {
                value.Scheme   = Ecc.P384;
                value.RawValue = key;
            }
            else if (key.Length == 64)
            {
                //Compression tag is not send in DLMS messages.
                value.Scheme      = Ecc.P256;
                value.RawValue    = new byte[65];
                value.RawValue[0] = 4;
                Array.Copy(key, 0, value.RawValue, 1, 64);
            }
            else if (key.Length == 96)
            {
                //Compression tag is not send in DLMS messages.
                value.Scheme      = Ecc.P384;
                value.RawValue    = new byte[96];
                value.RawValue[0] = 4;
                Array.Copy(key, 0, value.RawValue, 1, 96);
            }
            else
            {
                throw new ArgumentOutOfRangeException("Invalid public key.");
            }
            return(value);
        }
Esempio n. 9
0
        /// <summary>
        /// Generate shared secret from public and private key.
        /// </summary>
        /// <param name="publicKey">Public key.</param>
        /// <returns>Generated secret.</returns>
        public byte[] GenerateSecret(GXPublicKey publicKey)
        {
            if (PrivateKey == null)
            {
                throw new ArgumentNullException("Invalid private key.");
            }
            if (PrivateKey.Scheme != publicKey.Scheme)
            {
                throw new ArgumentNullException("Private key scheme is different than public key.");
            }
            GXByteBuffer bb = new GXByteBuffer();

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

            p = JacobianMultiply(p, pk, curve.N, curve.A, curve.P);
            FromJacobian(p, curve.P);
            return(p.x.ToArray());
        }
Esempio n. 10
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="key">Public key.</param>
 public GXEcdsa(GXPublicKey key) : this(key.Scheme)
 {
     PublicKey = key;
 }