Hay varias maneras de construir buenas S-boxes para cifrados, así como varias maneras de medirlas. Algunos diseñadores usan una aproximación matemática rigurosa al usar funciones curvilíneas (o relacionadas) para crear S-boxes que puedan ser probadas como resistentes contra algunos ataques particulares. Otros diseñadores usan aproximaciones heurísticas, lo cual conduciría a que las s-boxes sean más difíciles de manejar en pruebas matemáticas, pero pueden tener beneficios adicionales (como varias opciones diferentes de implementación).
La S-Box puede ser la única parte no lineal del cifrado, este es el caso del cifrado en bloque DES, y de esta manera debe ser considerado como la parte más importante del algoritmo. De hecho, muchos consideran a las S-boxes DES tan buenas que las usan en sus propios diseños.
Las Tablas prefijadas se usan en algunos algoritmo mientras que otros cifradores usan S-Boxes dependientes de la clave, como en Blowfish y Twofish.
S-Box 6x4 bits
La imagen nos muestra una S-Box de 6x4 bits:En donde nuestra entrada es de 6 bits y nos devolverá una salida de 4bits, de los cuales para la entrada esta dividido asi:
- 4 bits de entrada internos
- 2 bits de entrada externos
Por ejemplo si tenemos una entrada de "011011", los bits externos serian "011011" (01) mientras que los bits internos serian "011011" (1101).
Implementación
Bueno para la implementación he escrito en una tabla los valores que tendrá nuestra S-Box de 6x4, tomaremos como parámetro una cadena de entrada, la cual evaluamos bit a bit, cada 6 bits tomaremos como entrada y almacenaremos la salida en la variable temporal, pues al solo tener 4 bits inicialmente, tienes que tener los siguientes 4 bits para completar los 8 bits (1 byte).
Pueden ver el codigo aqui.
Compilamos y ejecutamos:
$ gcc S-Box.c -o sbox
$ ./sbox texto1234
Podemos comprobar que los valores que imprime, si los ubicamos en la tabla, son los mismos al resultado mostrado, van en el siguiente orden:
El código prácticamente he tratado de comentar cada parte para que sea mas comprensible:
Pueden ver el codigo aqui.
Compilamos y ejecutamos:
$ gcc S-Box.c -o sbox
$ ./sbox texto1234
Podemos comprobar que los valores que imprime, si los ubicamos en la tabla, son los mismos al resultado mostrado, van en el siguiente orden:
Bits internos (4 bit) - bits externos (2 bits) - valor en la tabla (4 bits de salida) - valor en la tabla desplazado 4 bits a la izquierda
*Nota: la salida normalmente son caracteres que la consola no puede mostrarnos, pero haciendo un recorrido por la cadena de salida, podemos ver que esta todo normal.
*Nota 2: Como mencioné anteriormente necesitamos 8 bits, por lo cual los primeros 4 bits desplazamos 4 bits a la izquierda y le sumamos los siguientes 4 bits (en el ejemplo el primer valor es 8 y le suma el seguido que es 1, por ello el resultado es 81 en hexadecimal).
*Nota 2: Como mencioné anteriormente necesitamos 8 bits, por lo cual los primeros 4 bits desplazamos 4 bits a la izquierda y le sumamos los siguientes 4 bits (en el ejemplo el primer valor es 8 y le suma el seguido que es 1, por ello el resultado es 81 en hexadecimal).
El código prácticamente he tratado de comentar cada parte para que sea mas comprensible:
/** Autor: PaoloRamirez Tema: S-Box o Cajas-S (ejemplo S-Box de 6x4bits) Link: https://www.facebook.com/PaoloProgrammer/ **/ #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char **argv) { if(argc!=2) { perror("Insertar 1 parametro (p1:texto)"); exit(0); } int len_texto,len_resultado; len_texto=strlen(argv[1]); len_resultado=len_texto*2/3; /** Texto inicial que ingresa al S-Box **/ //Tamaño de cadena = len+fincadena \0 char texto[len_texto+1]; char resultado[len_resultado+1]; //Format memset(texto,0,sizeof(texto)); memset(resultado,0,sizeof(resultado)); //Copiar a variable strcpy(texto,argv[1]); printf("Entrada: %s\n", texto); /** Tabla prefijada 6x4 bits **/ char tabla[4][16]; //Externo x Interno tabla[0][0]=2;tabla[0][1]=12;tabla[0][2]=4;tabla[0][3]=1; tabla[0][4]=7;tabla[0][5]=10;tabla[0][6]=11;tabla[0][7]=6; tabla[0][8]=8;tabla[0][9]=5;tabla[0][10]=3;tabla[0][11]=15; tabla[0][12]=13;tabla[0][13]=0;tabla[0][14]=14;tabla[0][15]=9; tabla[1][0]=14;tabla[1][1]=11;tabla[1][2]=2;tabla[1][3]=12; tabla[1][4]=4;tabla[1][5]=7;tabla[1][6]=13;tabla[1][7]=1; tabla[1][8]=5;tabla[1][9]=0;tabla[1][10]=15;tabla[1][11]=12; tabla[1][12]=3;tabla[1][13]=9;tabla[1][14]=8;tabla[1][15]=6; tabla[2][0]=4;tabla[2][1]=2;tabla[2][2]=1;tabla[2][3]=11; tabla[2][4]=12;tabla[2][5]=13;tabla[2][6]=7;tabla[2][7]=8; tabla[2][8]=15;tabla[2][9]=9;tabla[2][10]=12;tabla[2][11]=5; tabla[2][12]=6;tabla[2][13]=3;tabla[2][14]=0;tabla[2][15]=14; tabla[3][0]=11;tabla[3][1]=8;tabla[3][2]=12;tabla[3][3]=7; tabla[3][4]=1;tabla[3][5]=14;tabla[3][6]=2;tabla[3][7]=13; tabla[3][8]=6;tabla[3][9]=15;tabla[3][10]=0;tabla[3][11]=9; tabla[3][12]=12;tabla[3][13]=4;tabla[3][14]=5;tabla[3][15]=3; /** Entrada[6] - Salida[4] **/ // variables "interno" y "externo" para acceder a la tabla prefijada int i,j,interno=0,externo=0; //variable temporal para saber el binario al aplicar un & int xbit=0x80; //suma interna varia entre 0 y 15 (0x8 para iniciar sabiendo el bit en la posicion 4) int suma_int=0x8; //suma externa varia entre 0 y 3 (0x2 para iniciar sabiendo el bit en la posicion 2) int suma_ext=0x2; int cont=0; int ind_resultado=0; //indice de la variable resultado (que sera el resultado final) int temp_resultado; int agregar=0; for (i = 0; i < len_texto; i++) { for (j = 0; j < 8; j++) { /** Obtener valores de "interno" y "externo" **/ //Aplicar & para saber si existe el bit en esa posicion //donde xbit tiene como valor la posicion a evaluar if(texto[i] & xbit) { //Sumarle el valor de "suma_x" en caso exista el bit en esa posicion if(cont==0 || cont==5) { externo+=suma_ext; } else { interno+=suma_int; } } //Hacer desplazamiento a la derecha >> xbit=xbit>>1; //Bits 0 y 5 para externo if(cont==0) { suma_ext=suma_ext>>1;} //Bits 1,2,3,4 para interno else { suma_int=suma_int>>1; } //Control de 6 bits de entrada if (cont==5) { //Obtener primeros 4 bits if (agregar==0) { temp_resultado=tabla[externo][interno]<<4; agregar++; } //Obtener los siguientes 4 bits y agregar al resultado de salida else { temp_resultado+=tabla[externo][interno]; resultado[ind_resultado]=temp_resultado; agregar=0; ind_resultado++; } //Test para mostrar valores de acceso a la tabla printf("Interno:%x - Externo:%x - Valor-Tabla:%x - %x\n, interno,externo,tabla[externo][interno],temp_resultado); //Inicializar variables cada 6 bits evaluados cont=0; suma_int=0x8; suma_ext=0x2; interno=0; externo=0; } else { cont++; } } //reiniciar temporal a bit 8: 0b1000 0000 -> 0x80 -> 128 xbit=0x80; } printf("\nSalida: %s\n",resultado); }
*Nota: Tener en cuenta que según el tamaño de nuestra cadena, sera el tamaño de la salida, al ser un S-Box de 6x4, frecuentemente utilizan un S-Box de NxN.
No hay comentarios.:
Publicar un comentario