/*
*******************************************************************************
\file bign96.h
\brief Experimental Bign signatures of security level 96
\project bee2 [cryptographic library]
\created 2021.01.20
\version 2025.09.05
\copyright The Bee2 authors
\license Licensed under the Apache License, Version 2.0 (see LICENSE.txt).
*******************************************************************************
*/

/*!
*******************************************************************************
\file bign96.h
\brief Подпись Bign уровня 96
*******************************************************************************
*/

#ifndef __BIGN96_H
#define __BIGN96_H

#ifdef __cplusplus
extern "C" {
#endif

#include "bee2/crypto/bign.h"

/*!
*******************************************************************************
\file bign96.h

Подпись Bign96 -- это подпись Bign при снижении уровня стойкости до l = 96
и следующих корректировках:
1) уменьшается длина s0, первой часть подписи: с 96 битов до 80;
2) в детерминированном режиме выработки подписи (функция bign96Sign2) для
   построения одноразового личного ключа вместо алгоритма belt-wblock
   используется алгоритм belt-32block (шифрование полутора блоков).
   Последний алгоритм определен в СТБ 34.101.31-2020 как вспомогательный для
   алгоритма belt-fmt.

Повторяются соглашения и интерфейсы модуля bee2/crypto/bign.

\expect{ERR_BAD_INPUT} Все входные указатели корректны.
*******************************************************************************
*/

/*
*******************************************************************************
Управление параметрами
*******************************************************************************
*/


/*!	\brief Загрузка стандартных долговременных параметров

	В params загружаются стандартные долговременные параметры с именем name.
	Поддерживается только одно имя:
		"1.2.112.0.2.0.34.101.45.3.0".
	\return ERR_OK, если параметры успешно загружены, и код ошибки в
	противном случае.
*/
err_t bign96ParamsStd(
	bign_params* params,	/*!< [out] стандартные параметры */
	const char* name		/*!< [in] имя параметров */
);

/*!	\brief Проверка долговременных параметров

	Проверяется корректность долговременных параметров params.
	\return ERR_OK, если параметры корректны, и код ошибки
	в противном случае.
*/
err_t bign96ParamsVal(
	const bign_params* params	/*!< [in] долговременные параметры */
);

/*
*******************************************************************************
Управление ключами
*******************************************************************************
*/

/*!	\brief Генерация пары ключей

	При долговременных параметрах params генерируются личный privkey 
	и открытый pubkey ключи. При генерации используется генератор rng 
	и его состояние rng_state.
	\expect{ERR_BAD_PARAMS} Параметры params корректны.
	\expect{ERR_BAD_RNG} Генератор rng (с состоянием rng_state) корректен.
	\expect Используется криптографически стойкий генератор rng.
	\return ERR_OK, если ключи успешно сгенерированы, и код ошибки
	в противном случае.
*/
err_t bign96KeypairGen(
	octet privkey[24],			/*!< [out] личный ключ */
	octet pubkey[48],			/*!< [out] открытый ключ */
	const bign_params* params,	/*!< [in] долговременные параметры */
	gen_i rng,					/*!< [in] генератор случайных чисел */
	void* rng_state				/*!< [in/out] состояние генератора */
);

/*!	\brief Проверка пары ключей

	При долговременных параметрах params проверяется корректность
	личного ключа privkey и соответствие ему открытого ключа pubkey.
	\expect{ERR_BAD_PARAMS} Параметры params корректны.
	\return ERR_OK, если пара корректна, и код ошибки в противном случае.
*/
err_t bign96KeypairVal(
	const bign_params* params,	/*!< [in] долговременные параметры */
	const octet privkey[24],	/*!< [in] личный ключ */
	const octet pubkey[48]		/*!< [in] открытый ключ */
);

/*!	\brief Проверка открытого ключа

	При долговременных параметрах params проверяется корректность 
	открытого ключа pubkey.
	\expect{ERR_BAD_PARAMS} Параметры params корректны.
	\return ERR_OK, если ключ корректен, и код ошибки в противном случае.
*/
err_t bign96PubkeyVal(
	const bign_params* params,	/*!< [in] долговременные параметры */
	const octet pubkey[48]		/*!< [in] проверяемый ключ */
);

/*!	\brief Построение открытого ключа по личному

	При долговременных параметрах params по личному ключу privkey 
	строится открытый ключ pubkey.
	\expect{ERR_BAD_PARAMS} Параметры params корректны.
	\expect{ERR_BAD_PRIVKEY} Личный ключ privkey корректен.
	\return ERR_OK, если открытый ключ успешно построен, и код ошибки
	в противном случае.
*/
err_t bign96PubkeyCalc(
	octet pubkey[48],			/*!< [out] открытый ключ */
	const bign_params* params,	/*!< [in] долговременные параметры */
	const octet privkey[24]		/*!< [in] личный ключ */
);

/*
*******************************************************************************
Электронная цифровая подпись (ЭЦП)
*******************************************************************************
*/

/*!	\brief Выработка ЭЦП

	Вырабатывается подпись sig сообщения с хэш-значением hash, полученном
	с помощью алгоритма с идентификатором [oid_len]oid_der, заданным DER-кодом.
	Подпись вырабатывается на личном ключе privkey. При выработке ЭЦП
	используются долговременные параметры params и генератор rng
	с состоянием rng_state. 
	\expect{ERR_BAD_PARAMS} Параметры params корректны.
	\expect{ERR_BAD_OID} Идентификатор oid_der корректен.
	\expect{ERR_BAD_INPUT} Буферы sig и hash не пересекаются.
	\expect{ERR_BAD_PRIVKEY} Личный ключ privkey корректен.
	\expect{ERR_BAD_RNG} Генератор rng (с состоянием rng_state) корректен.
	\expect Генератор rng является криптографически стойким.
	\return ERR_OK, если подпись выработана, и код ошибки в противном
	случае.
*/
err_t bign96Sign(
	octet sig[34],				/*!< [out] подпись */
	const bign_params* params,	/*!< [in] долговременные параметры */
	const octet oid_der[],		/*!< [in] идентификатор хэш-алгоритма */
	size_t oid_len,				/*!< [in] длина oid_der в октетах */
	const octet hash[24],		/*!< [in] хэш-значение */
	const octet privkey[24],	/*!< [in] личный ключ */
	gen_i rng,					/*!< [in] генератор случайных чисел */
	void* rng_state				/*!< [in/out] состояние генератора */
);

/*!	\brief Детерминированная выработка ЭЦП

	Вырабатывается подпись sig сообщения с хэш-значением hash, полученном
	с помощью алгоритма с идентификатором [oid_len]oid_der, заданным DER-кодом.
	Подпись вырабатывается на личном ключе privkey. При выработке ЭЦП
	используются долговременные параметры params. Одноразовый личный ключ
	генерируется с использованием дополнительных данных [t_len]t.
	Если t == 0, то дополнительные данные не используются.
	\expect{ERR_BAD_PARAMS} Параметры params корректны.
	\expect{ERR_BAD_OID} Идентификатор oid_der корректен.
	\expect{ERR_BAD_INPUT} Буферы sig и hash не пересекаются.
	\expect{ERR_BAD_PRIVKEY} Личный ключ privkey корректен.
	\return ERR_OK, если подпись выработана, и код ошибки в противном
	случае.
*/
err_t bign96Sign2(
	octet sig[34],				/*!< [out] подпись */
	const bign_params* params,	/*!< [in] долговременные параметры */
	const octet oid_der[],		/*!< [in] идентификатор хэш-алгоритма */
	size_t oid_len,				/*!< [in] длина oid_der в октетах */
	const octet hash[24],		/*!< [in] хэш-значение */
	const octet privkey[24],	/*!< [in] личный ключ */
	const void* t,				/*!< [in] дополнительные данные */
	size_t t_len				/*!< [in] размер дополнительных данных */
);

/*!	\brief Проверка ЭЦП

	Проверяется ЭЦП sig сообщения с хэш-значением hash. При проверке
	используются долговременные параметры params и открытый ключ pubkey.
	Считается, что хэш-значение hash получено с помощью алгоритма
	с идентификатором [oid_len]oid_der, заданным DER-кодом.
	\expect{ERR_BAD_PARAMS} Параметры params корректны.
	\expect{ERR_BAD_OID} Идентификатор oid_der корректен.
	\expect{ERR_BAD_PUBKEY} Открытый ключ pubkey корректен.
	\return ERR_OK, если подпись корректна, и код ошибки в противном
	случае.
	\remark При нарушении ограничений на ЭЦП возвращается код ERR_BAD_SIG.
*/
err_t bign96Verify(
	const bign_params* params,	/*!< [in] долговременные параметры */
	const octet oid_der[],		/*!< [in] идентификатор хэш-алгоритма */
	size_t oid_len,				/*!< [in] длина oid_der в октетах */
	const octet hash[24],		/*!< [in] хэш-значение */
	const octet sig[34],		/*!< [in] подпись */
	const octet pubkey[48]		/*!< [in] открытый ключ */
);

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif /* __BIGN96_H */
