//! \~\file pidigest.h
//! \~\ingroup Digest
//! \~\brief
//! \~english Digest calculation helpers
//! \~russian Вспомогательные методы вычисления хэш-сумм
/*
	PIP - Platform Independent Primitives
	Digest algorithms
	Ivan Pelipenko peri4ko@yandex.ru

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU Lesser General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef pidigest_h
#define pidigest_h

#include "pibytearray.h"
#include "piconstchars.h"

//! \class PIDigest
//! \~\ingroup Digest
//! \~\brief
//! \~english One-shot digest API for supported algorithms.
//! \~russian Одношаговый API хэширования для поддерживаемых алгоритмов.
class PIP_EXPORT PIDigest {
public:
	//! \~english Supported digest algorithms.
	//! \~russian Поддерживаемые алгоритмы хэширования.
	enum class Type {
		SHA1 /** \~english SHA-1 \~russian SHA-1 */,

		SHA2_224 /** \~english SHA-2 with 224-bit digest \~russian SHA-2 с дайджестом 224 бита */,
		SHA2_256 /** \~english SHA-2 with 256-bit digest \~russian SHA-2 с дайджестом 256 бит */,
		SHA2_384 /** \~english SHA-2 with 384-bit digest \~russian SHA-2 с дайджестом 384 бита */,
		SHA2_512 /** \~english SHA-2 with 512-bit digest \~russian SHA-2 с дайджестом 512 бит */,
		SHA2_512_224 /** \~english SHA-512/224 \~russian SHA-512/224 */,
		SHA2_512_256 /** \~english SHA-512/256 \~russian SHA-512/256 */,

		MD2 /** \~english MD2 \~russian MD2 */,
		MD4 /** \~english MD4 \~russian MD4 */,
		MD5 /** \~english MD5 \~russian MD5 */,

		BLAKE2s_128 /** \~english BLAKE2s with 128-bit digest \~russian BLAKE2s с дайджестом 128 бит */,
		BLAKE2s_160 /** \~english BLAKE2s with 160-bit digest \~russian BLAKE2s с дайджестом 160 бит */,
		BLAKE2s_224 /** \~english BLAKE2s with 224-bit digest \~russian BLAKE2s с дайджестом 224 бита */,
		BLAKE2s_256 /** \~english BLAKE2s with 256-bit digest \~russian BLAKE2s с дайджестом 256 бит */,
		BLAKE2b_128 /** \~english BLAKE2b with 128-bit digest \~russian BLAKE2b с дайджестом 128 бит */,
		BLAKE2b_160 /** \~english BLAKE2b with 160-bit digest \~russian BLAKE2b с дайджестом 160 бит */,
		BLAKE2b_224 /** \~english BLAKE2b with 224-bit digest \~russian BLAKE2b с дайджестом 224 бита */,
		BLAKE2b_256 /** \~english BLAKE2b with 256-bit digest \~russian BLAKE2b с дайджестом 256 бит */,
		BLAKE2b_384 /** \~english BLAKE2b with 384-bit digest \~russian BLAKE2b с дайджестом 384 бита */,
		BLAKE2b_512 /** \~english BLAKE2b with 512-bit digest \~russian BLAKE2b с дайджестом 512 бит */,

		SipHash_2_4_64 /** \~english SipHash-2-4 with 64-bit output \~russian SipHash-2-4 с выходом 64 бита */,
		SipHash_2_4_128 /** \~english SipHash-2-4 with 128-bit output \~russian SipHash-2-4 с выходом 128 бит */,
		HalfSipHash_2_4_32 /** \~english HalfSipHash-2-4 with 32-bit output \~russian HalfSipHash-2-4 с выходом 32 бита */,
		HalfSipHash_2_4_64 /** \~english HalfSipHash-2-4 with 64-bit output \~russian HalfSipHash-2-4 с выходом 64 бита */,

		Count /** \~english Number of supported algorithms \~russian Количество поддерживаемых алгоритмов */
	};


	//! \~english Returns digest length in bytes for algorithm "type".
	//! \~russian Возвращает длину дайджеста в байтах для алгоритма "type".
	static int hashLength(Type type);

	//! \~english Returns internal block length in bytes for algorithm "type".
	//! \~russian Возвращает внутреннюю длину блока в байтах для алгоритма "type".
	static int blockLength(Type type);

	//! \~english Returns stable algorithm name for "type".
	//! \~russian Возвращает стабильное имя алгоритма для "type".
	static PIConstChars typeName(Type type);


	//! \~english Calculates digest of message "msg" with algorithm "type".
	//! \~russian Вычисляет хэш сообщения "msg" алгоритмом "type".
	static PIByteArray calculate(const PIByteArray & msg, Type type);

	//! \~english Calculates keyed digest for algorithms with native key support, otherwise returns empty array.
	//! \~russian Вычисляет keyed digest для алгоритмов с нативной поддержкой ключа, иначе возвращает пустой массив.
	static PIByteArray calculateWithKey(const PIByteArray & msg, const PIByteArray & key, Type type);

	//! \~english Calculates HMAC for message "msg" and key "key" with algorithm "type".
	//! \~russian Вычисляет HMAC для сообщения "msg" и ключа "key" алгоритмом "type".
	static PIByteArray HMAC(const PIByteArray & msg, const PIByteArray & key, PIDigest::Type type);
};

#endif
