
#ifndef CRYS_COMMON_MATH_H
#define CRYS_COMMON_MATH_H

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


#ifdef __cplusplus
extern "C"
{
#endif

  /*
   *  Object %CRYS_COMMON_math.h    : %
   *  State           :  %state%
   *  Creation date   :  Tue Nov 23 09:29:46 2004
   *  Last modified   :  %modify_time%
   */
  /** @file
   *  \brief This file containes general math operations that are used by the CRYS software.
   *
   *  \version CRYS_COMMON_math.h#1:incl:2
   *  \author adams
   *  \remarks Copyright (C) 2004 by Discretix Technologies Ltd.
   *           All Rights reserved
   */

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

/************************ Macros ******************************/

/* invers the bytes on a word */
#define CRYS_COMMON_INVERSE_UINT32_BYTES( val ) \
   ( ((val) >> 24) | (((val) & 0x00FF0000) >> 8) | (((val) & 0x0000FF00) << 8) | (((val) & 0x000000FF) << 24) )
   
/* get a bit val from a word array */   
#define CRYS_COMMON_GET_BIT_VAL_FROM_WORD_ARRAY( ptr , bit_pos ) \
   ( ((ptr)[(bit_pos)/32] & (1 << ((bit_pos) % 32))) >> ((bit_pos) % 32) ) 
   
/* exchange a bit on a word array */
#define CRYS_COMMON_EXCHANGE_BIT_ON_WORD_ARRAY(ptr,bit_pos) ( (ptr)[(bit_pos)/32] ^= (1UL << ((bit_pos) % 32) ) )
              
/* the minimum and maximum macros */
#undef min
#define min( a , b ) ( ( (a) < (b) ) ? (a) : (b) )

#undef max    
#define max( a , b ) ( ( (a) > (b) ) ? (a) : (b) )


/************************ Enums ********************************/

/* the counter comperation result enum */
typedef enum { CRYS_COMMON_CmpCounter1AndCounter2AreIdentical = 0,
               CRYS_COMMON_CmpCounter1GraterThenCounter2      = 1,
               CRYS_COMMON_CmpCounter2GraterThenCounter1      = 2,
               
               CRYS_COMMON_CmpCounterLast                    = 0x7FFFFFFF,

             } CRYS_COMMON_CmpCounter_t;  
             
/* shift direction  enum */
typedef enum { CRYS_COMMON_ShiftRight = 0,
               CRYS_COMMON_ShiftLeft  = 1,
               
               CRYS_COMMON_ShiftOffMode,
               
               CRYS_COMMON_ShiftDirectionLast= 0x7FFFFFFF,

             } CRYS_COMMON_ShiftDirection_t;  
            
                  

/************************ Typedefs  ****************************/


/************************ Structs  ******************************/


/************************ Public Variables **********************/


/************************ Public Functions **********************/

/**************************************************************
 * @brief This function adds a value to a large counter presented in a buffer.
 *        The MSB of the counter is stored in the first cell in the array.
 *        
 *        for example:
 *
 *        a counter of 64 bit : the value is : 
 *
 *        byte[0] << 56 | byte[1] << 48 ............ byte[6] << 8 | byte[7]  
 *
 * @param[in] CounterBuff_ptr - The buffer containing the counter.
 * @param[in] Val             - this value to add.
 * @param[in] ConterSize      - the counter size in 32bit words. 
 *
 * @return CRYSError_t - On success CRYS_OK is returned, on failure a
 *                        value MODULE_* as defined in ...
 */

 void CRYS_COMMON_IncMsbUnsignedCounter( DxUint32_t *CounterBuff_ptr ,
                                         DxUint32_t Val ,
                                         DxUint8_t  ConterSize );
                                         
                                       
/********************************************************************************
 * @brief This function adds a value to a large counter presented in a buffer.
 *        The LSB of the counter is stored in the first cell in the array.
 *        
 *        for example:
 *
 *        a counter of 64 bit : the value is : 
 *
 *        byte[7] << 56 | byte[6] << 48 ............ byte[1] << 8 | byte[0]  
 *
 * @param[in] CounterBuff_ptr - The buffer containing the counter.
 * @param[in] Val             - this value to add.
 * @param[in] ConterSize      - the counter size in 32bit words. 
 *
 * @return carry bit from MS word if carry occur
 *                        
 */

 DxUint32_t CRYS_COMMON_IncLsbUnsignedCounter( 
                                         DxUint32_t     *CounterBuff_ptr ,
                                         DxUint32_t      Val,
                                         DxUint8_t       ConterSize );


/********************************************************************************
 * @brief This function subtracts a value from a large counter presented in a buffer.
 *        The LSB of the counter is stored in the first cell in the array.
 *        
 *        for example:
 *
 *        a counter of 64 bit : the value is : 
 *
 *        byte[7] << 56 | byte[6] << 48 ............ byte[1] << 8 | byte[0]  
 *
 * @param[in] CounterBuff_ptr - the buffer containing the counter.
 * @param[in] Val             - the value to subtract.
 * @param[in] ConterSize      - the counter size in 32bit words. 
 *
 * @return CRYSError_t - On success CRYS_OK is returned, on failure a
 *                        value MODULE_* as defined in ...
 */

  void CRYS_COMMON_DecrLsbUnsignedCounter( DxUint32_t     *CounterBuff_ptr,
                                           DxUint32_t      Val,
                                           DxUint8_t       ConterSizeInWords );
                                          


 /**************************************************************
 * @brief This function compares a value of 2 large counter presented in a byte buffer.
 *        The MSB of the counter is stored in the first cell in the array.
 *        
 *        for example:
 *
 *        a counter of 64 bit : the value is : 
 *
 *        byte[0] << 56 | byte[1] << 48 ............ byte[6] << 8 | byte[7]  
 *
 *
 * @param[in] CounterBuff1_ptr - The first counter buffer.
 * @param[in] Counter1Size     - the first counter size in bytes. 
 * @param[in] CounterBuff2_ptr - The second counter buffer.
 * @param[in] Counter2Size     - the second counter size in bytes.
 * @param[in] SizeUnit         - the size units. 0 - bits , 1 - bytes 
 *
 * @return result - an enum with the comparation result: 
 *                                0 - both counters are identical 
 *                                1 - counter 1 is larger.
 *                                2 - counter 2 is larger.
 * @note This code executes in constant time, regardless of the arguments.
 */

 CRYS_COMMON_CmpCounter_t CRYS_COMMON_CmpMsbUnsignedCounters( DxUint8_t  *CounterBuff1_ptr,
                                                              DxUint16_t  Counter1Size, 
                                                              DxUint8_t  *CounterBuff2_ptr,
                                                              DxUint16_t Counter2Size );
                                                              
                                                              

/**************************************************************
 * @brief This function compares a value of 2 large counter presented in a byte buffer.
 *        The LSB of the counter is stored in the first cell in the array.
 *        
 *        for example:
 *
 *        a counter of 64 bit : the value is : 
 *
 *        byte[7] << 56 | byte[6] << 48 ............ byte[1] << 8 | byte[0]  
 *
 * @param[in] CounterBuff1_ptr - The first counter buffer.
 * @param[in] Counter1Size     - the first counter size in bytes. 
 * @param[in] CounterBuff2_ptr - The second counter buffer.
 * @param[in] Counter2Size     - the second counter size in bytes.
 *
 * @return result - an enum with the comparation result: 
 *                                0 - both counters are identical 
 *                                1 - counter 1 is larger.
 *                                2 - counter 2 is larger.
 */

 CRYS_COMMON_CmpCounter_t CRYS_COMMON_CmpLsbUnsignedCounters( DxUint8_t  *CounterBuff1_ptr,
                                                              DxUint16_t  Counter1Size, 
                                                              DxUint8_t  *CounterBuff2_ptr,
                                                              DxUint16_t Counter2Size );



/**************************************************************
 * @brief This function returnes the effective number of bits in the byte stream counter 
 *        ( searching the highest '1' in the counter )
 *
 *        The LSB of the counter is stored in the first cell in the array. 
 *        
 *        for example:
 *
 *        a counter of 64 bit : the value is : 
 *
 *        byte[7] << 56 | byte[6] << 48 ............ byte[1] << 8 | byte[0]  
 *
 * @param[in] CounterBuff_ptr -  The counter buffer.
 * @param[in] CounterSize     -  the counter size in bytes. 
 *
 * @return result - The effective counters size in bits.
 */

 DxUint32_t CRYS_COMMON_GetCounterEffectiveSizeInBits( DxUint8_t  *CounterBuff_ptr,
                                                     DxUint16_t  CounterSize );
                                                     
                                                     
                                                     
/********************************************************************************
 * @brief This function devides a vector by 2 - in a secured way
 *
 *        The LSB of the vector is stored in the first cell in the array. 
 *        
 *        for example:
 *
 *        a vector of 128 bit : the value is : 
 *
 *        word[3] << 96 | word[2] << 64 ............ word[1] << 32 | word[0]  
 *
 * @param[in] VecBuff_ptr     -  The vector buffer.
 * @param[in] SizeInWords     -  the counter size in words. 
 *
 * @return result - no return value.
 */
void CRYS_COMMON_DivideVectorBy2(DxUint32_t *VecBuff_ptr,DxUint32_t SizeInWords);


/********************************************************************************
 * @brief This function shifts left a big endian vector by Shift - bits (Shift < 8).
 *
 *        The MSB of the vector is stored in the first cell in the array, 
 *        
 *        For example, a vector of 128 bit is : 
 *
 *        byte[n-1] | byte[n-2] ... byte[1] | byte[0]  
 *
 * @param[in] VecBuff_ptr     -  The vector buffer.
 * @param[in] SizeInBytes     -  The counter size in bytes. 
 * @param[in] Shift           -  The number of shift left bits, must be < 8.
 * @return no return value.
 */

void CRYS_COMMON_ShiftLeftBigEndVector(DxUint8_t *VecBuff_ptr,DxUint32_t SizeInBytes, DxInt8_t Shift);

 
/********************************************************************************
 * @brief This function shifts right a vector by Shift - bits (Shift < 8).
 *
 *        The LSB of the vector is stored in the first cell in the array. 
 *        For example, a vector of 128 bit is : 
 *
 *        byte[n-1] | byte[n-2] ... byte[1] | byte[0]  
 *
 * @param[in] VecBuff_ptr     -  The vector buffer.
 * @param[in] SizeInBytes     -  The counter size in bytes. 
 * @param[in] Shift           -  The number of shift left bits, must be < 8.
 * @return no return value.
 */

void CRYS_COMMON_ShiftRightVector(DxUint8_t *VecBuff_ptr,DxUint32_t SizeInBytes, DxInt8_t Shift);


/**************************************************************
 * @brief This function adds 2 vectors ( A+B).
 *
 * @param[in] A_ptr       -  input vector A.
 * @param[in] B_ptr       -  input vector B.
 * @param[in] SizeInWords - The size in words 
 * @param[in] Res_ptr     - The result pointer
 *
 * @return result  - Carry from high words addition.
 */
 
DxUint32_t  CRYS_COMMON_Add2vectors ( 
							   DxUint32_t *A_ptr, 
                               DxUint32_t *B_ptr,
                               DxUint32_t SizeInWords, 
                               DxUint32_t *Res_ptr );


/*******************************************************************************
 *                      CRYS_COMMON_SubtractWordArrays                         *
 *******************************************************************************
 
 * @brief This function subtracts two little endian words arrays of length 
          SizeInWords:  Res = (A - B) and returns Borrow from subtracting of high 
          words. 
 *
 * @param[in] A_ptr       -  input vector A.
 * @param[in] B_ptr       -  input vector B.
 * @param[in] SizeInWords -  size in words 
 * @param[in] Res_ptr     -  result pointer
 *
 * @return  Borrow from high words subtracting.
 */
 
DxUint32_t CRYS_COMMON_SubtractUintArrays(DxUint32_t *A_ptr, 
                                          DxUint32_t *B_ptr, 
                                          DxUint32_t  SizeInWords, 
                                          DxUint32_t *Res_ptr );
                                          
/*******************************************************************************
 *                      CRYS_COMMON_AddTwoLsbUint8Vectors                      *
 *******************************************************************************
 *
 * @brief This function adds two little endian vectors Res = (A + B) and returns carry. 
 * 
 *
 * @param[in] A_ptr       -  input vector A.
 * @param[in] B_ptr       -  input vector B.
 * @param[in] SizeInWords -  size in words 
 * @param[in] Res_ptr     -  result pointer
 *
 * @return - carry from adding of two high bytes.
 */
 
DxUint32_t CRYS_COMMON_AddTwoLsbUint8Vectors(
                                          DxUint8_t  *A_ptr, 
                                          DxUint8_t  *B_ptr, 
                                          DxUint32_t  VectSizeInBytes, 
                                          DxUint8_t  *Res_ptr ); 
                                          
                                                                                   
/*******************************************************************************
 *                      CRYS_COMMON_SubtractMSBUint8Arrays                     *
 *******************************************************************************
 
 * @brief This function subtracts two big endian byte arrays. 
 *
 *   Assuming:  SizeA >= SizeB. 
 *              Size of result buffer is not less, than sizeA.
 *
 * @param[in] A_ptr       -  Pointer to input vector A.
 * @param[in] sizeA       -  Size in bytes of each of vector A.
 * @param[in] B_ptr       -  Pointer to input vector B.
 * @param[in] sizeB       -  Size in bytes of each of vector B.
 * @param[in] Res_ptr     -  result pointer
 *
 * @return  Borrow from high byte of vector A.
 */
DxUint8_t CRYS_COMMON_SubtractMSBUint8Arrays(
                                          DxUint8_t  *A_ptr, 
                                          DxUint32_t  sizeA, 
                                          DxUint8_t  *B_ptr, 
                                          DxUint32_t  sizeB, 
                                          DxUint8_t  *Res_ptr );



#ifdef __cplusplus
}
#endif

#endif



