Introducción
Hace un tiempo me topé con el pequeño algoritmo de encriptación ( TEA ) y desde entonces lo he recomendado cuando no se necesitaban propiedades especiales de seguridad criptográfica y se requería una auto implementación.
Ahora, queremos tomar literalmente el nombre * pequeño * algoritmo de cifrado y su tarea será implementar el algoritmo de cifrado más pequeño .
Especificación
Entrada
La entrada es una lista de 8 bytes (o su equivalente de idioma), este es el texto sin formato , y otra lista de 16 bytes (o su equivalente de idioma), esta es la clave .
Se permite la conversión de entrada de decimal, hexadecimal, octal o binario.
Se permite leer 1 entero de 64 bits, 2 de 32 bits o 4 de 16 bits como salida (opcionalmente como una lista) (para el texto sin formato, duplicar los números para la clave)
Salida
La salida es una lista de 8 bytes (o el equivalente de su idioma), este es el texto cifrado .
La conversión de salida a decimal, hexadecimal, octal o binario está permitida, pero no es obligatoria.
Se permite escribir 1 entero de 64 bits, 2 de 32 bits o 4 de 16 bits como salida (opcionalmente como una lista).
¿Qué hacer?
Su tarea es implementar la dirección de cifrado del pequeño algoritmo de cifrado ( TEA ), tenga en cuenta que XTEA y XXTEA son otros algoritmos.
Wikipedia tiene un ejemplo de código C y una lista de referencias a algunas implementaciones en otros idiomas, esta es la descripción original (PDF) .
Más formalmente:
Let k1, k2, k3, k4, v1, v2, sum be unsigned 32-bit integers.
(k1,k2,k3,k4) <- key input
(v1,v2) <- plaintext input
sum <- 0
repeat 32 times:
sum <- ( sum + 0x9e3779b9 ) mod 2^32
v0 <- ( v0 + ( ((v1 << 4) + k0) XOR (v1 + sum) XOR ((v1 >> 5) + k1) ) ) mod 2^32
v1 <- ( v1 + ( ((v0 << 4) + k2) XOR (v0 + sum) XOR ((v0 >> 5) + k3) ) ) mod 2^32
output <- (v0,v1)
where 0x9e3779b9 is a hexadecimal constant and
"<<" denotes logical left shift and ">>" denotes logical right shift.
Posibles casos de esquina
\0
es un carácter válido y no puede acortar su entrada ni su salida.
Se supone que la codificación entera es little-endian (por ejemplo, lo que probablemente ya tenga).
¿Quién gana?
Este es el código de golf por lo que gana la respuesta más corta en bytes.
Se aplican reglas estándar, por supuesto.
Casos de prueba
Los vectores de prueba se generaron usando el ejemplo de código C de Wikipedia.
Key: all zero (16x \0)
Plaintext -> Ciphertext (all values as two 32-bit hexadecimal words)
00000000 00000000 -> 41ea3a0a 94baa940
3778001e 2bf2226f -> 96269d3e 82680480
48da9c6a fbcbe120 -> 2cc31f2e 228ad143
9bf3ceb8 1e076ffd -> 4931fc15 22550a01
ac6dd615 9c593455 -> 392eabb4 505e0755
ebad4b59 7b962f3c -> b0dbe165 cfdba177
ca2d9099 a18d3188 -> d4641d84 a4bccce6
b495318a 23a1d131 -> 39f73ca0 bda2d96c
bd7ce8da b69267bf -> e80efb71 84336af3
235eaa32 c670cdcf -> 80e59ecd 6944f065
762f9c23 f767ea2c -> 3f370ca2 23def34c
Aquí hay algunos vectores de prueba autogenerados con claves distintas de cero:
format: ( 4x 32-bit word key , 2x 32-bit word plaintext ) -> ( 2x 32-bit word ciphertext )
(all in hexadecimal)
( 4300e123 e39877ae 7c4d7a3c 98335923 , a9afc671 79dcdb73 ) -> ( 5d357799 2ac30c80 )
( 4332fe8f 3a127ee4 a9ca9de9 dad404ad , d1fe145a c84694ee ) -> ( a70b1d53 e7a9c00e )
( 7f62ac9b 2a0771f4 647db7f8 62619859 , 618f1ac2 67c3e795 ) -> ( 0780b34d 2ca7d378 )
( 0462183a ce7edfc6 27abbd9a a634d96e , 887a585d a3f83ef2 ) -> ( d246366c 81b87462 )
( 34c7b65d 78aa9068 599d1582 c42b7e33 , 4e81fa1b 3d22ecd8 ) -> ( 9d5ecc3b 947fa620 )
( f36c977a 0606b8a0 9e3fe947 6e46237b , 5d8e0fbe 2d3b259a ) -> ( f974c6b3 67e2decf )
( cd4b3820 b2f1e5a2 485dc7b3 843690d0 , 48db41bb 5ad77d7a ) -> ( b4add44a 0c401e70 )
( ee2744ac ef5f53ec 7dab871d d58b3f70 , 70c94e92 802f6c66 ) -> ( 61e14e3f 89408981 )
( 58fda015 c4ce0afb 49c71f9c 7e0a16f0 , 6ecdfbfa a705a912 ) -> ( 8c2a9f0c 2f56c18e )
( 87132255 41623986 bcc3fb61 7e6142ce , 9d0eff09 55ac6631 ) -> ( 8919ea55 c7d430c6 )
fuente
Respuestas:
JavaScript (ES6),
122118114113 bytesNota: Utiliza aritmética little-endian. Acepta y devuelve valores enteros de 32 bits sin signo. Editar: Guardado 4 bytes usando la multiplicación en lugar del desplazamiento a la izquierda. Se guardaron 4 bytes al probar
s
, evitando así una variable de bucle separada. Se guardó 1 byte moviendo la+=
s dentro delfor
.fuente
{return}
coneval('')
no me ahorra bytesRuby,
114113106 bytesDebido a que Ruby no tiene aritmética de 32 bits, las operaciones de mod adicionales causaron que casi se vincule con Javascript de todos modos a pesar de las otras operaciones de ahorro de bytes que Ruby ha ...
Pruébalo en línea!
fuente
C, 116 bytes
Toma texto plano como v y w ; clave como k , l , m , y n ; y almacena el texto cifrado en v y w .
Pruébalo en Ideone .
fuente
J, 149 bytes
¡Hurra! explícito (Boo!) J! Creo que hay una manera de hacerlo tácitamente, pero probablemente se volvería ilegible.
Uso
Toma las claves como cuatro enteros de 32 bits en el LHS y el texto sin formato como dos enteros de 32 bits en el RHS. El prefijo
16b
es equivalente a0x
en otros idiomas y representa un valor hexadecimal. El incorporadohfd
formatea la salida en una cadena hexadecimal para facilitar la prueba.fuente