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

📄 serpent.c

📁 一个加密库代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	k_set(18,a,b,c,d);sb1(a,b,c,d,e,f,g,h);k_get(18,e,f,g,h);
	k_set(19,a,b,c,d);sb0(a,b,c,d,e,f,g,h);k_get(19,e,f,g,h);
	k_set(20,a,b,c,d);sb7(a,b,c,d,e,f,g,h);k_get(20,e,f,g,h);
	k_set(21,a,b,c,d);sb6(a,b,c,d,e,f,g,h);k_get(21,e,f,g,h);
	k_set(22,a,b,c,d);sb5(a,b,c,d,e,f,g,h);k_get(22,e,f,g,h);
	k_set(23,a,b,c,d);sb4(a,b,c,d,e,f,g,h);k_get(23,e,f,g,h);
	k_set(24,a,b,c,d);sb3(a,b,c,d,e,f,g,h);k_get(24,e,f,g,h);
	k_set(25,a,b,c,d);sb2(a,b,c,d,e,f,g,h);k_get(25,e,f,g,h);
	k_set(26,a,b,c,d);sb1(a,b,c,d,e,f,g,h);k_get(26,e,f,g,h);
	k_set(27,a,b,c,d);sb0(a,b,c,d,e,f,g,h);k_get(27,e,f,g,h);
	k_set(28,a,b,c,d);sb7(a,b,c,d,e,f,g,h);k_get(28,e,f,g,h);
	k_set(29,a,b,c,d);sb6(a,b,c,d,e,f,g,h);k_get(29,e,f,g,h);
	k_set(30,a,b,c,d);sb5(a,b,c,d,e,f,g,h);k_get(30,e,f,g,h);
	k_set(31,a,b,c,d);sb4(a,b,c,d,e,f,g,h);k_get(31,e,f,g,h);
	k_set(32,a,b,c,d);sb3(a,b,c,d,e,f,g,h);k_get(32,e,f,g,h);
}

void serpentEncrypt(SERPENTCTX* pCtx,
					const WORD32* pInBlock,
					WORD32* pOutBlock)
{
	WORD32 a,b,c,d,e,f,g,h;
	WORD32 t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16;
	WORD32* l_key = pCtx->l_key;

	a = pInBlock[0];
	b = pInBlock[1];
	c = pInBlock[2];
	d = pInBlock[3];

	// perform 32 rounds of encryption
	k_xor( 0,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h);
	k_xor( 1,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d);
	k_xor( 2,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h);
	k_xor( 3,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d);
	k_xor( 4,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h);
	k_xor( 5,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d);
	k_xor( 6,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h);
	k_xor( 7,e,f,g,h); sb7(e,f,g,h,a,b,c,d); rot(a,b,c,d);
	k_xor( 8,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h);
	k_xor( 9,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d);
	k_xor(10,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h);
	k_xor(11,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d);
	k_xor(12,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h);
	k_xor(13,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d);
	k_xor(14,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h);
	k_xor(15,e,f,g,h); sb7(e,f,g,h,a,b,c,d); rot(a,b,c,d);
	k_xor(16,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h);
	k_xor(17,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d);
	k_xor(18,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h);
	k_xor(19,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d);
	k_xor(20,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h);
	k_xor(21,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d);
	k_xor(22,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h);
	k_xor(23,e,f,g,h); sb7(e,f,g,h,a,b,c,d); rot(a,b,c,d);
	k_xor(24,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h);
	k_xor(25,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d);
	k_xor(26,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h);
	k_xor(27,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d);
	k_xor(28,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h);
	k_xor(29,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d);
	k_xor(30,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h);
	k_xor(31,e,f,g,h); sb7(e,f,g,h,a,b,c,d); k_xor(32,a,b,c,d);

	pOutBlock[0] = a;
	pOutBlock[1] = b;
	pOutBlock[2] = c;
	pOutBlock[3] = d;
}

void serpentDecrypt(SERPENTCTX* pCtx,
					const WORD32* pInBlock,
					WORD32* pOutBlock)
{
	WORD32 a,b,c,d,e,f,g,h;
	WORD32 t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16;
	WORD32* l_key = pCtx->l_key;

	a = pInBlock[0];
	b = pInBlock[1];
	c = pInBlock[2];
	d = pInBlock[3];

	k_xor(32,a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor(31,e,f,g,h);
	irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor(30,a,b,c,d);
	irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor(29,e,f,g,h);
	irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor(28,a,b,c,d);
	irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor(27,e,f,g,h);
	irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor(26,a,b,c,d);
	irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor(25,e,f,g,h);
	irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor(24,a,b,c,d);
	irot(a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor(23,e,f,g,h);
	irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor(22,a,b,c,d);
	irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor(21,e,f,g,h);
	irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor(20,a,b,c,d);
	irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor(19,e,f,g,h);
	irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor(18,a,b,c,d);
	irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor(17,e,f,g,h);
	irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor(16,a,b,c,d);
	irot(a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor(15,e,f,g,h);
	irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor(14,a,b,c,d);
	irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor(13,e,f,g,h);
	irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor(12,a,b,c,d);
	irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor(11,e,f,g,h);
	irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor(10,a,b,c,d);
	irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor( 9,e,f,g,h);
	irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor( 8,a,b,c,d);
	irot(a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor( 7,e,f,g,h);
	irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor( 6,a,b,c,d);
	irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor( 5,e,f,g,h);
	irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor( 4,a,b,c,d);
	irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor( 3,e,f,g,h);
	irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor( 2,a,b,c,d);
	irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor( 1,e,f,g,h);
	irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor( 0,a,b,c,d);

	pOutBlock[0] = a;
	pOutBlock[1] = b;
	pOutBlock[2] = c;
	pOutBlock[3] = d;
}


// public functions

WORD32 Serpent_GetCipherInfo(CIPHERINFOBLOCK* pInfo)
{
	WORD32 lI;
	WORD8* pSrc;
	WORD8* pDst;
	CIPHERINFOBLOCK tmpInfo;

	tmpInfo.lSizeOf = pInfo->lSizeOf;
	tmpInfo.lBlockSize = SERPENT_BLOCKSIZE;
	tmpInfo.lKeySize = SERPENT_KEYSIZE;
	tmpInfo.blOwnHasher = BOOL_FALSE;
	tmpInfo.lInitDataSize = SERPENT_BLOCKSIZE;
	tmpInfo.lContextSize = sizeof(SERPENTCTX);
	tmpInfo.bCipherIs = CIPHER_IS_BLOCKLINK;

	// copy as many bytes of the information block as possible
	pSrc = (WORD8*) &tmpInfo;
	pDst = (WORD8*) pInfo;
	for (lI = 0; lI < tmpInfo.lSizeOf; lI++)
		*pDst++ = *pSrc++;
	return CIPHER_ERROR_NOERROR;
}

WORD32 Serpent_SelfTest(void* pTestContext)
{
	/*
	* NOTE: These test vectors are NOT official test vectors.
	* I tested this implementation by comparing it with the outputs given
	* in ecb_e_m.txt (see the Serpent package for more details). The official
	* test implementation encrypts the plaintext vector 10,000 times, which
	* makes it fairly slow. That's why I decided to use my own test vectors.
	* However, this implementation was throughly tested and should work fine.
	*/

	const WORD8 testkey[32] =
	{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
	21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 };

	const WORD32 plaintext[4] =
	{ 0x01234567, 0xABCDEF01, 0xA0B1C2D3, 0xE4F58899 };

	const WORD32 cipher_must[4] =
	{ 0xB633567F, 0x52776204, 0x8D761E99, 0x6701200B };

	WORD32 testbuf[4];

	// Addition: test vector of the NIST reference, KEYSIZE=256
	
	const int NIST_LOOPS = 10000;

	// I=0
	// KEY=0000000000000000000000000000000000000000000000000000000000000000
	// PT=00000000000000000000000000000000
	// CT=92efa3ca9477794d31f4df7bce23e60a
	const WORD8 testKeyNist[SERPENT_KEYSIZE] = {
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
		
	const WORD32 plaintextNist[4] = {
		 0x00000000, 0x00000000, 0x00000000, 0x00000000 };

	const WORD32 cipherMustNist[4] = {
		 0xce23e60a, 0x31f4df7b, 0x9477794d, 0x92efa3ca };

	SERPENTCTX* pCtx = (SERPENTCTX*) pTestContext;
	int nI;

	// initialize the cipher
	serpentSetKey(pCtx, testkey, 32);

	// encrypt the test vector
	serpentEncrypt(pCtx, plaintext, testbuf);

	// did it work correctly?
	for (nI = 0; nI < 4; nI++)
	{
		if (testbuf[nI] != cipher_must[nI])
			return CIPHER_ERROR_INVALID;
	}

	// test the decryption
	serpentDecrypt(pCtx, testbuf, testbuf);

	for (nI = 0; nI < 4; nI++)
	{
		if (testbuf[nI] != plaintext[nI])
			return CIPHER_ERROR_INVALID;
	}

	// now for the NIST vector (Monte Carlo test)

	serpentSetKey(pCtx, testKeyNist, sizeof(testKeyNist));

	testbuf[0] = plaintextNist[0];
	testbuf[1] = plaintextNist[1];
	testbuf[2] = plaintextNist[2];
	testbuf[3] = plaintextNist[3];

	for (nI = 0; nI < NIST_LOOPS; nI++)
		serpentEncrypt(pCtx, testbuf, testbuf);

	// did it work correctly?
	for (nI = 0; nI < 4; nI++)
		if (testbuf[nI] != cipherMustNist[nI])
			return CIPHER_ERROR_INVALID;

	return CIPHER_ERROR_NOERROR;
}

WORD32 Serpent_CreateWorkContext(void* pContext,
								 const WORD8* pKey,
								 WORD32 lKeyLen,
								 WORD32 lMode,
								 void* pInitData,
								 Cipher_RandomGenerator GetRndBytes,
								 const void* pRandGenData)
{
	SERPENTCTX* pCtx = (SERPENTCTX*) pContext;
	WORD8* pbInit;

	// legacy or standard?
	pCtx->blLegacy = (CIPHER_GETFLAGS(lMode) & CIPHER_MODE_FLAG_LEGACY) ? BOOL_TRUE : BOOL_FALSE;

	// do the key setup
	serpentSetKey(pCtx, pKey, lKeyLen);

	pbInit = (WORD8*) pInitData;
	if (CIPHER_GETMODE(lMode) == CIPHER_MODE_ENCRYPT)
		GetRndBytes(pbInit, SERPENT_BLOCKSIZE, pRandGenData);

	// set the CBC IV
	if (pCtx->blLegacy)
	{
		pCtx->cbc_iv[0] = BYTES_TO_WORD32_X86(pbInit);
		pCtx->cbc_iv[1] = BYTES_TO_WORD32_X86(pbInit + 4);
		pCtx->cbc_iv[2] = BYTES_TO_WORD32_X86(pbInit + 8);
		pCtx->cbc_iv[3] = BYTES_TO_WORD32_X86(pbInit + 12);
	}
	else
	{
		pCtx->cbc_iv[0] = BYTES_TO_WORD32(pbInit);
		pCtx->cbc_iv[1] = BYTES_TO_WORD32(pbInit + 4);
		pCtx->cbc_iv[2] = BYTES_TO_WORD32(pbInit + 8);
		pCtx->cbc_iv[3] = BYTES_TO_WORD32(pbInit + 12);
	}

	return CIPHER_ERROR_NOERROR;
}

void Serpent_ResetWorkContext(void* pContext,
							  WORD32 lMode,
							  void* pInitData,
							  Cipher_RandomGenerator GetRndBytes,
							  const void* pRandGenData)
{
	SERPENTCTX* pCtx = (SERPENTCTX*) pContext;
	WORD8* pbInit = (WORD8*) pInitData;

	if (CIPHER_GETMODE(lMode) == CIPHER_MODE_ENCRYPT)
		GetRndBytes(pbInit, SERPENT_BLOCKSIZE, pRandGenData);

	if (pCtx->blLegacy)
	{
		pCtx->cbc_iv[0] = BYTES_TO_WORD32_X86(pbInit);
		pCtx->cbc_iv[1] = BYTES_TO_WORD32_X86(pbInit + 4);
		pCtx->cbc_iv[2] = BYTES_TO_WORD32_X86(pbInit + 8);
		pCtx->cbc_iv[3] = BYTES_TO_WORD32_X86(pbInit + 12);
	}
	else
	{
		pCtx->cbc_iv[0] = BYTES_TO_WORD32(pbInit);
		pCtx->cbc_iv[1] = BYTES_TO_WORD32(pbInit + 4);
		pCtx->cbc_iv[2] = BYTES_TO_WORD32(pbInit + 8);
		pCtx->cbc_iv[3] = BYTES_TO_WORD32(pbInit + 12);
	}
}

WORD32 Serpent_DestroyWorkContext(void *pContext)
{
	int nI;
	WORD8* pCtxBuf = (WORD8*) pContext;

	for (nI = 0; nI < sizeof(SERPENTCTX); nI++)
		pCtxBuf[nI] = 0x00;

	return CIPHER_ERROR_NOERROR;
}

void Serpent_EncryptBuffer(void* pContext,
						   const void*  pSource,
						   void* pTarget,
						   WORD32 lNumOfBytes)
{
	WORD32 lNumOfBlocks;
	WORD32 blk[SERPENT_BLOCKSIZE / 4];
	WORD8* pbIn = (WORD8*) pSource;
	WORD8* pbOut = (WORD8*) pTarget;
	SERPENTCTX* pCtx = (SERPENTCTX*) pContext;

	lNumOfBlocks = lNumOfBytes / SERPENT_BLOCKSIZE;

	while (lNumOfBlocks--)
	{
		if (pCtx->blLegacy)
		{
			blk[0] = BYTES_TO_WORD32_X86(pbIn);
			blk[1] = BYTES_TO_WORD32_X86(pbIn + 4);
			blk[2] = BYTES_TO_WORD32_X86(pbIn + 8);
			blk[3] = BYTES_TO_WORD32_X86(pbIn + 12);
		}
		else
		{
			blk[0] = BYTES_TO_WORD32(pbIn);
			blk[1] = BYTES_TO_WORD32(pbIn + 4);
			blk[2] = BYTES_TO_WORD32(pbIn + 8);
			blk[3] = BYTES_TO_WORD32(pbIn + 12);
		}

		blk[0] ^= pCtx->cbc_iv[0];			
		blk[1] ^= pCtx->cbc_iv[1];			
		blk[2] ^= pCtx->cbc_iv[2];			
		blk[3] ^= pCtx->cbc_iv[3];			

		// encrypt the buffer
		serpentEncrypt(pCtx, blk, blk);

		// store the encrypted block
		if (pCtx->blLegacy)
		{
			WORD32_TO_BYTES_X86(blk[0], pbOut)
			WORD32_TO_BYTES_X86(blk[1], pbOut + 4)
			WORD32_TO_BYTES_X86(blk[2], pbOut + 8)
			WORD32_TO_BYTES_X86(blk[3], pbOut + 12)
		}
		else
		{
			WORD32_TO_BYTES(blk[0], pbOut)
			WORD32_TO_BYTES(blk[1], pbOut + 4)
			WORD32_TO_BYTES(blk[2], pbOut + 8)
			WORD32_TO_BYTES(blk[3], pbOut + 12)
		}

		// set the new IV
		pCtx->cbc_iv[0] = blk[0];
		pCtx->cbc_iv[1] = blk[1];
		pCtx->cbc_iv[2] = blk[2];
		pCtx->cbc_iv[3] = blk[3];

		pbIn += SERPENT_BLOCKSIZE;
		pbOut += SERPENT_BLOCKSIZE;
	}
}

void Serpent_DecryptBuffer(void* pContext,
						   const void* pSource,
						   void* pTarget,
						   WORD32 lNumOfBytes,
						   const void* pPreviousBlock)
{
	WORD32 lNumOfBlocks;
	WORD8* pbIn = (WORD8*) pSource;
	WORD8* pbOut = (WORD8*) pTarget;
	WORD8* pbPrev = (WORD8*) pPreviousBlock;
	WORD32 blk[4];
	WORD32 save_cbc_iv[4];
	SERPENTCTX* pCtx = (SERPENTCTX*) pContext;

	// load a new IV, if necessary
	if (pbPrev != CIPHER_NULL)
	{
		if (pCtx->blLegacy)
		{
			pCtx->cbc_iv[0] = BYTES_TO_WORD32_X86(pbPrev);
			pCtx->cbc_iv[1] = BYTES_TO_WORD32_X86(pbPrev + 4);
			pCtx->cbc_iv[2] = BYTES_TO_WORD32_X86(pbPrev + 8);
			pCtx->cbc_iv[3] = BYTES_TO_WORD32_X86(pbPrev + 12);
		}
		else
		{
			pCtx->cbc_iv[0] = BYTES_TO_WORD32(pbPrev);
			pCtx->cbc_iv[1] = BYTES_TO_WORD32(pbPrev + 4);
			pCtx->cbc_iv[2] = BYTES_TO_WORD32(pbPrev + 8);
			pCtx->cbc_iv[3] = BYTES_TO_WORD32(pbPrev + 12);
		}
	}

	lNumOfBlocks = lNumOfBytes / SERPENT_BLOCKSIZE;

	while (lNumOfBlocks--)
	{
		// load the block
		if (pCtx->blLegacy)
		{
			blk[0] = BYTES_TO_WORD32_X86(pbIn);
			blk[1] = BYTES_TO_WORD32_X86(pbIn + 4);
			blk[2] = BYTES_TO_WORD32_X86(pbIn + 8);
			blk[3] = BYTES_TO_WORD32_X86(pbIn + 12);
		}
		else
		{
			blk[0] = BYTES_TO_WORD32(pbIn);
			blk[1] = BYTES_TO_WORD32(pbIn + 4);
			blk[2] = BYTES_TO_WORD32(pbIn + 8);
			blk[3] = BYTES_TO_WORD32(pbIn + 12);
		}

		// save the current block for later
		save_cbc_iv[0] = blk[0];
		save_cbc_iv[1] = blk[1];
		save_cbc_iv[2] = blk[2];
		save_cbc_iv[3] = blk[3];
		
		// decrypt the block
		serpentDecrypt(pCtx, blk, blk);

		// unchain the block
		blk[0] ^= pCtx->cbc_iv[0];
		blk[1] ^= pCtx->cbc_iv[1];
		blk[2] ^= pCtx->cbc_iv[2];
		blk[3] ^= pCtx->cbc_iv[3];

		// and safe it
		if (pCtx->blLegacy)
		{
			WORD32_TO_BYTES_X86(blk[0], pbOut)
			WORD32_TO_BYTES_X86(blk[1], pbOut + 4)
			WORD32_TO_BYTES_X86(blk[2], pbOut + 8)
			WORD32_TO_BYTES_X86(blk[3], pbOut + 12)
		}
		else
		{
			WORD32_TO_BYTES(blk[0], pbOut)
			WORD32_TO_BYTES(blk[1], pbOut + 4)
			WORD32_TO_BYTES(blk[2], pbOut + 8)
			WORD32_TO_BYTES(blk[3], pbOut + 12)
		}

		// set the new IV
		pCtx->cbc_iv[0] = save_cbc_iv[0];
		pCtx->cbc_iv[1] = save_cbc_iv[1];
		pCtx->cbc_iv[2] = save_cbc_iv[2];
		pCtx->cbc_iv[3] = save_cbc_iv[3];

		pbIn += SERPENT_BLOCKSIZE;
		pbOut += SERPENT_BLOCKSIZE;
	}
}

⌨️ 快捷键说明

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