📄 rc5base.cpp
字号:
// RC5Base.cpp: implementation of the CRC5Base class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "RC5Base.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
DWORD DWORD_Sub(DWORD A, DWORD B);
#define P32_MAGIC 0xB7E15163UL
#define Q32_MAGIC 0x9E3779B9UL
/* Left and right rotation operations. Most decent compilers should be
able to recognise these as rotate instructions */
#define ROTL(x,s) ( ( ( x ) << ( s ) ) | ( ( x ) >> ( 32 - ( s ) ) ) )
#define ROTR(x,s) ( ( ( x ) >> ( s ) ) | ( ( x ) << ( 32 - ( s ) ) ) )
/* The individual RC5 en/decryption rounds. Note that the "& 0x1F" isn't
necessary on a number of processors which mask off everything but the low
5 bits of the rotate amount */
#define encryptRound(A,B,key) \
A = MASK32( ROTL( A ^ B, B & 0x1F ) + *key++ ); \
B = MASK32( ROTL( B ^ A, A & 0x1F ) + *key++ )
// B -= *--key; // A -= *--key;
#define decryptRound(A,B,key) \
B = DWORD_Sub(B, *--key); \
B = ROTR( MASK32( B ), A & 0x1F ) ^ A; \
A = DWORD_Sub(A, *--key); \
A = ROTR( MASK32( A ), B & 0x1F ) ^ B
/* RC5 en/decryption routines */
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
DWORD DWORD_Sub(DWORD A, DWORD B)
{
if(A >= B) return A - B;
B = 0xffffffff - B + 1;
return A + B;
}
CRC5Base::CRC5Base():m_key()
{
m_key.noRounds = 12;
m_KeySize = RC5_EXPANDED_KEYSIZE; // 256
}
CRC5Base::~CRC5Base()
{
}
/* RC5 en/decryption routines */
int CRC5Base::Encrypt( BYTE *pByte, DWORD nBlockSize )
{
BYTE *dataPtr = pByte;
//LONG *keyPtr = m_key.S;
//LONG A, B;
DWORD *keyPtr = (DWORD *)m_key.S;
DWORD A, B;
/* Copy the data buffer to the local variables */
A = mgetLLong( dataPtr );
B = mgetLLong( dataPtr );
A = MASK32( A + *keyPtr++ );
B = MASK32( B + *keyPtr++ );
/* Perform the 12 rounds of encryption */
for(int i=0; i<m_key.noRounds; i++)
{
encryptRound( A, B, keyPtr );
}
/*
encryptRound( A, B, keyPtr );
encryptRound( A, B, keyPtr );
encryptRound( A, B, keyPtr );
encryptRound( A, B, keyPtr );
encryptRound( A, B, keyPtr );
encryptRound( A, B, keyPtr );
encryptRound( A, B, keyPtr );
encryptRound( A, B, keyPtr );
encryptRound( A, B, keyPtr );
encryptRound( A, B, keyPtr );
encryptRound( A, B, keyPtr );
encryptRound( A, B, keyPtr );
*/
/* Copy the local variables back to the data buffer */
dataPtr = pByte;
mputLLong( dataPtr, A );
mputLLong( dataPtr, B );
return 0;
}
int CRC5Base::Decrypt(BYTE *pByte, DWORD nBlockSize)
{
BYTE *dataPtr = pByte;
//LONG *keyPtr = m_key.S;
//LONG A, B;
DWORD *keyPtr = (DWORD *)m_key.S;
DWORD A, B;
/* Copy the data buffer to the local variables */
A = mgetLLong( dataPtr );
B = mgetLLong( dataPtr );
/* Point to the end of the keying material (no.rounds + the initial
addition, two longwords each time) */
keyPtr += 2 * ( m_key.noRounds + 1 );
/* Perform the 12 rounds of decryption */
for(int i=0; i<m_key.noRounds; i++)
{
decryptRound( A, B, keyPtr);
}
/*
decryptRound( A, B, keyPtr );
decryptRound( A, B, keyPtr );
decryptRound( A, B, keyPtr );
decryptRound( A, B, keyPtr );
decryptRound( A, B, keyPtr );
decryptRound( A, B, keyPtr );
decryptRound( A, B, keyPtr );
decryptRound( A, B, keyPtr );
decryptRound( A, B, keyPtr );
decryptRound( A, B, keyPtr );
decryptRound( A, B, keyPtr );
decryptRound( A, B, keyPtr );
*/
// B -= *--keyPtr;
B = DWORD_Sub(B, *--keyPtr);
// A -= *--keyPtr;
A = DWORD_Sub(A, *--keyPtr);
/* Copy the local variables back to the data buffer */
dataPtr = pByte;
mputLLong( dataPtr, A );
mputLLong( dataPtr, B );
return 0;
}
/* RC5 key setup routines. The variable names, while cryptic, follow the
original algorithm specification */
//void rc5keyInit( RC5_KEY *key, BYTE *userKey, int userKeyLength )
int CRC5Base::KeyInitial(BYTE *pByte, DWORD nKeySize, DWORD dwParam)
{
if(dwParam != 0) m_key.noRounds = dwParam;
int userKeyLength = nKeySize;
m_KeySize = nKeySize;
LONG L[ RC5_EXPANDED_KEYSIZE_LONG ], A = 0, B = 0;
BYTE temp[ RC5_EXPANDED_KEYSIZE ], *tempPtr = temp;
int i, j, c = ( userKeyLength + 3 ) / 4, t = 2 * ( m_key.noRounds + 1 );
int iterations = ( c > t ) ? 3 * c : 3 * t;
/* Copy the user key into the L array */
memset( temp, 0, RC5_EXPANDED_KEYSIZE );
memcpy( temp, pByte, userKeyLength );
for( i = 0; i < RC5_EXPANDED_KEYSIZE_LONG; i++ )
{
L[ i ] = mgetLLong( tempPtr ); // tempPtr increases by 4
}
/* Initialise the key array with the LCRNG */
m_key.S[ 0 ] = P32_MAGIC;
for( i = 1; i < RC5_EXPANDED_KEYSIZE_LONG; i++ )
m_key.S[ i ] = m_key.S[ i - 1 ] + Q32_MAGIC; // overflow ignored
/* Mix the user key into the key array */
i = j = 0;
while( iterations-- )
{
A = m_key.S[ i ] = ROTL( MASK32( m_key.S[ i ] + A + B ), 3 );
B = L[ j ] = ROTL( MASK32( L[ j ] + A + B ), ( A + B ) & 0x1F );
i = ( i + 1 ) % t;
j = ( j + 1 ) % c;
}
/* Clean up */
memset( L,0, RC5_EXPANDED_KEYSIZE_LONG * sizeof( LONG ) );
memset( temp,0, RC5_EXPANDED_KEYSIZE );
return 0;
}
// set the number of rounds
int CRC5Base::CipherInitail(DWORD dwParam)
{
if(dwParam == 0) m_key.noRounds = 12;
else m_key.noRounds = dwParam;
return 0;
}
int CRC5Base::GetBlockSize()
{
return RC5_BLOCKSIZE;
}
int CRC5Base::GetKeySize()
{
return m_KeySize;
}
int CRC5Base::GetRounds()
{
return m_key.noRounds;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -