📄 aes.cpp
字号:
* In the process, it alters the 16-byte value pointed to by ivBytes.
*/
static void Rc6EncryptCbc(unsigned long* S, BYTE* IV, int numberOfBlocks,
BYTE* plaintext, BYTE* ciphertext)
{
for ( ; numberOfBlocks-- > 0; plaintext += 16, ciphertext += 16) {
int i;
/* XOR IV and plaintext */
for (i = 0; i < 16; i++)
IV[i] ^= plaintext[i];
/* Encrypt XORed plaintext */
Rc6EncryptBlock(S, IV, ciphertext);
/* Store ciphertext as IV for next block */
memcpy((void*) IV, (void*) ciphertext, 16);
}
}
/*
* Rc6DecryptCbc() decrypts a specified number of blocks in CBC mode.
* In the process, it alters the 16-byte value pointed to by ivBytes.
*/
static void Rc6DecryptCbc(unsigned long* S, BYTE* IV, int numberOfBlocks,
BYTE* ciphertext, BYTE* plaintext)
{
for ( ; numberOfBlocks-- > 0; ciphertext += 16, plaintext += 16) {
BYTE savedCiphertext[16];
int i;
/* Save ciphertext block in case the ciphertext and plaintext buffers
* overlap */
memcpy((void*) savedCiphertext, (void*) ciphertext, 16);
/* Recover XORed plaintext */
Rc6DecryptBlock(S, ciphertext, plaintext);
/* XOR plaintext and IV to get plaintext */
for (i = 0; i < 16; i++)
plaintext[i] ^= IV[i];
/* Keep ciphertext as IV for next block */
memcpy((void*) IV, (void*) savedCiphertext, 16);
}
}
/*
* Rc6EncryptCfb1() encrypts a specified number of bits (*not* blocks) in
* 1-bit CFB mode. In the process, it alters the 16-byte value pointed
* to by ivBytes.
*/
static void Rc6EncryptCfb1(unsigned long* S, BYTE* IV, int numberOfBits,
BYTE* plaintext, BYTE* ciphertext)
{
int bitsProcessed;
for (bitsProcessed = 0; bitsProcessed < numberOfBits; bitsProcessed++) {
int bitIndex = bitsProcessed % 8;
int bitMask = 0x80 >> bitIndex;
int plaintextBit, maskingBit, ciphertextBit;
BYTE encryptedIv[16];
int i;
if (bitIndex == 0)
*ciphertext = 0;
/* Get bit of plaintext (as a 0-1 value) */
plaintextBit = ((*plaintext & bitMask) != 0);
/* Encrypt IV and get masking bit (as a 0-1 value) for this text bit */
Rc6EncryptBlock(S, IV, encryptedIv);
maskingBit = ((encryptedIv[0] & 0x80) != 0);
/* Compute bit of ciphertext and put it in the current ciphertext byte */
ciphertextBit = plaintextBit ^ maskingBit;
*ciphertext |= (BYTE) (ciphertextBit*bitMask);
/* Now shift the entire IV 1 bit to the left */
for (i = 0; i < 15; i++)
IV[i] = (BYTE) ((IV[i] << 1) | ((IV[i+1] & 0x80) != 0));
IV[15] <<= 1;
/* Put the bit of ciphertext just created into right end of IV */
IV[15] = (BYTE) (IV[15] | ciphertextBit);
/* If that was the end of a byte, bump the plaintext/ciphertext pointers */
if (bitIndex == 7) {
plaintext++;
ciphertext++;
}
}
}
/*
* Rc6DecryptCfb1() decrypts a specified number of bytes (*not* blocks) in
* 1-bit CFB mode. In the process, it alters the 16-byte value pointed
* to by ivBytes.
*/
static void Rc6DecryptCfb1(unsigned long* S, BYTE* IV, int numberOfBits,
BYTE* ciphertext, BYTE* plaintext)
{
int bitsProcessed;
for (bitsProcessed = 0; bitsProcessed < numberOfBits; bitsProcessed++) {
int bitIndex = bitsProcessed % 8;
int bitMask = 0x80 >> bitIndex;
int ciphertextBit, maskingBit, plaintextBit;
BYTE encryptedIv[16];
int i;
if (bitIndex == 0)
*plaintext = 0;
/* Get bit of ciphertext (as a 0-1 value) */
ciphertextBit = ((*ciphertext & bitMask) != 0);
/* Encrypt IV and get masking bit (as a 0-1 value) for this text bit */
Rc6EncryptBlock(S, IV, encryptedIv);
maskingBit = ((encryptedIv[0] & 0x80) != 0);
/* Compute bit of plaintext and put it in the current plaintext byte */
plaintextBit = ciphertextBit ^ maskingBit;
*plaintext |= (BYTE) (plaintextBit*bitMask);
/* Now shift the entire IV 1 bit to the left */
for (i = 0; i < 15; i++)
IV[i] = (BYTE) ((IV[i] << 1) | ((IV[i+1] & 0x80) != 0));
IV[15] <<= 1;
/* Put the bit of ciphertext just used into right end of IV */
IV[15] = (BYTE) (IV[15] | ciphertextBit);
/* If that was the end of a byte, bump the ciphertext/plaintext pointers */
if (bitIndex == 7) {
ciphertext++;
plaintext++;
}
}
}
/*
* Below, we implement all the functions that have actually been specified
* by NIST for their C API.
*/
/*
* makeKey() initializes a keyInstance.
*/
int makeKey(keyInstance* key, BYTE direction, int keyLen, char* keyMaterial)
{
BYTE keyBytes[255];
int count;
if ((direction != DIR_ENCRYPT) && (direction != DIR_DECRYPT))
return BAD_KEY_DIR;
key -> direction = direction;
/* Check key length. RC6 can use keys of length 0-255 bytes
* (0-2040 bits, in multiples of 8). */
if ((keyLen < 0) || (keyLen > 2040) || ((keyLen % 8) != 0))
return BAD_KEY_MAT;
/* Check hexadecimalness of key material */
for (count = 0; count < keyLen/4; count++)
if (!isxdigit(keyMaterial[count]))
return BAD_KEY_MAT;
/* Copy ASCII key */
memcpy(key -> keyMaterial, keyMaterial, keyLen/4);
key -> keyMaterial[keyLen/4] = 0;
key -> keyLen = keyLen;
/* Get key as a sequence of bytes */
ConvertDigitsToBytes(keyMaterial, keyBytes, keyLen/8);
Rc6ComputeKeySchedule(keyBytes, keyLen/8, key -> S);
return TRUE;
}
/*
* cipherInit() initializes a cipherInstance.
*/
int cipherInit(cipherInstance* cipher, BYTE mode, char* IV)
{
int count;
if ((mode != MODE_ECB) && (mode != MODE_CBC) && (mode != MODE_CFB1))
return BAD_CIPHER_MODE;
cipher -> mode = mode;
if (IV != NULL) {
/* Check hexadecimalness of IV material */
for (count = 0; count < 32; count++)
if (!isxdigit(IV[count]))
return BAD_IV_MAT;
/* Get IV as a sequence of bytes */
ConvertDigitsToBytes(IV, cipher -> IV, 16);
}
return TRUE;
}
/*
* blockEncrypt() encrypts some number of blocks of plaintext.
*/
int blockEncrypt(cipherInstance *cipher, keyInstance *key,
BYTE *input, int inputLen, BYTE *outBuffer)
{
if (key -> direction != DIR_ENCRYPT)
return BAD_KEY_MAT;
/* The API document says that BAD_KEY_MATERIAL should be returned
* in this situation; however, there is no such error code. It
* appears that BAD_KEY_MAT (or possibly BAD_KEY_DIR) is appropriate
* here. */
switch(cipher -> mode) {
case MODE_ECB: {
int numberOfBlocks = inputLen/128;
Rc6EncryptEcb(key -> S, numberOfBlocks, input, outBuffer);
/* Note that we completely ignore partial blocks of plaintext */
return (numberOfBlocks*128);
}
case MODE_CBC: {
int numberOfBlocks = inputLen/128;
Rc6EncryptCbc(key -> S, cipher -> IV, numberOfBlocks, input, outBuffer);
/* Note that we completely ignore partial blocks of plaintext */
return (numberOfBlocks*128);
}
case MODE_CFB1: {
Rc6EncryptCfb1(key -> S, cipher -> IV, inputLen, input, outBuffer);
/* Note that we completely process every bit of plaintext */
return inputLen;
}
default: {
return BAD_CIPHER_STATE;
}
}
}
/*
* blockDecrypt() decrypts some number of blocks of ciphertext.
*/
int blockDecrypt(cipherInstance *cipher, keyInstance *key,
BYTE *input, int inputLen, BYTE *outBuffer)
{
if (key -> direction != DIR_DECRYPT)
return BAD_KEY_MAT;
/* The API document says that BAD_KEY_MATERIAL should be returned
* in this situation; however, there is no such error code. It
* appears that BAD_KEY_MAT (or possibly BAD_KEY_DIR) is appropriate
* here. */
switch(cipher -> mode) {
case MODE_ECB: {
int numberOfBlocks = inputLen/128;
Rc6DecryptEcb(key -> S, numberOfBlocks, input, outBuffer);
/* Note that we completely ignore partial blocks of ciphertext */
return (numberOfBlocks*128);
}
case MODE_CBC: {
int numberOfBlocks = inputLen/128;
Rc6DecryptCbc(key -> S, cipher -> IV, numberOfBlocks, input, outBuffer);
/* Note that we completely ignore partial blocks of ciphertext */
return (numberOfBlocks*128);
}
case MODE_CFB1: {
Rc6DecryptCfb1(key -> S, cipher -> IV, inputLen, input, outBuffer);
/* Note that we completely process every bit of plaintext */
return inputLen;
}
default: {
return BAD_CIPHER_STATE;
}
}
}
main()
{
int keyLengthInBytes=16,i;
BYTE key[16]={0xf1,0xe0,0xdf,0xce,0xbd,0xac,0x9b,0x8a,0x79,0x68,0x57,0x46,0x35,0x24,0x13,0x02};
//67452301efcdab893423120178675645 加密==> bbfefd97be074c0205d8733eb0d31ec2
//bbfefd97be074c0205d8733eb0d31ec2 解密==> 67452301efcdab893423120178675645
BYTE plaintext[16]={0x67,0x45,0x23,0x01,0xef,0xcd,0xab,0x89,0x34,0x23,0x12,0x01,0x78,0x67,0x56,0x45};
//BYTE plaintext[16]={0xbb,0xfe,0xfd,0x97,0xbe,0x7,0x4c,0x2,0x5,0xd8,0x73,0x3e,0xb0,0xd3,0x1e,0xc2};
unsigned long S[128];
BYTE ciphertext[128];
printf("plaintext\n");
for(i=0;i<16;i++)printf("%02x ",plaintext[i]);printf("\n\n");
printf("key\n");
for(i=0;i<16;i++)printf("%02x ",key[i]);printf("\n\n");
Rc6ComputeKeySchedule(key,keyLengthInBytes,S);
Rc6EncryptBlock(S,plaintext,ciphertext);
//Rc6DecryptBlock(S,plaintext,ciphertext);
printf("密文\n");
for(i=0;i<16;i++)printf("%x ",ciphertext[i]);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -