rijndael.cpp

来自「提供加密的c/s 聊天程序。用到对称加密算法和非对称加密算法」· C++ 代码 · 共 1,439 行 · 第 1/5 页

CPP
1,439
字号
		209336225, 24197544, 376187827, 459744698, 
		945164165, 895287692, 574624663, 793451934, 
		1679968233, 1764313568, 2117360635, 1933530610, 
		1343127501, 1560637892, 1243112415, 1192455638, 
		-590686415, -775825096, -958608605, -875051734, 
		-387518699, -437395172, -219090169, -262898, 
		-1265457287, -1181111952, -1367032981, -1550863006, 
		-2134991011, -1917480620, -1700232369, -1750889146
};

const int CRijndael::sm_U4[256] =
{
	0, 151849742, 303699484, 454499602, 
		607398968, 758720310, 908999204, 1059270954, 
		1214797936, 1097159550, 1517440620, 1400849762, 
		1817998408, 1699839814, 2118541908, 2001430874, 
		-1865371424, -1713521682, -2100648196, -1949848078, 
		-1260086056, -1108764714, -1493267772, -1342996022, 
		-658970480, -776608866, -895287668, -1011878526, 
		-57883480, -176042074, -292105548, -409216582, 
		1002142683, 850817237, 698445255, 548169417, 
		529487843, 377642221, 227885567, 77089521, 
		1943217067, 2061379749, 1640576439, 1757691577, 
		1474760595, 1592394909, 1174215055, 1290801793, 
		-1418998981, -1570324427, -1183720153, -1333995991, 
		-1889540349, -2041385971, -1656360673, -1807156719, 
		-486304949, -368142267, -249985705, -132870567, 
		-952647821, -835013507, -718427793, -601841055, 
		1986918061, 2137062819, 1685577905, 1836772287, 
		1381620373, 1532285339, 1078185097, 1229899655, 
		1040559837, 923313619, 740276417, 621982671, 
		439452389, 322734571, 137073913, 19308535, 
		-423803315, -273658557, -190361519, -39167137, 
		-1031181707, -880516741, -795640727, -643926169, 
		-1361764803, -1479011021, -1127282655, -1245576401, 
		-1964953083, -2081670901, -1728371687, -1846137065, 
		1305906550, 1155237496, 1607244650, 1455525988, 
		1776460110, 1626319424, 2079897426, 1928707164, 
		96392454, 213114376, 396673818, 514443284, 
		562755902, 679998000, 865136418, 983426092, 
		-586793578, -737462632, -820237430, -971956092, 
		-114159186, -264299872, -349698126, -500888388, 
		-1787927066, -1671205144, -2022411270, -1904641804, 
		-1319482914, -1202240816, -1556062270, -1437772596, 
		-321194175, -438830001, -20913827, -137500077, 
		-923870343, -1042034569, -621490843, -738605461, 
		-1531793615, -1379949505, -1230456531, -1079659997, 
		-2138668279, -1987344377, -1835231979, -1684955621, 
		2081048481, 1963412655, 1846563261, 1729977011, 
		1480485785, 1362321559, 1243905413, 1126790795, 
		878845905, 1030690015, 645401037, 796197571, 
		274084841, 425408743, 38544885, 188821243, 
		-681472870, -563312748, -981755258, -864644728, 
		-212492126, -94852180, -514869570, -398279248, 
		-1626745622, -1778065436, -1928084746, -2078357000, 
		-1153566510, -1305414692, -1457000754, -1607801408, 
		1202797690, 1320957812, 1437280870, 1554391400, 
		1669664834, 1787304780, 1906247262, 2022837584, 
		265905162, 114585348, 499347990, 349075736, 
		736970802, 585122620, 972512814, 821712160, 
		-1699282452, -1816524062, -2001922064, -2120213250, 
		-1098699308, -1215420710, -1399243832, -1517014842, 
		-757114468, -606973294, -1060810880, -909622130, 
		-152341084, -1671510, -453942344, -302225226, 
		174567692, 57326082, 410887952, 292596766, 
		777231668, 660510266, 1011452712, 893681702, 
		1108339068, 1258480242, 1343618912, 1494807662, 
		1715193156, 1865862730, 1948373848, 2100090966, 
		-1593017801, -1476300487, -1290376149, -1172609243, 
		-2059905521, -1942659839, -1759363053, -1641067747, 
		-379313593, -529979063, -75615141, -227328171, 
		-850391425, -1000536719, -548792221, -699985043, 
		836553431, 953270745, 600235211, 718002117, 
		367585007, 484830689, 133361907, 251657213, 
		2041877159, 1891211689, 1806599355, 1654886325, 
		1568718495, 1418573201, 1335535747, 1184342925
};

