/// <summary> /// Attempts to validate a message tag and then decrypts the message if validation was successful. /// </summary> /// <param name="source"></param> /// <param name="destination"></param> /// <param name="work"></param> /// <param name="tag"></param> public void Decrypt(MemoryStream source, Stream destination, Stream work, ReadOnlySpan <byte> tag) { if (source.IsNull()) { throw new ArgumentNullException(paramName: nameof(source)); } if (destination.IsNull()) { throw new ArgumentNullException(paramName: nameof(destination)); } if (work.IsNull()) { throw new ArgumentNullException(paramName: nameof(work)); } ComputeTag(source, work, m_aad); source.Position = 0L; work.Position = 0L; if (Operations.CompareInConstantTime(m_poly1305.ComputeHash(work), tag)) { m_chaCha20.Transform(source, destination); } else { throw new CryptographicException(message: MESSAGE_AUTHENTICATION_ERROR); } }
/// <summary> /// Verifies a password by comparing it against the derived cryptographic key value; returns false if the values are not equal. /// </summary> /// <param name="keyLength">The length of the derived key value (in bytes).</param> /// <param name="hash">The password hash that will be verified.</param> public bool Validate(int keyLength, ReadOnlySpan <byte> hash) => Operations.CompareInConstantTime(Generate(keyLength), hash);