Exemple #1
0
        /// <summary>
        /// Generates a digital signature for the specified hash value.
        /// </summary>
        /// <param name="hash">
        /// The hash value of the data that is being signed.
        /// </param>
        /// <returns>
        /// A digital signature that consists of the given hash value encrypted with the private key.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// The <paramref name="hash"/> parameter is <see langword="null"/>.
        /// </exception>
        public override byte[] SignHash(byte[] hash)
        {
            if (hash == null)
            {
                throw new ArgumentNullException(nameof(hash));
            }

            ThrowIfDisposed();

            if (KeySize / 8 != hash.Length)
            {
                throw new CryptographicException(CryptographyStrings.CryptographicInvalidHashSize(KeySize / 8));
            }

            var keySizeInByted = KeySize / 8;

            if (!_parametersSet)
            {
                GenerateKey(GetDefaultCurve());
            }

            var subgroupOrder = CryptoUtils.Normalize(new BigInteger(_curve.Order), _modulus) /
                                CryptoUtils.Normalize(new BigInteger(_curve.Cofactor), _modulus);

            var e = CryptoUtils.Normalize(new BigInteger(hash), _modulus) % subgroupOrder;

            if (e == BigInteger.Zero)
            {
                e = BigInteger.One;
            }

            BigInteger
                prime = CryptoUtils.Normalize(new BigInteger(_curve.Prime), _modulus),
                a = CryptoUtils.Normalize(new BigInteger(_curve.A), _modulus),
                d = CryptoUtils.Normalize(new BigInteger(_privateKey), _modulus),
                k, r, s;

            var rgb = new byte[keySizeInByted];

            do
            {
                do
                {
                    do
                    {
                        CryptoUtils.StaticRandomNumberGenerator.GetBytes(rgb);
                        k = CryptoUtils.Normalize(new BigInteger(rgb), _modulus);
                    } while (k <= BigInteger.Zero || k >= subgroupOrder);

                    r = BigIntegerPoint.Multiply(new BigIntegerPoint(_curve.G, _modulus), k, prime, a).X;
                } while (r == BigInteger.Zero);

                s = (r * d + k * e) % subgroupOrder;
            } while (s == BigInteger.Zero);

            byte[]
            signature = new byte[keySizeInByted * 2],
            array = s.ToByteArray();

            Buffer.BlockCopy(array, 0, signature, 0, Math.Min(array.Length, keySizeInByted));
            array = r.ToByteArray();
            Buffer.BlockCopy(array, 0, signature, keySizeInByted, Math.Min(array.Length, keySizeInByted));

            return(signature);
        }
Exemple #2
0
        /// <summary>
        /// Verifies a digital signature against the specified hash value.
        /// </summary>
        /// <param name="hash">
        /// The hash value of a block of data.
        /// </param>
        /// <param name="signature">
        /// The digital signature to be verified.
        /// </param>
        /// <returns>
        /// <see langword="true"/> if the hash value equals the decrypted signature;
        /// otherwise, <see langword="false"/>.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// The <paramref name="hash"/> parameter is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// The <paramref name="signature"/> parameter is <see langword="null"/>.
        /// </exception>
        public override bool VerifyHash(byte[] hash, byte[] signature)
        {
            if (hash == null)
            {
                throw new ArgumentNullException(nameof(hash));
            }
            if (signature == null)
            {
                throw new ArgumentNullException(nameof(signature));
            }

            ThrowIfDisposed();

            if (KeySize / 8 != hash.Length)
            {
                throw new CryptographicException(CryptographyStrings.CryptographicInvalidHashSize(KeySize / 8));
            }
            if (KeySize / 4 != signature.Length)
            {
                throw new CryptographicException(CryptographyStrings.CryptographicInvalidSignatureSize(KeySize / 4));
            }

            // There is no necessity to generate new parameter, just return false
            if (!_parametersSet)
            {
                return(false);
            }

            var keySizeInByted = KeySize / 8;

            var subgroupOrder = CryptoUtils.Normalize(new BigInteger(_curve.Order), _modulus) /
                                CryptoUtils.Normalize(new BigInteger(_curve.Cofactor), _modulus);

            var array = new byte[keySizeInByted];

            Buffer.BlockCopy(signature, 0, array, 0, keySizeInByted);
            var s = CryptoUtils.Normalize(new BigInteger(array), _modulus);

            if (s < BigInteger.One || s > subgroupOrder)
            {
                return(false);
            }

            Buffer.BlockCopy(signature, keySizeInByted, array, 0, keySizeInByted);
            var r = CryptoUtils.Normalize(new BigInteger(array), _modulus);

            if (r < BigInteger.One || r > subgroupOrder)
            {
                return(false);
            }

            var e = CryptoUtils.Normalize(new BigInteger(hash), _modulus) % subgroupOrder;

            if (e == BigInteger.Zero)
            {
                e = BigInteger.One;
            }

            BigInteger
                v     = BigInteger.ModPow(e, subgroupOrder - 2, subgroupOrder),
                z1    = (s * v) % subgroupOrder,
                z2    = (subgroupOrder - r) * v % subgroupOrder,
                prime = CryptoUtils.Normalize(new BigInteger(_curve.Prime), _modulus),
                a     = CryptoUtils.Normalize(new BigInteger(_curve.A), _modulus);

            var c = BigIntegerPoint.Add(
                BigIntegerPoint.Multiply(new BigIntegerPoint(_curve.G, _modulus), z1, prime, a),
                BigIntegerPoint.Multiply(new BigIntegerPoint(_publicKey, _modulus), z2, prime, a),
                prime);

            return(c.X == r);
        }
Exemple #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="HMACStreebog256"/>
 /// class with a randomly generated key.
 /// </summary>
 public HMACStreebog256()
     : this(CryptoUtils.GenerateRandomBytes(64))
 {
 }
Exemple #4
0
 public BigIntegerPoint(ECPoint point, BigInteger modulus)
 {
     X = CryptoUtils.Normalize(new BigInteger(point.X), modulus);
     Y = CryptoUtils.Normalize(new BigInteger(point.Y), modulus);
 }
Exemple #5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="CMACMagma"/> class.
 /// </summary>
 public CMACMagma()
     : this(CryptoUtils.GenerateRandomBytes(32))
 {
 }
Exemple #6
0
 /// <summary>
 /// Generates a random key to be used for the algorithm.
 /// </summary>
 public override void GenerateKey()
 {
     KeyValue = CryptoUtils.GenerateRandomBytes(KeySizeValue / 8);
 }
Exemple #7
0
 /// <summary>
 /// Generates a random initialization vector to be used for the algorithm.
 /// </summary>
 public override void GenerateIV()
 {
     IVValue = CryptoUtils.GenerateRandomBytes(FeedbackSizeValue / 8);
 }