⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vmsha1.cpp

📁 TOOL (Tiny Object Oriented Language) is an easily-embedded, object-oriented, C++-like-language inter
💻 CPP
字号:
/*****************************************************************************/
/*                              SOURCE FILE                                  */
/*****************************************************************************/
/*
       $Archive: $

      $Revision: $
          $Date: $
        $Author: $

    Description: Implementation of the NIST proposed Secure Hash Standard
                 Based on work that was put into the public domain by:
                 Peter C. Gutmann on Written 2 September 1992 
*/
static char OBJECT_ID[] = "$Revision: $ : $Date: $";
/*****************************************************************************/


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "VMSHA1.h"


// The SHS Mysterious Constants 
//
const ULONG cK1  = 0x5A827999;
const ULONG cK2  = 0x6ED9EBA1;
const ULONG cK3  = 0x8F1BBCDC;
const ULONG cK4  = 0xCA62C1D6;



/*****************************************************************************/
/*
     FUNCTION NAME:  VMSHA1Hash::Hash

       DESCRIPTION:  Super ordinate method. Calls on other members to do the
                     required work.

             INPUT:  pshsInfo - Pointer to output structure for this class. 
                     pbInput  - the string to hash through this class
                     lLength  - the length of the string to be hashed.
            OUTPUT:  none

           RETURNS:  void  - 
*/
void VMSHA1Hash::Hash( P_VM_SHS_INFO pshsInfo, const BYTE* pbInput, long lLength )
{
  Init( pshsInfo );
  Update( pshsInfo, pbInput, lLength );
  Final( pshsInfo );
}
/* End of function "VMSHA1Hash::Hash"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMSHA1Hash::Init

       DESCRIPTION:  Initialize the SHS values

             INPUT:  pshsInfo - pointer to the structure to initialize
            OUTPUT:  none

           RETURNS:  void  
*/
void VMSHA1Hash::Init( P_VM_SHS_INFO pshsInfo )
{
  // Set the h-vars to their initial values as defined by the NIST spec
  //
  pshsInfo->m_ulaDigest[ 0 ] = 0x67452301;
  pshsInfo->m_ulaDigest[ 1 ] = 0xEFCDAB89;
  pshsInfo->m_ulaDigest[ 2 ] = 0x98BADCFE;
  pshsInfo->m_ulaDigest[ 3 ] = 0x10325476;
  pshsInfo->m_ulaDigest[ 4 ] = 0xC3D2E1F0;

  // Initialise bit count 
  //
  pshsInfo->m_CountLo = pshsInfo->m_CountHi = 0L;
}
/* End of function "VMSHA1Hash::Init"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMSHA1Hash::Expand

       DESCRIPTION:  The initial expansion function

             INPUT:  sCount - the index of the element to expand
            OUTPUT:  none

           RETURNS:  void
*/
inline void VMSHA1Hash::Expand( ULONG ulArray[], short sCount )
{
   ulArray[ sCount ] = ulArray[ sCount - 3 ] 
                     ^ ulArray[ sCount - 8 ] 
                     ^ ulArray[ sCount - 14 ] 
                     ^ ulArray[ sCount - 16 ];
}
/* End of function "VMSHA1Hash::Expand"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMSHA1Hash::DoRound1

       DESCRIPTION:  mangles the values of class members

             INPUT:  ulValueAtIndex - a specific value to throw into the mix
            OUTPUT:  none

           RETURNS:  void  
*/
inline void VMSHA1Hash::DoRound1( ULONG ulValueAtIndex )
{
  ULONG uTemp;

  uTemp = ( ( m_A << 5 ) | ( m_A >> 27 ) ) + ( ( m_B & m_C ) | ( ~m_B & m_D ) ) + m_E + ulValueAtIndex + cK1;
  m_E = m_D;
  m_D = m_C;
  m_C = ( m_B << 30 ) | ( m_B >> 2 );
  m_B = m_A;
  m_A = uTemp;
}
/* End of function "VMSHA1Hash::DoRound1"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMSHA1Hash::DoRound2

       DESCRIPTION:  mangles the values of class members

             INPUT:  ulValueAtIndex - a specific value to throw into the mix
            OUTPUT:  none

           RETURNS:  void  
*/
inline void VMSHA1Hash::DoRound2( ULONG ulValueAtIndex )
{
  ULONG uTemp;

  uTemp = ( ( m_A << 5 ) | ( m_A >> 27 ) ) + ( m_B ^ m_C ^ m_D ) + m_E + ulValueAtIndex + cK2;
  m_E = m_D;
  m_D = m_C;
  m_C = ( m_B << 30 ) | ( m_B >> 2 );
  m_B = m_A;
  m_A = uTemp;
}
/* End of function "VMSHA1Hash::DoRound2"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMSHA1Hash::DoRound3

       DESCRIPTION:  mangles the values of class members

             INPUT:  ulValueAtIndex - a specific value to throw into the mix
            OUTPUT:  none

           RETURNS:  void  
*/
inline void VMSHA1Hash::DoRound3( ULONG ulValueAtIndex )
{
  ULONG uTemp;

  uTemp = ( ( m_A << 5 ) | ( m_A >> 27 ) ) + ( ( m_B & m_C ) | ( m_B & m_D ) | ( m_C & m_D ) ) + m_E + ulValueAtIndex + cK3;
  m_E = m_D;
  m_D = m_C;
  m_C = ( m_B << 30 ) | ( m_B >> 2 );
  m_B = m_A;
  m_A = uTemp;
}
/* End of function "VMSHA1Hash::DoRound3"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMSHA1Hash::DoRound4

       DESCRIPTION:  mangles the values of class members

             INPUT:  ulValueAtIndex - a specific value to throw into the mix
            OUTPUT:  none

           RETURNS:  void  
*/
inline void VMSHA1Hash::DoRound4( ULONG ulValueAtIndex )
{
  ULONG uTemp;

  uTemp = ( ( m_A << 5 ) | ( m_A >> 27 ) ) + ( m_B ^ m_C ^ m_D ) + m_E + ulValueAtIndex + cK4;
  m_E = m_D;
  m_D = m_C;
  m_C = ( m_B << 30 ) | ( m_B >> 2 );
  m_B = m_A;
  m_A = uTemp;
}
/* End of function "VMSHA1Hash::DoRound4"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMSHA1Hash::Transform

       DESCRIPTION:  Perform the SHS transformation. Note that this code, like 
                     MD5, seems to break some optimizing compilers - it may be 
                     necessary to split it into sections, eg based on the four 
                     subrounds

             INPUT:  pshsInfo - 
            OUTPUT:  none

           RETURNS:  void   
*/
void VMSHA1Hash::Transform( P_VM_SHS_INFO pshsInfo )
{
  ULONG ulaWorking[ 80 ];
  int   iLoop;

  // Step A.  Copy the data buffer into the local work buffer 
  //
  for( iLoop = 0; iLoop < 16; iLoop++ )
	  ulaWorking[ iLoop ] = pshsInfo->m_ulaData[ iLoop ];

  // Step B.  Expand the 16 words into 64 temporary data words
  //
  for ( iLoop = 16; iLoop < 80; iLoop++ )
    Expand( ulaWorking, iLoop );

  // Step C.  Set up first buffer 
  //
  m_A = pshsInfo->m_ulaDigest[ 0 ];
  m_B = pshsInfo->m_ulaDigest[ 1 ];
  m_C = pshsInfo->m_ulaDigest[ 2 ];
  m_D = pshsInfo->m_ulaDigest[ 3 ];
  m_E = pshsInfo->m_ulaDigest[ 4 ];

  // Step D.  Serious mangling, divided into four sub-rounds 
  //
  for ( iLoop = 0; iLoop < 20; iLoop++ )
    DoRound1( ulaWorking[ iLoop ] );

  for ( iLoop = 20; iLoop < 40; iLoop++ )
    DoRound2( ulaWorking[ iLoop ] );

  for ( iLoop = 40; iLoop < 60; iLoop++ )
    DoRound3( ulaWorking[ iLoop ] );

  for ( iLoop = 60; iLoop < 80; iLoop++ )
    DoRound4( ulaWorking[ iLoop ] );

  // Step E.  Build message digest
  //
  pshsInfo->m_ulaDigest[ 0 ] += m_A;
  pshsInfo->m_ulaDigest[ 1 ] += m_B;
  pshsInfo->m_ulaDigest[ 2 ] += m_C;
  pshsInfo->m_ulaDigest[ 3 ] += m_D;
  pshsInfo->m_ulaDigest[ 4 ] += m_E;
}
/* End of function "VMSHA1Hash::Transform"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  Update

       DESCRIPTION:  Update SHS for a block of data.  This code assumes that 
                     the buffer size is a multiple of ciBlockSize bytes long, 
                     which makes the code a lot more efficient since it does 
                     away with the need to handle partial blocks between calls 
                     to Update()

             INPUT:  pshsInfo - the "target" of the operation
                     pBuffer - pointer to the data buffer to operate on
                     lCount - the length of the input buffer
            OUTPUT:  pshsInfo contents are modified

           RETURNS:  void  
*/
void VMSHA1Hash::Update( P_VM_SHS_INFO pshsInfo, const BYTE* pBuffer, long lCount )
{
  // Update bitcount
  //
  if ( ( pshsInfo->m_CountLo + ( (ULONG) lCount << 3 ) ) < pshsInfo->m_CountLo )
  {
    // Carry from low to high bitCount 
    //
    pshsInfo->m_CountHi++; 
  }

  pshsInfo->m_CountLo += ( (ULONG) lCount << 3 );
  pshsInfo->m_CountHi += ( (ULONG) lCount >> 29 );

  // Process data in ciBlockSize chunks 
  //
  while ( lCount >= ciBlockSize )
	{
    memcpy( pshsInfo->m_ulaData, pBuffer, ciBlockSize );

    #ifdef LITTLE_ENDIAN
    ReverseByte( pshsInfo->m_ulaData, ciBlockSize );
    #endif

    Transform( pshsInfo );
    pBuffer += ciBlockSize;
    lCount  -= ciBlockSize;
  }

  // Handle any remaining bytes of data. This should
  // only happen once on the final lot of data
  //
  memcpy( pshsInfo->m_ulaData, pBuffer, lCount );
}
/* End of function "VMSHA1Hash::Update"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMSHA1Hash::Final

       DESCRIPTION:  

             INPUT:  pshsInfo - pointer to the structure to operate on
            OUTPUT:  none

           RETURNS:  void
*/
void VMSHA1Hash::Final( P_VM_SHS_INFO pshsInfo )
{
  int count;
  ULONG lowBitcount  = pshsInfo->m_CountLo;
  ULONG highBitcount = pshsInfo->m_CountHi;

  // Compute number of bytes mod 64
  //
  count = (int) ( ( pshsInfo->m_CountLo >> 3 ) & 0x3F );

  // Set the first char of padding to 0x80. This is 
  // safe since there is always at least one byte free 
  //
  ( (BYTE*) pshsInfo->m_ulaData )[ count++ ] = 0x80;

  // Pad out to 56 mod 64 
  //
  if( count > 56 )
	{
    // Two lots of padding: Pad the first block to 64 bytes
    //
    memset( (BYTE*) &pshsInfo->m_ulaData + count, 0, 64 - count );

    #ifdef LITTLE_ENDIAN
    ReverseByte( pshsInfo->m_ulaData, ciBlockSize );
    #endif

    Transform( pshsInfo );

    // Now fill the next block with 56 bytes
    //
	  memset( &pshsInfo->m_ulaData, 0, 56 );
  }
  else
  {
    // Pad block to 56 bytes
    //
    memset( (BYTE*) &pshsInfo->m_ulaData + count, 0, 56 - count );
  }

  #ifdef LITTLE_ENDIAN
  ReverseByte( pshsInfo->m_ulaData, ciBlockSize );
  #endif

  // Append length in bits and transform 
  //
  pshsInfo->m_ulaData[ 14 ] = highBitcount;
  pshsInfo->m_ulaData[ 15 ] = lowBitcount;

  Transform( pshsInfo );

  #ifdef LITTLE_ENDIAN
  ReverseByte( pshsInfo->m_ulaData, ciDigestSize );
  #endif
}
/* End of function "VMSHA1Hash::Final"
/*****************************************************************************/


