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

📄 rijndael.cpp

📁 crypt++ 3.2版本
💻 CPP
字号:
// rijndael.cpp - modified by Wei Dai from Brian Gladman's rijndael.c

/* This is an independent implementation of the encryption algorithm:	*/
/*																		*/
/*		   RIJNDAEL by Joan Daemen and Vincent Rijmen					*/
/*																		*/
/* which is a candidate algorithm in the Advanced Encryption Standard	*/
/* programme of the US National Institute of Standards and Technology.	*/
/*																		*/
/* Copyright in this implementation is held by Dr B R Gladman but I 	*/
/* hereby give permission for its free direct or derivative use subject */
/* to acknowledgment of its origin and compliance with any conditions	*/
/* that the originators of the algorithm place on its exploitation. 	*/
/*																		*/
/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999 	*/

#include "pch.h"
#include "rijndael.h"

NAMESPACE_BEGIN(CryptoPP)

/* initialise the key schedule from the user supplied key	*/

#define ls_box(x)							 \
	((word32)sbx_tab[GETBYTE(x, 0)] <<	0) ^	\
	((word32)sbx_tab[GETBYTE(x, 1)] <<	8) ^	\
	((word32)sbx_tab[GETBYTE(x, 2)] << 16) ^	\
	((word32)sbx_tab[GETBYTE(x, 3)] << 24)

Rijndael::Rijndael(const byte *userKey, unsigned int keylen)
	: k_len(keylen/4), key(k_len*5 + 24)
{
	assert(keylen == KeyLength(keylen));

	word32 t;
	int i;

	GetUserKeyLittleEndian(key.ptr, k_len, userKey, keylen);

	switch(k_len)
	{
		case 4: t = key[3];
				for(i = 0; i < 10; ++i)
				{
					t = rotrFixed(t, 8);
					t = ls_box(t) ^ rco_tab[i];
					key[4 * i + 4] = t ^= key[4 * i];
					key[4 * i + 5] = t ^= key[4 * i + 1];
					key[4 * i + 6] = t ^= key[4 * i + 2];
					key[4 * i + 7] = t ^= key[4 * i + 3];
				}
				break;

		case 6: t = key[5];
				for(i = 0; i < 8; ++i)
				{
					t = rotrFixed(t,  8);
					t = ls_box(t) ^ rco_tab[i];
					key[6 * i + 6] = t ^= key[6 * i];
					key[6 * i + 7] = t ^= key[6 * i + 1];
					key[6 * i + 8] = t ^= key[6 * i + 2];
					key[6 * i + 9] = t ^= key[6 * i + 3];
					key[6 * i + 10] = t ^= key[6 * i + 4];
					key[6 * i + 11] = t ^= key[6 * i + 5];
				}
				break;

		case 8: t = key[7];
				for(i = 0; i < 7; ++i)
				{
					t = rotrFixed(t,  8);
					t = ls_box(t) ^ rco_tab[i];
					key[8 * i + 8] = t ^= key[8 * i];
					key[8 * i + 9] = t ^= key[8 * i + 1];
					key[8 * i + 10] = t ^= key[8 * i + 2];
					key[8 * i + 11] = t ^= key[8 * i + 3];
					key[8 * i + 12] = t = key[8 * i + 4] ^ ls_box(t);				\
					key[8 * i + 13] = t ^= key[8 * i + 5];
					key[8 * i + 14] = t ^= key[8 * i + 6];
					key[8 * i + 15] = t ^= key[8 * i + 7];
				}
				break;
	}
}

/* encrypt a block of text	*/

#define f_rn(bo, bi, n, k)							\
	bo[n] =  ft_tab[0][GETBYTE(bi[n],0)] ^			   \
			 ft_tab[1][GETBYTE(bi[(n + 1) & 3],1)] ^   \
			 ft_tab[2][GETBYTE(bi[(n + 2) & 3],2)] ^   \
			 ft_tab[3][GETBYTE(bi[(n + 3) & 3],3)] ^ *(k + n)

#define f_rl(bo, bi, n, k)										\
	bo[n] = (word32)sbx_tab[GETBYTE(bi[n],0)] ^ 				   \
		rotlFixed(((word32)sbx_tab[GETBYTE(bi[(n + 1) & 3],1)]),  8) ^	\
		rotlFixed(((word32)sbx_tab[GETBYTE(bi[(n + 2) & 3],2)]), 16) ^	\
		rotlFixed(((word32)sbx_tab[GETBYTE(bi[(n + 3) & 3],3)]), 24) ^ *(k + n)

#define f_nround(bo, bi, k) \
	f_rn(bo, bi, 0, k); 	\
	f_rn(bo, bi, 1, k); 	\
	f_rn(bo, bi, 2, k); 	\
	f_rn(bo, bi, 3, k); 	\
	k += 4

