clinuxencryptionrc4-cipher

RC4 Algo with drop


How can I implement this fuction in C

void code_RC4(byte *Key, int key_size, byte *Message, int msg_size, int n)

The argument n will be the number of initial bytes not used during generation. (In other words, we wait for n generated bytes before starting to encrypt.)

TEST

Key Msg N Cipher
Key Plaintext 0 BBF316E8D940AF0AD3
lorem ipsum 123 4FC201FAFF
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef unsigned char byte;

void swap(byte *a, byte *b);
void code_RC4(byte *Cle, int taille_cle, byte *Message, int taille_message, int n);

int main(int argc, char *argv[])
{
    if (argc != 4) {
        printf("RC4-drop[n], utilisation : %s cle message n\n", argv[0]);
        exit(-1);
    }
    code_RC4((byte*)argv[1], strlen(argv[1]), (byte*)argv[2], strlen(argv[2]), atoi(argv[3]));
    puts("");
    return 0;
}






void swap(byte *a, byte *b){
    byte temp = *a;
    *a = *b;
    *b = temp;
}


void code_RC4(byte *Cle, int taille_cle, byte *Message, int taille_message, int n)
 {
    /* KSA: Key Scheduling Algorithm */
    /* L'état est constitué des variables P (tableau de 256 octets), index_i et index_j (entiers). */
    byte P[256];
    byte *K = (byte *) malloc(taille_message);
    byte *OA = (byte *) malloc(taille_message);
    int i, j;

    // Initialisation du tableau S
    for (i = 0; i < 256; i++) {
        P[i] = i;
    }

    // Mélange initial des éléments de S
    j = 0;
    for (int i = 0; i < 256; i++) {
        j = (j + P[i] + Cle[i % taille_cle]) % 256;
         swap(&P[i], &P[j]);
    }

    // Génération des n premiers octets
    i = 0;
    j = 0;
    for (int t =0 ; t < taille_message; t++) {
        i = (i + 1) % 256;
        j = (j + P[i]) % 256;
        swap(&P[i], &P[j]);
        OA[t] = P[(P[i] + P[j]) % 256];
    }

    // Chiffrement du message avec RC4-drop
    i = 0;
    j = 0;
    for (int t = 0; t < taille_message; t++) {
        K[t] = Message[t]^ OA[t];
    }

    // Affichage du résultat en hexadécimal
    for (i = 0; i < taille_message; i++) {
        printf("%02X", K[i]);
    }
}

the first test is ok but the second return A0E922A001 instead of 4FC201FAFF


Solution

  • You want to implement a modified version of the RC4 algorithm called RC4-drop[n]. In order to achieve this, you will need to modify your code_RC4 function so it utilizes a parameter n. Here is the correct implementation of the RC4-drop[n] based on your code:

    void code_RC4(byte *Cle, int taille_cle, byte *Message, int taille_message, int n)
     {
        /* KSA: Key Scheduling Algorithm */
        /* L'état est constitué des variables P (tableau de 256 octets), index_i et index_j (entiers). */
        byte P[256];
        int i, j;
    
        // Initialisation du tableau S
        for (i = 0; i < 256; i++) {
            P[i] = i;
        }
    
        // Mélange initial des éléments de S
        j = 0;
        for (int i = 0; i < 256; i++) {
            j = (j + P[i] + Cle[i % taille_cle]) % 256;
             swap(&P[i], &P[j]);
        }
    
        i = 0;
        j = 0;
        for (int t = 0 ; t < taille_message + n; t++) {
            i = (i + 1) % 256;
            j = (j + P[i]) % 256;
            swap(&P[i], &P[j]);
            // Discard the first n bytes of the keystream.
            if (t >= n)
            {
                printf("%02X", Message[t-n] ^ P[(P[i] + P[j]) % 256]);
            }
        }
    }
    

    I've tested this code with both rows from your table and I have gotten the correct values, to be more specific, for a message "ipsum" and a key "lorem" after dropping 123 bytes you will get 4FC201FAFF.