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