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

📄 aes.cpp

📁 RC2算法源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
 * 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 + -