#ifndef CE2_DH_KG_H
#define CE2_DH_KG_H

/*
* All the includes that are needed for code using this module to
* compile correctly should be #included here.
*/
#include "CE2_DH.h"
#include "CE2_HASH.h"

#ifdef __cplusplus
extern "C"
{
#endif

/*
*  Object name     :  CE2_DH_KG.h
*/

/**
*  Object %name    : %CE2_DH_KG.h
*  State           :  %state%
*  Creation date   :  16 Dec. 2007
*  Last modified   :  %modify_time% 
*/
/** @file
*  \brief This module defines the API that supports Diffie-Hellman domain 
*  parameters and key generation and checking according to ANSI X9.42.
*
*  \version CE2_DH_KG.h #1:incl:
*  \author Aliaksandr Masiuk
*
*  \remarks Copyright (C) 2007 by Discretix Technologies Ltd.
*           All Rights reserved
*/

/************************ Defines ******************************/

#define CE2_DH_SEED_MIN_SIZE_IN_BYTES    CE2_HASH_SHA1_DIGEST_SIZE_IN_BYTES  /*20 bytes */
#define CE2_DH_SEED_MIN_SIZE_IN_BITS     (CE2_DH_SEED_MIN_SIZE_IN_BYTES * 8) /* 160 bits */   

/** The following defines are for the readability of the user*/
#define CE2_DHPubKey_t  CE2RSAPubKey_t

#define CE2_DH_MAX_VALID_KEY_SIZE_VALUE_IN_BITS  CE2_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS
#define CE2_DH_MIN_VALID_KEY_SIZE_VALUE_IN_BITS  1024

#define CE2_DH_MAX_MOD_SIZE_IN_BYTES   (CE2_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS / sizeof(DxUint32_t))

#define CE2_DH_MAX_MOD_BUFFER_SIZE_IN_WORDS   CE2_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS

/************************ Enums ********************************/
/************************ Typedefs  ****************************/
/************************ Structs  ******************************/
/************************ Public Variables **********************/
/************************ Public Functions **********************/

/**
****************************************************************
* Function Name: 
*  CE2_DH_CreateDomainParams
*
* Inputs:
* @param[in]  modPSizeBits       - The  modulus (prime) P size in bits equal 256*n, where n >= 4. 
* @param[in]  orderQSizeBits     - The size of order of generator in bits. Must be m >= 160 and
*                                  multiple of 32 bits. According to ANSI X9.30-1: m = 160.
* @param[in]  seedSizeBits       - The  seed size in bytes. Requirements:  seedSizeBytes >= 20,
*                                  seedSizeBytes <= modPSizeBytes (the last requiered by implementation).
* @param[out] modP_ptr           - The prime modulus P of structure P = J*Q + 1, where Q is prime
*                                  and j is an integer. Size of the buffer for output generated value must 
*                                  be not less, than modulus size. 
* @param[out] orderQ_ptr         - The pointer to the order Q of generator. Size of the buffer for output 
*                                  generated value must be not less, than order size. 
* @param[out] generatorG_ptr     - The pointer to the generator of multiplicative subgroup in GF(P).
*                                  Size of the buffer for output generated value must be not less, 
*                                  than modulus size. If the pointer == NULL, the function not puts this 
*                                  parametr out (in this case generGsizeBytes_ptr must be set to NULL also, 
*                                  otherwise the function returns an error). Size of the buffer must be not less,
*                                  than modulus size. 
* @param[in/out] generGsizeBytes_ptr- The pointer to the word-buffer, containing the generator size value (in bytes). 
*                                  If output of generator is needed, the user must the set size value equalled to size 
*                                  of allocated buffer, and the function returns the actual size of generator in bytes. 
* @param[out] factorJ_ptr        - The pointer to buffer for integer factor J. If the pointer == NULL, the function 
*                                  not puts this parametr out  (in this case JsizeBytes_ptr must be set to NULL also, 
*                                  otherwise the function returns an error). Size of the buffer must be not less,
*                                  than ( modPSizesBytes - orderQSizeBytes + 1 ). 
* @param[in/out] JsizeBytes_ptr  - The pointer to size of integer factor J. If the pointer == NULL, 
*                                  the function not puts this parametr out. If output of the factor J is needed, the
*                                  user must set the J size value equal to the size of allocated buffer, and the 
*                                  function returns the actual size of J in bytes. 
* @param[in/out] seedS_ptr       - The random seed used for generation of primes. If the pointer == NULL,  
*                                  the function not puts this parametr out. Size of the buffer for output 
*                                  generated value must be not less, than passed seed size. 
* @param[in] generateSeed        - The flag defining whether the seed generated randomly  by the function
*                                  (generateSeed = 1) or it is passed by the input (generateSeed = 0).                                 
* @param[out] pgenCounter_ptr    - The pointer to counter of tries to generate the primes. If the pointer == NULL, 
*                                  the function not puts this parametr out.
*
* Outputs: @returns \b
*  CE2Error_t  
*  - CE2_OK - On success
*  - Otherwise - error code:
*   - CE2_DH_INVALID_ARGUMENT_POINTER_ERROR
*   - CE2_DH_INVALID_MODULUS_SIZE_ERROR
*   - CE2_DH_INVALID_ORDER_SIZE_ERROR
*   - CE2_DH_INVALID_SEED_SIZE_ERROR
*   - CE2_DH_INVALID_GENERATOR_PTR_OR_SIZE_ERROR
*   - CE2_DH_INVALID_J_FACTOR_PTR_OR_SIZE_ERROR
*   - CE2_LLF_DH_MODULE_ERROR_BASE
*
* \brief \b
* Description:
*  The function generates a DH (DLP) domain parameters in GF(P) (see X9.42-2001)
*
*     Note:  1. Input and Output vectors are in big endianness (high most byte is left most).
*            2. For reliability of checking of input parameters, in case that the user don't wont output of
*               some parameters (generator or factorJ), he must set both - a pointer to appropriate buffer and a 
*               pointer to its size equalled to NULL for these parameters, otherwise the function returns an error.
*            2. In case of any error the function may clean the output buffers. 
*
* \b
* Algorithm:
*  -# Verify input parameters for validity;
*  -# Call low level function LLF_DH_CreateDomainParams
*     to create domain params data with using LibTomCrypt.
***************************************************************/
CE2CIMPORT_C CE2Error_t CE2_DH_CreateDomainParams(
                          DxUint32_t          modPsizeBits,             /*in */
                          DxUint32_t          orderQsizeBits,           /*in */
                          DxUint32_t          seedSizeBits,             /*in */
                          DxUint8_t          *modP_ptr,                 /*out*/  
                          DxUint8_t          *orderQ_ptr,               /*out*/
                          DxUint8_t          *generatorG_ptr,           /*out*/
						  DxUint32_t         *generGsizeBytes_ptr,      /*in/out*/
                          DxUint8_t          *factorJ_ptr,              /*out*/
                          DxUint32_t         *JsizeBytes_ptr,           /*in/out*/ 
                          DxUint8_t          *seedS_ptr,                /*in/out*/
                          DxInt8_t            generateSeed,             /*in*/ 
                          DxUint32_t         *pgenCounter_ptr);         /*out*/

/**
****************************************************************
* Function Name: 
*  CE2_DH_CreateDomainParams
*
* Inputs:
* @param[out] modP_ptr           - The prime modulus P. Must be of structure P = j*Q + 1, 
*                                  where Q is prime and j is an integer.
* @param[in]  modPSizeBytes      - The modulus (prime) size in bytes. Size in bits must be 
*                                  equal 256*n, where n >= 4.
* @param[in]  orderQ_ptr         - The pointer to prime order Q of generator,
* @param[in]  orderQSizeBytes    - The size of generator order in bytes. Size in bytes must be >= 20.
* @param[in]  generatorG_ptr     - The pointer to the generator of multiplicative subgroup in GF(P).
* @param[in]  generatorSizeBytes - The size of generator in bytes (must be set if generator will be checked). 
* @param[in]  seedS_ptr          - The random seed used for generation of primes (must be set if 
*                                  primes will be checked).
* @param[in]  seedSizeBits       - The pointer to seed size in bytes (if seed is used, the size 
*                                  must be >= 20 bytes).
* @param[in]  pgenCounter        - The counter of tries to generate the primes (must be set if primes 
*                                  will be checked).
*
* Outputs: @returns \b
*  CE2Error_t  
*  - CE2_OK - On success
*  - Otherwise - error code:
*   - CE2_DH_INVALID_ARGUMENT_POINTER_ERROR
*   - CE2_DH_INVALID_MODULUS_SIZE_ERROR
*   - CE2_DH_INVALID_ORDER_SIZE_ERROR
*   - CE2_DH_CHECK_SEED_SIZE_OR_PTR_NOT_VALID_ERROR
*   - CE2_DH_CHECK_GENERATOR_SIZE_OR_PTR_NOT_VALID_ERROR
*   - CE2_DH_CHECK_DOMAIN_PRIMES_NOT_VALID_ERROR
*   - CE2_DH_CHECK_GENERATOR_NOT_VALID_ERROR
*   - CE2_LLF_DH_MODULE_ERROR_BASE
*
* \brief \b
* Description:
*  The function checks the obtained DH domain parameters according X9.42-2001.
*
*        There may be 3 case of checking:
*        1. Checking of primes only ( modulus P and order Q according to passed seed S and pgenCounter).
*           In this case all pointers and sizes of said parameters must be passed (not NULL), but generator 
*           G pointer and it size must be both set to NULL.
*        2. Checking of generator G only in assuming that primes parameters P, Q are valid. In ths case 
*           the user must to pass the P,Q,G pointers and sizes. The seed S pointer and size must be both
*           set to NULL, otherwise the function returns an error.
*        3. Checking all domain parameters. In this case all input parameters must be passed to the function.
*
*        If any of checked domain parameters is not compliant to X9.42-2001 standard, the function returns
*        an error according to errors definitions in CE2_DH_error.h file.  
*
*     Note:  Input vectors are in big endianness.
*
* \b
* Algorithm:
*  -# Verify input parameters for validity;
*  -# Call low level function LLF_DH_CheckDomainParams
*     to check domain params with using LibTomCrypt.
***************************************************************/
CE2CIMPORT_C CE2Error_t CE2_DH_CheckDomainParams(
                          DxUint8_t               *modP_ptr,           /*in */  
                          DxUint32_t               modPsizeBytes,      /*in */
                          DxUint8_t               *orderQ_ptr,         /*in */
                          DxUint32_t               orderQsizeBytes,    /*in */
                          DxUint8_t               *generatorG_ptr,     /*in */
                          DxUint32_t               generatorSizeBytes, /*in */
                          DxUint8_t               *seedS_ptr,          /*in */
                          DxUint32_t               seedSizeBits,       /*in */
                          DxUint32_t               pgenCounter);       /*in */

/**
****************************************************************
* Function Name: 
*  CE2_DH_CheckPubKey
*
* Inputs:
* @param[out] modP_ptr           - The modulus (prime) P.
* @param[in]  modPSizeBytes      - The modulus size in bytes.
* @param[in]  orderQ_ptr         - The pointer to prime order Q of generator,
* @param[in]  orderQSizeBytes    - The size of order of generator in bytes.
* @param[in]  pubKey_ptr         - The pointer to public key to be validated . 
* @param[in]  pubKeySizeBytes    - The public key size in bytes. 
*
* Outputs: @returns \b
*  CE2Error_t  
*  - CE2_OK - On success
*  - Otherwise - error code:
*   - CE2_DH_INVALID_ARGUMENT_POINTER_ERROR
*   - CE2_DH_INVALID_MODULUS_SIZE_ERROR
*   - CE2_DH_INVALID_ORDER_SIZE_ERROR
*   - CE2_DH_INVALID_PUBLIC_KEY_SIZE_ERROR
*   - CE2_DH_INVALID_PUBLIC_KEY_ERROR
*   - CE2_LLF_DH_MODULE_ERROR_BASE
*
* \brief \b
* Description:
*  The function checks the obtained DH public key according to its domain 
*        parameters (see X9.42-2001)
*
*              Assuming: The DH domain parameters are valid.
*
* \b
* Algorithm:
*  -# Verify input parameters for validity;
*  -# Call low level function LLF_DH_CheckPubKey
*     to check public key with using LibTomCrypt.
***************************************************************/
CE2CIMPORT_C CE2Error_t CE2_DH_CheckPubKey(
                          DxUint8_t              *modP_ptr,             /*in */  
                          DxUint32_t              modPsizeBytes,        /*in */
                          DxUint8_t              *orderQ_ptr,           /*in */
                          DxUint32_t              orderQsizeBytes,      /*in */
                          DxUint8_t              *pubKey_ptr,           /*in */
                          DxUint32_t              pubKeySizeBytes);     /*in */

#ifdef __cplusplus
}
#endif

#endif
