Cryptography - AddRoundKey Transformation



Data is encrypted and decrypted using a number of different transformations by the Advanced Encryption Standard, or AES. One of these transformations is AddRoundKey.

AddRoundKey requires rotating between a chunk of the data and a different encryption key during the encryption process. Like a secret code, this key is used to purposely to scramble the data.

How it Works?

The AddRoundKey transformation is a step in the Advanced Encryption Standard (AES) cryptography technology. Data has to be encrypted and decrypted using this process. It works as follows −

  • Key Addition − Each byte of the data is combined with a corresponding byte of the encryption key using a simple bitwise XOR operation in the AddRoundKey transformation. It means that if the bit in the data and the corresponding bit in the key disagree, the resulting bit in the encrypted data will be set to 1; otherwise, it will be set to 0.
  • Key Expansion − This process encrypts the encryption key before applying the AddRoundKey transformation. This process creates a unique set of round keys for each encryption round.
  • Round Keys − Each round key is created from the original encryption key and is used to encrypt a particular round of data. The AddRoundKey transformation combines each byte of the input with the matching byte of the round key to produce the encrypted output.

Features

  • Each cycle of AES encryption has a unique key.
  • With the AddRoundKey transformation, every data byte is XORed with its corresponding round key byte.
  • Unauthorised entities will find it difficult to decode the encrypted transmission when the data is XORed.
  • By using different keys for each round, AES improves the encryption, enhancing its complexity and security.

Implementation using Python

Using list comprehension and Python's built-in zip function, this Python code iterates over corresponding bytes of the data and the round key, applying the XOR operator (\) to each pair of bytes for implementing AddRound Key.

Example

def addRoundKey(data, round_key):
   return bytes(a ^ b for a, b in zip(data, round_key))

# function execution
data = b'\x12\x34\x56\x78'
round_key = b'\xAB\xCD\xEF\x01'
encrypted_data = addRoundKey(data, round_key)
print("The Encrypted Data:", encrypted_data.hex())

Following is the output of the above example −

Input/Output

The Encrypted Data: b9f9b979

Implementation using Java

Now we will use Java to implement the Add Round key Transformation. Java uses a simple loop to iterate over each byte of the data and the round key in order to perform the XOR operation (^). Java's primitive array type, byte[] is used to store the data and round key. So the code is given below −

Example

public class AddRoundKey {
   public static byte[] addRoundKey(byte[] data, byte[] roundKey) {
      byte[] encryptedData = new byte[data.length];
      for (int i = 0; i < data.length; i++) {
         encryptedData[i] = (byte) (data[i] ^ roundKey[i]);
      }
      return encryptedData;
   }

   public static void main(String[] args) {
      byte[] data = {(byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78};
      byte[] roundKey = {(byte) 0xAB, (byte) 0xCD, (byte) 0xEF, (byte) 0x01};
      byte[] encryptedData = addRoundKey(data, roundKey);
      System.out.print("Encrypted Data: ");
      for (byte b : encryptedData) {
         System.out.printf("%02X ", b);
      }
   }
}

Following is the output of the above example −

Input/Output

Encrypted Data: B9F9B979

Implementation using C++

This C++ implementation uses a std::vector to store both the data and the round key. A simple for loop is used to iterate over each byte of the data and round key in order to do the XOR operation (^). The encrypted data is then stored in an extra std::vector after that. The code is following −

Example

#include <iostream>
#include <vector>

std::vector<unsigned char> addRoundKey(const std::vector<unsigned char>& data, const std::vector<unsigned char>& roundKey) {
   std::vector<unsigned char> encryptedData;
   for (size_t i = 0; i < data.size(); ++i) {
      encryptedData.push_back(data[i] ^ roundKey[i]);
   }
   return encryptedData;
}

int main() {
   std::vector<unsigned char> data = {0x12, 0x34, 0x56, 0x78};
   std::vector<unsigned char> roundKey = {0xAB, 0xCD, 0xEF, 0x01};
   std::vector<unsigned char> encryptedData = addRoundKey(data, roundKey);
   std::cout << "Encrypted Data: ";
   for (auto byte : encryptedData) {
      printf("%02X ", byte);
   }
   return 0;
}

Following is the output of the above example −

Input/Output

Encrypted Data: B9 F9 B9 79 

Summary

The AddRoundKey transformation is the essential component of the Advanced Encryption Standard (AES) cryptographic technique. Each byte of the data is combined with a corresponding byte of the encryption key using a bitwise XOR method. There are AddRoundKey implementations in Python, Java, and C++. The process is the same for all implementations: iterating over the round key and related data bytes, XORing the result, and finally returning the encrypted data.

Advertisements