📄 twofish.c
字号:
for (i=0,j=3; i<4; i++,j--)
{ /* split into even/odd key dwords */
k32e[i]=keyInput[2*i ];
k32o[i]=keyInput[2*i+1];
/* compute S-box keys using (12,8) Reed-Solomon code over GF(256) */
sKey[j]=key->sboxKeys[j]=RS_MDS_Encode(k32e[i],k32o[i]); /* reverse order */
}
for (i=q=0;i< TOTAL_SUBKEYS/2;i++,q+=SK_STEP)
{ /* compute round subkeys for PHT */
F32(A,q ,k32e); /* A uses even key dwords */
F32(B,q+SK_BUMP,k32o); /* B uses odd key dwords */
B = ROL(B,8);
key->subKeys[2*i ] = A+B; /* combine with a PHT */
B = A + 2*B;
key->subKeys[2*i+1] = ROL(B,SK_ROTL);
}
sb256(0);
sb256(1);
sb256(2);
sb256(3);
return TRUE;
}
/*
+*****************************************************************************
*
* Function Name: KeyExtend
*
* Function: Initialize the Twofish key schedule
*
* Arguments: KeySource = ptr to 256 bit of key
* KeyDestination = ptr to keyInstance to be initialized
*
* Return: TRUE on success
*
-****************************************************************************/
/* Macros to transform array of 4 bytes to 32-bit dwords
* without depending on the Little-Endian or
* Big-Endian processor's architecture
*/
#define BYTES_TO_DWORD(b,d) (d =((DWORD)(*((b)++))), \ d|=((DWORD)(*((b)++)))<< 8, \ d|=((DWORD)(*((b)++)))<<16, \ d|=((DWORD)(*((b)++)))<<24)
#define DWORD_TO_4BYTES(d,b) (*((b)++)=(BYTE)(((d) )&0xff), \ *((b)++)=(BYTE)(((d)>> 8)&0xff), \ *((b)++)=(BYTE)(((d)>>16)&0xff), \ *((b)++)=(BYTE)(((d)>>24)&0xff))
BOOL
KeyExtend( PUCHAR KeySource, //32 8-bits bytes - 256-bit key
PDWORD KeyDestination )
{
int i,j;
KeyInstance *keyInstance = (KeyInstance *)KeyDestination;
DWORD dwKey[ MAX_KEY_BITS/32 ];
UCHAR *bPtr;
/* place 256 bits of key to array of 32-bit DWORDs */
for( i=0,j=0; i<MAX_KEY_BITS/8; i=i+4,j++ ) /* DWORD consists of 4 bytes */
{
bPtr = &(KeySource[i]);
BYTES_TO_DWORD( bPtr,dwKey[j] );
}
return reKey( dwKey, keyInstance );
}
/*
+*****************************************************************************
*
* Function Name: blockEncrypt
*
* Function: Encrypt 128-bit block of data in ECB mode
*
* Arguments: Block = ptr to 128-bit data block to be encrypted
* key = ptr to already initialized keyInstance
*
* Return: BOOLEAN
*
-****************************************************************************/
/* Input whitening: sk is a sub keys table */
#define LoadBlockE(N) ( x[N]=Bswap(((DWORD *)Block)[N]) ^ sk[N] )
/* Output whitening: need to do final swap */
#if LittleEndian
#define StoreBlockE(N) ( ((DWORD *)Block)[N]=x[N^2] ^ sk[INPUT_WHITEN+N] )
#else
#define StoreBlockE(N) { t0=x[N^2] ^ sk[INPUT_WHITEN+N]; ((DWORD *)Block)[N]=Bswap(t0); }
#endif
BOOL
blockEncrypt( DWORD *Block,
KeyInstance *key )
{
DWORD x[ TF_BLOCK_SIZE/32 ]; /* block being encrypted */
DWORD t0,t1; /* temp variables */
DWORD *sk;
sk = key->subKeys;
LoadBlockE(0); LoadBlockE(1); LoadBlockE(2); LoadBlockE(3);
Encrypt2(14);
Encrypt2(12);
Encrypt2(10);
Encrypt2( 8);
Encrypt2( 6);
Encrypt2( 4);
Encrypt2( 2);
Encrypt2( 0);
StoreBlockE(0); StoreBlockE(1); StoreBlockE(2); StoreBlockE(3);
return TRUE;
}
/*
+*****************************************************************************
*
* Function Name: blockDecrypt
*
* Function: Decrypt block(s) of data using Twofish
*
* Arguments: Block = ptr to 128-bit data block to be decrypted
* key = ptr to already initialized keyInstance
*
* Return: BOOLEAN
*
-****************************************************************************/
#define LoadBlockD(N) x[N^2]=Bswap(((DWORD *)Block)[N]) ^ sk[OUTPUT_WHITEN+N]
#if LittleEndian
#define StoreBlockD(N) ((DWORD *)Block)[N] = x[N] ^ sk[N]
#else
#define StoreBlockD(N) { t0=x[N]^sk[N]; ((DWORD *)Block)[N] = Bswap(t0); }
#endif
BOOL
blockDecrypt( DWORD *Block,
KeyInstance *key )
{
DWORD x[TF_BLOCK_SIZE/32]; /* block being encrypted */
DWORD t0,t1; /* temp variables */
DWORD *sk;
sk = key->subKeys;
LoadBlockD(0); LoadBlockD(1); LoadBlockD(2); LoadBlockD(3);
Decrypt2(14);
Decrypt2(12);
Decrypt2(10);
Decrypt2( 8);
Decrypt2( 6);
Decrypt2( 4);
Decrypt2( 2);
Decrypt2( 0);
StoreBlockD(0); StoreBlockD(1); StoreBlockD(2); StoreBlockD(3);
return TRUE;
}
/************ TWOFISH 32-bit CFB mode encryption *****************/
VOID
encrypt_CFB( DWORD *IVector,
DWORD *KeyAddress,
DWORD *SrcBuffer,
DWORD *DstBuffer,
DWORD Length ) /* in bytes */
{
DWORD i,j,dwLength;
DWORD shReg[4], shRegEnc[4];
for(i=0; i<(TF_BLOCK_SIZE/32); i++) shReg[i] = IVector[i];
dwLength = Length>>2; /* Length of buffer in 32-bit DWORDs */
for(i=0; i<dwLength; i++)
{
for(j=0; j<(TF_BLOCK_SIZE/32); j++) shRegEnc[j] = shReg[j];
blockEncrypt( shRegEnc, (KeyInstance *)KeyAddress );
DstBuffer[i] = SrcBuffer[i] ^ shRegEnc[ (TF_BLOCK_SIZE/32 - 1) ];
for(j=TF_BLOCK_SIZE/32; (j--)>0 ;)
{ shReg[ j ] = shReg[ j - 1];
}
shReg[0] = DstBuffer[i];
}
}
/************ TWOFISH 32-bit CFB mode decryption *****************/
VOID
decrypt_CFB( DWORD *IVector,
DWORD *KeyAddress,
DWORD *SrcBuffer,
DWORD *DstBuffer,
DWORD Length ) /* in bytes */
{
DWORD i,j,dwLength;
DWORD shReg[4], shRegEnc[4], srcSave;
for(i=0; i<(TF_BLOCK_SIZE/32); i++) shReg[i] = IVector[i];
dwLength = Length>>2; /* Length of buffer in 32-bit DWORDs */
for(i=0; i<dwLength; i++)
{
for(j=0; j<(TF_BLOCK_SIZE/32); j++) shRegEnc[j] = shReg[j];
srcSave = SrcBuffer[i];
blockEncrypt( shRegEnc, (KeyInstance *)KeyAddress );
DstBuffer[i] = SrcBuffer[i] ^ shRegEnc[ (TF_BLOCK_SIZE/32 - 1) ];
for(j=TF_BLOCK_SIZE/32; (j--)>0 ;)
{ shReg[ j ] = shReg[ j - 1];
}
shReg[0] = srcSave;
}
}
/************ TWOFISH CBC mode encryption *****************/
VOID
Encrypt( DWORD *IVector,
DWORD *KeyAddress,
DWORD *SrcBuffer,
DWORD *DstBuffer,
DWORD Length ) /* in bytes */
{ DWORD i,l;
DWORD ivLocal[4];
for(i=0; i<4; i++) ivLocal[i] = IVector[i&1];
if (Length < (TF_BLOCK_SIZE/8))
{
encrypt_CFB(ivLocal,KeyAddress,SrcBuffer,DstBuffer,Length);
return;
}
/* CBC encryption */
for(i=0, l=0; l<(Length>>4); l++, i=i+4)
{
// do ECB encryption of (Initial_Vector XOR Data)
ivLocal[0] ^= SrcBuffer[i ];
ivLocal[1] ^= SrcBuffer[i+1];
ivLocal[2] ^= SrcBuffer[i+2];
ivLocal[3] ^= SrcBuffer[i+3];
blockEncrypt( ivLocal, (KeyInstance *)KeyAddress );
DstBuffer[i ] = ivLocal[0];
DstBuffer[i+1] = ivLocal[1];
DstBuffer[i+2] = ivLocal[2];
DstBuffer[i+3] = ivLocal[3];
}
}
/************** TWOFISH CBC mode decryption ****************/
VOID
Decrypt( DWORD *IVector,
DWORD *KeyAddress,
DWORD *SrcBuffer,
DWORD *DstBuffer,
DWORD Length ) // in bytes
{ DWORD i,j,l;
DWORD ivOld[4], ivNew[4], buf[4];
for(i=0; i<4; i++) ivOld[i] = IVector[i&1];
if (Length < (TF_BLOCK_SIZE/8))
{
decrypt_CFB(ivOld,KeyAddress,SrcBuffer,DstBuffer,Length);
return;
}
/* CBC decryption */
for(i=0, l=0; l<(Length>>4) ; l++, i = i+4)
{
// Encrypted Data -> new IV,
// then do ECB decryption of Encrypted Data,
// then XOR decrypted data with old IV
for(j=0; j<4; j++) buf[j] = ivNew[j] = SrcBuffer[i+j];
blockDecrypt( buf, (KeyInstance *)KeyAddress );
for(j=0; j<4; j++)
{ DstBuffer[i+j] = ivOld[j] ^ buf[j];
ivOld[j] = ivNew[j];
}
}
}
char twofish_c[]="$Id: twofish.c,v 1.3 2002/10/29 07:11:46 crypt Rel-1.6-5 $";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -