/ reference / main.c
main.c
  1  #include <stdio.h>
  2  
  3  #include <stdio.h>
  4  #include <stdint.h>
  5  #include <string.h>
  6  
  7  extern uint8_t dinoxor(uint8_t x0, uint8_t x1);
  8  
  9  // Function to swap two bytes
 10  void swap(uint8_t *a, uint8_t *b) {
 11      uint8_t temp = *a;
 12      *a = *b;
 13      *b = temp;
 14  }
 15  
 16  /**
 17   * Key-Scheduling Algorithm (KSA)
 18   * 
 19   * The KSA initializes and shuffles the state array `S` using the provided key. The state array
 20   * starts as an identity permutation (0 to 255) and is shuffled in a way that is dependent on the key.
 21   * This shuffled state array is crucial for the security of the RC4 stream cipher, as it ensures that
 22   * the generated keystream will be unique for each key.
 23   *
 24   * @param key The encryption key as a string.
 25   * @param S The state array to be initialized and shuffled by the KSA.
 26   */
 27  void KSA(char *key, uint8_t S[256]) {
 28      int len = strlen(key);
 29      for(int i = 0; i < 256; i++)
 30          S[i] = i;
 31      int j = 0;
 32      for(int i = 0; i < 256; i++) {
 33          // The KSA shuffling logic:
 34          // Each byte of the key influences the shuffling of the state array `S`.
 35          // The key is repeated as necessary to match the 256 iterations, ensuring the entire state array
 36          // is influenced by the key's data. This step is crucial for spreading the key's entropy throughout `S`.
 37          j = (j + S[i] + key[i % len]) % 256;
 38  
 39          // Swapping elements `S[i]` and `S[j]` further shuffles the state array.
 40          // This operation is critical for ensuring the state array's initial permutation
 41          // is well-mixed and heavily dependent on the key, laying the foundation for a secure keystream.
 42          swap(&S[i], &S[j]);
 43      }
 44  }
 45  
 46  /**
 47   * Pseudo-Random Generation Algorithm (PRGA)
 48   * 
 49   * The PRGA modifies the state array `S` further and generates a byte of the keystream at each iteration.
 50   * This keystream is then XORed with the plaintext to produce ciphertext or vice versa for decryption.
 51   * The security of the RC4 encryption relies on the complexity and unpredictability of the keystream,
 52   * which is generated based on the shuffled state array `S` produced by the KSA.
 53   *
 54   * @param S The shuffled state array from the KSA.
 55   * @param plaintext The input text (plaintext for encryption, ciphertext for decryption).
 56   * @param ciphertext The output text (ciphertext for encryption, decrypted plaintext for decryption).
 57   * @param len The length of the input text.
 58   */
 59  void PRGA(uint8_t S[256], uint8_t *plaintext, uint8_t *ciphertext, size_t len) {
 60      int i = 0, j = 0;
 61      for(size_t n = 0; n < len; n++) {
 62          i = (i + 1) % 256;
 63          j = (j + S[i]) % 256;
 64          swap(&S[i], &S[j]);
 65          uint8_t rnd = S[(S[i] + S[j]) % 256]; // Generate the next byte of the keystream
 66          ciphertext[n] = rnd ^ plaintext[n]; // XOR it with the plaintext
 67      }
 68  }
 69  
 70  /**
 71   * RC4 Encryption/Decryption Function
 72   * 
 73   * This function combines the KSA and PRGA to encrypt or decrypt data using the RC4 algorithm.
 74   * RC4 is a symmetric stream cipher, meaning the same algorithm and key are used for both encryption
 75   * and decryption. The security of RC4 lies in the complexity of its keystream, which is unique for each key.
 76   *
 77   * @param key The encryption key as a string.
 78   * @param plaintext The input text (plaintext for encryption, ciphertext for decryption).
 79   * @param ciphertext The output text (ciphertext for encryption, decrypted plaintext for decryption).
 80   * @param len The length of the input text.
 81   */
 82  void RC4(char *key, uint8_t *plaintext, uint8_t *ciphertext, size_t len) {
 83      uint8_t S[256]; // The state array, crucial for keystream generation
 84      KSA(key, S); // Initialize and shuffle the state array with the key
 85      PRGA(S, plaintext, ciphertext, len); // Generate the keystream and produce the output text
 86  }
 87  
 88  int main() {
 89      char *key = "Key"; // The encryption/decryption key
 90      uint8_t plaintext[] = "Plaintext"; // The plaintext to be encrypted
 91      size_t len = sizeof(plaintext) - 1; // Calculate the length of the plaintext
 92      uint8_t ciphertext[len]; // Array to hold the ciphertext
 93  
 94      // Encrypt the plaintext
 95      RC4(key, plaintext, ciphertext, len);
 96      printf("Ciphertext: ");
 97      for(size_t i = 0; i < len; i++)
 98          printf("%02hhX", ciphertext[i]); // Print each byte of ciphertext in hex
 99      printf("\n");
100  
101      // Decrypt the ciphertext (RC4 is symmetric, so the same function is used for decryption)
102      uint8_t decryptedtext[len]; // Array to hold the decrypted text
103      RC4(key, ciphertext, decryptedtext, len); // Decrypt the ciphertext
104      printf("Decrypted Text: ");
105      for(size_t i = 0; i < len; i++)
106          printf("%c", decryptedtext[i]); // Print the decrypted text
107      printf("\n");
108  
109      return 0;
110  }