En criptografía , el bloque TEA corregido (a menudo denominado XXTEA ) es un cifrado de bloque diseñado para corregir debilidades en el bloque TEA original . [2] [3]
XXTEA es vulnerable a un ataque de texto simple elegido que requiere 259 consultas y un trabajo insignificante. Vea el criptoanálisis a continuación.
Los diseñadores del algoritmo fueron Roger Needham y David Wheeler , del Cambridge Computer Laboratory , y el mismo fue presentado en un informe técnico inédito [ aclaración necesaria ] en octubre de 1998 (Wheeler y Needham, 1998). No está sujeto a ninguna patente .
Formalmente hablando, XXTEA es un cifrado de bloque UFN ( red Feistel no balanceada) heterogéneo, consistente, incompleto y con un gran uso de fuentes . XXTEA opera en bloques de longitud variable que tienen un tamaño arbitrario de múltiplo de 32 bits (mínimo de 64 bits). El número de ciclos completos depende del tamaño del bloque, pero hay al menos seis (aumentando a 32 para tamaños de bloque pequeños). El Block TEA original aplica la función de redondeo XTEA a cada palabra del bloque y la combina de forma aditiva con su vecino más a la izquierda. La lenta tasa de difusión del proceso de descifrado se aprovechó inmediatamente para descifrar el cifrado. El Block TEA corregido utiliza una función de redondeo más compleja que hace uso de ambos vecinos inmediatos para procesar cada palabra del bloque.
Es probable que XXTEA sea más eficiente que XTEA para mensajes más largos. [ cita requerida ]
Needham & Wheeler hacen los siguientes comentarios sobre el uso de Block TEA:
Para facilitar su uso y seguridad general, se prefiere la versión de bloque grande cuando sea aplicable por las siguientes razones.
- Un solo cambio de bit cambiará aproximadamente la mitad de los bits de todo el bloque, sin dejar ningún lugar donde comiencen los cambios.
- No hay elección de modo involucrado.
- Incluso si se emplea el uso correcto de cambiar siempre los datos enviados (posiblemente mediante un número de mensaje), sólo los mensajes idénticos dan el mismo resultado y la fuga de información es mínima.
- Siempre debe comprobarse el número de mensaje, ya que esta redundancia es la comprobación para evitar que se acepte un mensaje aleatorio.
- Los ataques de cortar y unir no parecen ser posibles.
- Si no es aceptable tener mensajes muy largos, se pueden dividir en fragmentos de, digamos, 60 palabras y encadenarlos de forma análoga a los métodos utilizados para DES .
Sin embargo, debido a la naturaleza incompleta de la función round, se pueden encontrar dos textos cifrados grandes de 53 o más palabras de 32 bits idénticas en todas las palabras excepto 12 mediante una simple búsqueda de colisión por fuerza bruta que requiere 2 96−N de memoria, 2 N de tiempo y 2 N +2 96−N de textos simples elegidos, en otras palabras con una complejidad total de tiempo*memoria de 2 96 , que en realidad es 2 wordsize*fullcycles/2 para cualquier cifrado de este tipo. Actualmente se desconoce si tales colisiones parciales representan alguna amenaza para la seguridad del cifrado. Ocho ciclos completos elevarían el nivel de complejidad de dicha búsqueda de colisiones por encima de los ataques de fuerza bruta paralelos. [ cita requerida ]
El tamaño inusualmente pequeño del algoritmo XXTEA lo convertiría en una opción viable en situaciones donde hay restricciones extremas, por ejemplo, sistemas de hardware heredados (quizás integrados) donde la cantidad de RAM disponible es mínima, o alternativamente computadoras de placa única como Raspberry Pi , Banana Pi o Arduino .
Un ataque publicado en 2010 por E. Yarrkov presenta un ataque de texto simple elegido contra XXTEA de ronda completa con bloque ancho, que requiere 2 59 consultas para un tamaño de bloque de 212 bytes o más y un trabajo insignificante. Se basa en criptoanálisis diferencial . [1]
Para cifrar "212 bytes o más" el algoritmo realiza sólo 6 rondas y patrones de bits cuidadosamente elegidos permiten detectar y analizar el efecto avalancha.
La formulación original del algoritmo TEA de bloque corregido, publicada por David Wheeler y Roger Needham, es la siguiente: [4]
#define DELTA 0x9e3779b9 #define MX ((z>>5^y<<2) + (y>>3^z<<4) ^ (suma^y) + (k[p&3^e]^z)) long btea ( long * v , long n , long * k ) { unsigned long z = v [ n -1 ], y = v [ 0 ], suma = 0 , e , DELTA = 0x9e3779b9 ; long p , q ; if ( n > 1 ) { /* Parte de codificación */ q = 6 + 52 / n ; while ( q -- > 0 ) { suma += DELTA ; e = ( suma >> 2 ) & 3 ; para ( p = 0 ; p < n -1 ; p ++ ) y = v [ p + 1 ], z = v [ p ] += MX ; y = v [ 0 ]; z = v [ n -1 ] += MX ; } devuelve 0 ; } de lo contrario si ( n < -1 ) { /* Parte de decodificación */ n = - n ; q = 6 + 52 / n ; suma = q * DELTA ; mientras ( suma != 0 ) { e = ( suma >> 2 ) & 3 ; para ( p = n -1 ; p > 0 ; p -- ) z = v [ p -1 ], y = v [ p ] -= MX ; z = v [ n -1 ]; y = v [ 0 ] -= MX ; suma -= DELTA ; } devuelve 0 ; } devuelve 1 ; }
Según Needham y Wheeler:
BTEA codificará o decodificará n palabras como un solo bloque donde n > 1
- v es el vector de datos de la palabra n
- k es la clave de 4 palabras
- n es negativo para decodificar
- Si n es cero, el resultado es 1 y no se realiza ninguna codificación ni decodificación; de lo contrario, el resultado es cero.
- asume una codificación y decodificación de 32 bits 'long' y el mismo endian
Tenga en cuenta que la inicialización de z es un comportamiento indefinido para n < 1, lo que puede provocar un error de segmentación u otro comportamiento no deseado; sería mejor colocarlo dentro del bloque "Parte de codificación". Además, en la definición de MX, algunos programadores preferirían usar corchetes para aclarar la precedencia de los operadores.
Una versión aclarada que incluye dichas mejoras es la siguiente:
#include <stdint.h> #define DELTA 0x9e3779b9 #define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((suma^y) + (clave[(p&3)^e] ^ z))) void btea ( uint32_t * v , int n , uint32_t const clave [ 4 ]) { uint32_t y , z , suma ; unsigned p , rondas , e ; if ( n > 1 ) { /* Parte de codificación */ rondas = 6 + 52 / n ; suma = 0 ; z = v [ n -1 ]; do { suma += DELTA ; e = ( suma >> 2 ) & 3 ; para ( p = 0 ; p < n -1 ; p ++ ) { y = v [ p + 1 ]; z = v [ p ] += MX ; } y = v [ 0 ]; z = v [ n -1 ] += MX ; } mientras ( -- rondas ); } de lo contrario si ( n < -1 ) { /* Parte de decodificación */ n = - n ; rondas = 6 + 52 / n ; suma = rondas * DELTA ; y = v [ 0 ]; hacer { e = ( suma >> 2 ) y 3 ; para ( p = n -1 ; p > 0 ; p -- ) { z = v [ p -1 ]; y = v [ p ] -= MX ; } z = v [ n -1 ]; y = v [ 0 ] -= MX ; suma -= DELTA ; } mientras ( -- rondas ); } }