const char CRijndael::sm_rcon[30] =
{
	1, 2, 4, 8, 16, 32, 
		64, -128, 27, 54, 108, -40, 
		-85, 77, -102, 47, 94, -68, 
		99, -58, -105, 53, 106, -44, 
		-77, 125, -6, -17, -59, -111
};

const int CRijndael::sm_shifts[3][4][2] =
{
	{ {0, 0}, {1, 3}, {2, 2}, {3, 1} },
	{ {0, 0}, {1, 5}, {2, 4}, {3, 3} },
	{ {0, 0}, {1, 7}, {3, 5}, {4, 4} }
};

//Error Messages
char const* CRijndael::sm_szErrorMsg1 = "Object not Initialized";
char const* CRijndael::sm_szErrorMsg2 = "Data not multiple of Block Size";

//Null chain
char const* CRijndael::sm_chain0 = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";

//CONSTRUCTOR
CRijndael::CRijndael() : m_bKeyInit(false)
{
}

//DESTRUCTOR
CRijndael::~CRijndael()
{
}

//Expand a user-supplied key material into a session key.
// key        - The 128/192/256-bit user-key to use.
// chain      - initial chain block for CBC and CFB modes.
// keylength  - 16, 24 or 32 bytes
// blockSize  - The block size in bytes of this Rijndael (16, 24 or 32 bytes).
void CRijndael::MakeKey(char const* key, char const* chain, int keylength, int blockSize)
{
	if(NULL == key)
		throw exception("Empty key");
	if(!(16==keylength || 24==keylength || 32==keylength))
		throw exception("Incorrect key length");
	if(!(16==blockSize || 24==blockSize || 32==blockSize))
		throw exception("Incorrect block length");
	m_keylength = keylength;
	m_blockSize = blockSize;
	//Initialize the chain
	memcpy(m_chain0, chain, m_blockSize);
	memcpy(m_chain, chain, m_blockSize);
	//Calculate Number of Rounds
	switch(m_keylength)
	{
	case 16:
		m_iROUNDS = (m_blockSize == 16) ? 10 : (m_blockSize == 24 ? 12 : 14);
		break;
		
	case 24:
		m_iROUNDS = (m_blockSize != 32) ? 12 : 14;
		break;
		
	default: // 32 bytes = 256 bits
		m_iROUNDS = 14;
	}
	int BC = m_blockSize / 4;
	int i, j;
	for(i=0; i<=m_iROUNDS; i++)
	{
		for(j=0; j<BC; j++)
			m_Ke[i][j] = 0;
	}
	for(i=0; i<=m_iROUNDS; i++)
	{
		for(j=0; j<BC; j++)
			m_Kd[i][j] = 0;
	}
	int ROUND_KEY_COUNT = (m_iROUNDS + 1) * BC;
	int KC = m_keylength/4;
	//Copy user material bytes into temporary ints
	int* pi = tk;
	char const* pc = key;
	for(i=0; i<KC; i++)
	{
		*pi = (unsigned char)*(pc++) << 24;
		*pi |= (unsigned char)*(pc++) << 16;
		*pi |= (unsigned char)*(pc++) << 8;
		*(pi++) |= (unsigned char)*(pc++);
	}
	//Copy values into round key arrays
	int t = 0;
	for(j=0; (j<KC)&&(t<ROUND_KEY_COUNT); j++,t++)
	{
		m_Ke[t/BC][t%BC] = tk[j];
		m_Kd[m_iROUNDS - (t/BC)][t%BC] = tk[j];
	}
	int tt, rconpointer = 0;
	while(t < ROUND_KEY_COUNT)
	{
		//Extrapolate using phi (the round key evolution function)
		tt = tk[KC-1];
		tk[0] ^= (sm_S[(tt >> 16) & 0xFF] & 0xFF) << 24 ^
			(sm_S[(tt >>  8) & 0xFF] & 0xFF) << 16 ^
			(sm_S[ tt & 0xFF] & 0xFF) <<  8 ^
			(sm_S[(tt >> 24) & 0xFF] & 0xFF) ^
			(sm_rcon[rconpointer++]  & 0xFF) << 24;
		if(KC != 8)
			for(i=1, j=0; i<KC;)
				tk[i++] ^= tk[j++];
			else
			{
				for(i=1, j=0; i<KC/2; )
					tk[i++] ^= tk[j++];
				tt = tk[KC/2-1];
				tk[KC/2] ^= (sm_S[ tt & 0xFF] & 0xFF) ^
					(sm_S[(tt >>  8) & 0xFF] & 0xFF) <<  8 ^
					(sm_S[(tt >> 16) & 0xFF] & 0xFF) << 16 ^
					(sm_S[(tt >> 24) & 0xFF] & 0xFF) << 24;
				for(j = KC/2, i=j+1; i<KC; )
					tk[i++] ^= tk[j++];
			}
			//Copy values into round key arrays
			for(j=0; (j<KC) && (t<ROUND_KEY_COUNT); j++, t++)
			{
				m_Ke[t/BC][t%BC] = tk[j];
				m_Kd[m_iROUNDS - (t/BC)][t%BC] = tk[j];
			}
	}
	//Inverse MixColumn where needed
	for(int r=1; r<m_iROUNDS; r++)
		for(j=0; j<BC; j++)
		{
			tt = m_Kd[r][j];
			m_Kd[r][j] = sm_U1[(tt >> 24) & 0xFF] ^
				sm_U2[(tt >> 16) & 0xFF] ^
				sm_U3[(tt >>  8) & 0xFF] ^
				sm_U4[tt & 0xFF];
		}
		m_bKeyInit = true;
}