#ifdef LITTLE_ENDIAN
/*****************************************************************************/
/*
     FUNCTION NAME:  VMSHA1Hash::ReverseByte

       DESCRIPTION:  When run on a little-endian CPU we need to perform byte 
                     reversal on an array of longwords.  It is possible to make 
                     the code endianness-independant by fiddling around with 
                     data at the byte level, but this makes for very slow code, 
                     so we rely on the user to sort out endianness at compile time

             INPUT:  pBuffer - pointer to the buffer to operate on
                     iByteCount - the size of the buffer
            OUTPUT:  

           RETURNS:  void
*/
void VMSHA1Hash::ReverseByte( ULONG* pBuffer, int iByteCount )
{
  ULONG value;
  int   count;

  iByteCount /= sizeof( ULONG );

  for( count = 0; count < iByteCount; count++ )
	{
	  value = ( pBuffer[ count ] << 16 ) | ( pBuffer[ count ] >> 16 );
	  pBuffer[ count ] = ( ( value & 0xFF00FF00L ) >> 8 ) | ( ( value & 0x00FF00FFL ) << 8 );
	}
}
/* End of function "VMSHA1Hash::ReverseByte"
/*****************************************************************************/
#endif // LITTLE_ENDIAN



/*****************************************************************************/
/* Check-in history */
/*
 *$Log: $
*/
/*****************************************************************************/


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -