¡Hora de un poco de té!

8

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

\0es 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 )
SEJPM
fuente
1
Cuando probé el código C de Wikipedia, usando una tecla cero y texto sin formato, obtuve la segunda fila de su texto sin formato como texto cifrado ...
Neil
Bueno, los dos primeros lo hacen ahora; Sin embargo, soy demasiado vago para probar el resto.
Neil
@Neil, eso es lo bueno de las criptomonedas: las posibilidades son altas, que si un pase de prueba trivial (basado en 0) y no trivial, todos los vectores de prueba pasarán :)
SEJPM
2
Le sugiero que agregue algunos casos de prueba con una clave distinta de cero.
Dennis
@ Dennis esos ahora se pueden encontrar al final de la pregunta :)
SEJPM

Respuestas:

5

JavaScript (ES6), 122 118 114 113 bytes

f=
(v,w,k,l,m,n)=>{for(s=0;s<84e9;v+=w*16+k^w+s^(w>>>5)+l,w+=v*16+m^v+s^(v>>>5)+n)s+=0x9e3779b9;return[v>>>0,w>>>0]}
;
<div oninput="[r0.value,r1.value]=f(...[v0,v1,k0,k1,k2,k3].map(i=>parseInt(i.value,16))).map(i=>(i+(1<<30)*4).toString(16).slice(1))">
Plain 0: <input id=v0><br>
Plain 1: <input id=v1><br>
Key 0: <input id=k0><br>
Key 1: <input id=k1><br>
Key 2: <input id=k2><br>
Key 3: <input id=k3><br>
</div>
Cipher 0: <input id=r0 readonly><br>
Cipher 1: <input id=r1 readonly><br>

Nota: 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 del for.

Neil
fuente
¿Por qué no usar eval con su retorno implícito en lugar de return?
Downgoat
Reemplazar {return}con eval('')no me ahorra bytes
Neil
Ah, vale. Pensé que ahorraría un par de bytes :(
Downgoat
4

Ruby, 114 113 106 bytes

Debido 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 ...

  • (-1 byte de punto y coma extra)
  • (-7 bytes de recortar operaciones de mod innecesarias y cambiar cosas)

Pruébalo en línea!

->v,w,a,b,c,d{s=0
32.times{s+=0x9e3779b9;v+=w*16+a^w+s^w/32+b;v%=m=2**32;w+=v*16+c^v+s^v/32+d;w%=m}
[v,w]}
Tinta de valor
fuente
2

C, 116 bytes

T(v,w,k,l,m,n,s)unsigned*v,*w;{for(s=0;s+957401312;*v+=*w*16+k^*w+s^*w/32+l,*w+=*v*16+m^*v+s^*v/32+n)s+=2654435769;}

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 .

Dennis
fuente
2

J, 149 bytes

4 :0
'u v'=.y
s=.0
m=.2x^32
for.i.32
do.s=.m|s+2654435769
u=.m|u+(22 b.)/(s+v),(2{.x)+4 _5(33 b.)v
v=.m|v+(22 b.)/(s+u),(2}.x)+4 _5(33 b.)u
end.u,v
)

¡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 16bes equivalente a 0xen otros idiomas y representa un valor hexadecimal. El incorporado hfdformatea la salida en una cadena hexadecimal para facilitar la prueba.

    f =: 4 :0
'u v'=.y
s=.0
m=.2x^32
for.i.32
do.s=.m|s+2654435769
u=.m|u+(22 b.)/(s+v),(2{.x)+4 _5(33 b.)v
v=.m|v+(22 b.)/(s+u),(2}.x)+4 _5(33 b.)u
end.u,v
)
   hfd 0 0 0 0 f 0 0
41ea3a0a
94baa940
   hfd 0 0 0 0 f 16b3778001e 16b2bf2226f
96269d3e
82680480
   hfd 16b4300e123 16be39877ae 16b7c4d7a3c 16b98335923 f 16ba9afc671 16b79dcdb73 
5d357799
2ac30c80
millas
fuente