//Convenience method to encrypt exactly one block of plaintext, assuming
//Rijndael's default block size (128-bit).
// in         - The plaintext
// result     - The ciphertext generated from a plaintext using the key
void CRijndael::DefEncryptBlock(char const* in, char* result)
{
	if(false==m_bKeyInit)
		throw exception(sm_szErrorMsg1);
	int* Ker = m_Ke[0];
	int t0 = ((unsigned char)*(in++) << 24);
	t0 |= ((unsigned char)*(in++) << 16);
	t0 |= ((unsigned char)*(in++) << 8);
	(t0 |= (unsigned char)*(in++)) ^= Ker[0];
	int t1 = ((unsigned char)*(in++) << 24);
	t1 |= ((unsigned char)*(in++) << 16);
	t1 |= ((unsigned char)*(in++) << 8);
	(t1 |= (unsigned char)*(in++)) ^= Ker[1];
	int t2 = ((unsigned char)*(in++) << 24);
	t2 |= ((unsigned char)*(in++) << 16);
	t2 |= ((unsigned char)*(in++) << 8);
	(t2 |= (unsigned char)*(in++)) ^= Ker[2];
	int t3 = ((unsigned char)*(in++) << 24);
	t3 |= ((unsigned char)*(in++) << 16);
	t3 |= ((unsigned char)*(in++) << 8);
	(t3 |= (unsigned char)*(in++)) ^= Ker[3];
	int a0, a1, a2, a3;
	//Apply Round Transforms
	for (int r = 1; r < m_iROUNDS; r++)
	{
		Ker = m_Ke[r];
		a0 = (sm_T1[(t0 >> 24) & 0xFF] ^
			sm_T2[(t1 >> 16) & 0xFF] ^
			sm_T3[(t2 >>  8) & 0xFF] ^
			sm_T4[t3 & 0xFF]) ^ Ker[0];
		a1 = (sm_T1[(t1 >> 24) & 0xFF] ^
			sm_T2[(t2 >> 16) & 0xFF] ^
			sm_T3[(t3 >>  8) & 0xFF] ^
			sm_T4[t0 & 0xFF]) ^ Ker[1];
		a2 = (sm_T1[(t2 >> 24) & 0xFF] ^
			sm_T2[(t3 >> 16) & 0xFF] ^
			sm_T3[(t0 >>  8) & 0xFF] ^
			sm_T4[t1 & 0xFF]) ^ Ker[2];
		a3 = (sm_T1[(t3 >> 24) & 0xFF] ^
			sm_T2[(t0 >> 16) & 0xFF] ^
			sm_T3[(t1 >>  8) & 0xFF] ^
			sm_T4[t2 & 0xFF]) ^ Ker[3];
		t0 = a0;
		t1 = a1;
		t2 = a2;
		t3 = a3;
	}
	//Last Round is special
	Ker = m_Ke[m_iROUNDS];
	int tt = Ker[0];
	result[0] = sm_S[(t0 >> 24) & 0xFF] ^ (tt >> 24);
	result[1] = sm_S[(t1 >> 16) & 0xFF] ^ (tt >> 16);
	result[2] = sm_S[(t2 >>  8) & 0xFF] ^ (tt >>  8);
	result[3] = sm_S[t3 & 0xFF] ^ tt;
	tt = Ker[1];
	result[4] = sm_S[(t1 >> 24) & 0xFF] ^ (tt >> 24);
	result[5] = sm_S[(t2 >> 16) & 0xFF] ^ (tt >> 16);
	result[6] = sm_S[(t3 >>  8) & 0xFF] ^ (tt >>  8);
	result[7] = sm_S[t0 & 0xFF] ^ tt;
	tt = Ker[2];
	result[8] = sm_S[(t2 >> 24) & 0xFF] ^ (tt >> 24);
	result[9] = sm_S[(t3 >> 16) & 0xFF] ^ (tt >> 16);
	result[10] = sm_S[(t0 >>  8) & 0xFF] ^ (tt >>  8);
	result[11] = sm_S[t1 & 0xFF] ^ tt;
	tt = Ker[3];

⌨️ 快捷键说明

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