#define f_lround(bo, bi, k) \
	f_rl(bo, bi, 0, k); 	\
	f_rl(bo, bi, 1, k); 	\
	f_rl(bo, bi, 2, k); 	\
	f_rl(bo, bi, 3, k)

void RijndaelEncryption::ProcessBlock(const byte *inBlock, byte *outBlock) const
{
	word32 b0[4], b1[4];

	GetBlockLittleEndian(inBlock, b0[0], b0[1], b0[2], b0[3]);

	b0[0] ^= key[0];
	b0[1] ^= key[1];
	b0[2] ^= key[2];
	b0[3] ^= key[3];

	const word32 *kp = key + 4;

	if(k_len > 6)
	{
		f_nround(b1, b0, kp); f_nround(b0, b1, kp);
	}

	if(k_len > 4)
	{
		f_nround(b1, b0, kp); f_nround(b0, b1, kp);
	}

	f_nround(b1, b0, kp); f_nround(b0, b1, kp);
	f_nround(b1, b0, kp); f_nround(b0, b1, kp);
	f_nround(b1, b0, kp); f_nround(b0, b1, kp);
	f_nround(b1, b0, kp); f_nround(b0, b1, kp);
	f_nround(b1, b0, kp); f_lround(b0, b1, kp);

	PutBlockLittleEndian(outBlock, b0[0], b0[1], b0[2], b0[3]);
}

// convert encryption key schedule to decryption key schedule

#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)

#define imix_col(y,x)		\
	u	= star_x(x);		\
	v	= star_x(u);		\
	w	= star_x(v);		\
	t	= w ^ (x);			\
   (y)	= u ^ v ^ w;		\
   (y) ^= rotrFixed(u ^ t,	8) ^ \
		  rotrFixed(v ^ t, 16) ^ \
		  rotrFixed(t,24)

RijndaelDecryption::RijndaelDecryption(const byte *userKey, unsigned int keylength)
	: Rijndael(userKey, keylength)
{
	word32 t, u, v, w;

	int i;
	for(i = 4; i < 4 * k_len + 24; ++i)
	{
		imix_col(key[i], key[i]);
	}
}

/* decrypt a block of text	*/

#define i_rn(bo, bi, n, k)							\
	bo[n] =  it_tab[0][GETBYTE(bi[n],0)] ^			   \
			 it_tab[1][GETBYTE(bi[(n + 3) & 3],1)] ^   \
			 it_tab[2][GETBYTE(bi[(n + 2) & 3],2)] ^   \
			 it_tab[3][GETBYTE(bi[(n + 1) & 3],3)] ^ *(k + n)

#define i_rl(bo, bi, n, k)										\
	bo[n] = (word32)isb_tab[GETBYTE(bi[n],0)] ^ 				   \
		rotlFixed(((word32)isb_tab[GETBYTE(bi[(n + 3) & 3],1)]),  8) ^	\
		rotlFixed(((word32)isb_tab[GETBYTE(bi[(n + 2) & 3],2)]), 16) ^	\
		rotlFixed(((word32)isb_tab[GETBYTE(bi[(n + 1) & 3],3)]), 24) ^ *(k + n)

#define i_nround(bo, bi, k) \
	i_rn(bo, bi, 0, k); 	\
	i_rn(bo, bi, 1, k); 	\
	i_rn(bo, bi, 2, k); 	\
	i_rn(bo, bi, 3, k); 	\
	k -= 4

#define i_lround(bo, bi, k) \
	i_rl(bo, bi, 0, k); 	\
	i_rl(bo, bi, 1, k); 	\
	i_rl(bo, bi, 2, k); 	\
	i_rl(bo, bi, 3, k)

void RijndaelDecryption::ProcessBlock(const byte *inBlock, byte *outBlock) const
{
	word32	b0[4], b1[4];

	GetBlockLittleEndian(inBlock, b0[0], b0[1], b0[2], b0[3]);

	b0[0] ^= key[4 * k_len + 24];
	b0[1] ^= key[4 * k_len + 25];
	b0[2] ^= key[4 * k_len + 26];
	b0[3] ^= key[4 * k_len + 27];

	const word32 *kp = key + 4 * (k_len + 5);

	if(k_len > 6)
	{
		i_nround(b1, b0, kp); i_nround(b0, b1, kp);
	}

	if(k_len > 4)
	{
		i_nround(b1, b0, kp); i_nround(b0, b1, kp);
	}

	i_nround(b1, b0, kp); i_nround(b0, b1, kp);
	i_nround(b1, b0, kp); i_nround(b0, b1, kp);
	i_nround(b1, b0, kp); i_nround(b0, b1, kp);
	i_nround(b1, b0, kp); i_nround(b0, b1, kp);
	i_nround(b1, b0, kp); i_lround(b0, b1, kp);

	PutBlockLittleEndian(outBlock, b0[0], b0[1], b0[2], b0[3]);
}

NAMESPACE_END

⌨️ 快捷键说明

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