Zeit für etwas TEE!

8

Einführung

Vor einiger Zeit bin ich auf den winzigen Verschlüsselungsalgorithmus ( TEA ) gestoßen, und seitdem habe ich ihn empfohlen, wenn spezielle kryptografische Sicherheitseigenschaften nicht benötigt wurden und eine Selbstimplementierung erforderlich war.
Heute wollen wir den Namen * tiny * Verschlüsselungsalgorithmus wörtlich nehmen und Ihre Aufgabe wird es sein, den kleinsten Verschlüsselungsalgorithmus zu implementieren !

Spezifikation

Eingang

Die Eingabe ist eine Liste von 8 Bytes (oder Ihrem Sprachäquivalent), dies ist der Klartext , und eine andere Liste von 16 Bytes (oder Ihr Sprachäquivalent) ist dies der Schlüssel .
Die Eingabekonvertierung von Dezimal, Hexadezimal, Oktal oder Binär ist zulässig.
Das Lesen von 1 64-Bit-, 2 32-Bit- oder 4 16-Bit-Ganzzahlen als Ausgabe (optional als Liste) ist zulässig (für den Klartext verdoppeln Sie die Zahlen für den Schlüssel).

Ausgabe

Die Ausgabe ist eine Liste von 8 Bytes (oder Ihrem Sprachäquivalent), dies ist der Chiffretext .
Die Ausgabekonvertierung in Dezimal, Hexadezimal, Oktal oder Binär ist zulässig, jedoch nicht obligatorisch.
Das Schreiben von 1 64-Bit-, 2 32-Bit- oder 4 16-Bit-Ganzzahlen als Ausgabe (optional als Liste) ist zulässig.

Was ist zu tun?

Ihre Aufgabe ist es, die Verschlüsselungsrichtung des winzigen Verschlüsselungsalgorithmus ( TEA ) zu implementieren. Beachten Sie, dass XTEA und XXTEA andere Algorithmen sind.
Wikipedia hat ein C-Code-Beispiel und eine Liste mit Verweisen auf einige Implementierungen in anderen Sprachen. Dies ist die Originalbeschreibung (PDF) .

Formeller:

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.

Mögliche Eckfälle

\0ist ein gültiges Zeichen und Sie dürfen weder Ihre Eingabe noch Ihre Ausgabe verkürzen.
Die Ganzzahlcodierung wird als Little-Endian-Codierung angenommen (z. B. das, was Sie wahrscheinlich bereits haben).

Wer gewinnt?

Dies ist Code-Golf, also gewinnt die kürzeste Antwort in Bytes!
Standardregeln gelten natürlich.

Testfälle

Testvektoren wurden unter Verwendung des Wikipedia C-Codebeispiels erzeugt.

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

Hier sind einige selbst generierte Testvektoren mit Schlüsseln ungleich Null:

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
quelle
1
Als ich den Wikipedia C-Code mit einem Nullschlüssel und Klartext ausprobierte, bekam ich die zweite Zeile Ihres Klartextes als meinen Chiffretext ...
Neil
Nun, die ersten beiden tun es jetzt; Ich bin zu faul, um den Rest zu versuchen.
Neil
@Neil, das ist das Schöne an Crypto: Die Chancen stehen gut, dass wenn ein trivialer (0-basierter) und ein nichttrivialer Testvektor bestanden werden, alle Testvektoren bestanden werden :)
SEJPM
2
Ich schlage vor, Sie fügen einige Testfälle mit einem Schlüssel ungleich Null hinzu.
Dennis
@ Tennis diese können jetzt am Ende der Frage gefunden werden :)
SEJPM

Antworten:

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>

Hinweis: Verwendet Little-Endian-Arithmetik. Akzeptiert vorzeichenlose 32-Bit-Ganzzahlwerte und gibt sie zurück. Bearbeiten: 4 Bytes durch Multiplikation anstelle von Linksverschiebung gespeichert. Durch Testen auf wurden 4 Bytes gespeichert, swodurch eine separate Schleifenvariable vermieden wurde. 1 Byte durch Verschieben des +=s innerhalb des gespeichert for.

Neil
quelle
Warum nicht eval mit seiner impliziten Rückgabe anstelle von return verwenden?
Downgoat
Das Ersetzen {return}durch eval('')spart mir keine Bytes
Neil
Oh ok. Dachte, es spart ein paar Bytes :(
Downgoat
4

Ruby, 114 113 106 Bytes

Da Ruby keine 32-Bit-Arithmetik hat, haben die zusätzlichen Mod-Operationen dazu geführt, dass es trotz der anderen byte-sparenden Operationen, die Ruby hat, sowieso fast mit Javascript verknüpft ist ...

  • (-1 Byte vom zusätzlichen Semikolon)
  • (-7 Bytes vom Ausschneiden unnötiger Mod-Operationen und Verschieben von Sachen)

Probieren Sie es online aus!

->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]}
Wert Tinte
quelle
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;}

Nimmt Klartext als v und w ; Schlüssel als k , l , m und n ; und speichert den Chiffretext in v und w .

Testen Sie es auf Ideone .

Dennis
quelle
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
)

Yay! explizit (Boo!) J! Ich denke, es gibt einen Weg, dies stillschweigend zu tun, aber es würde wahrscheinlich unlesbar werden.

Verwendungszweck

Nimmt die Schlüssel als vier 32-Bit-Ganzzahlen auf der linken Seite und den Klartext als zwei 32-Bit-Ganzzahlen auf der rechten Seite. Das Präfix 16bentspricht 0xanderen Sprachen und stellt einen Hex-Wert dar. Das integrierte hfdFormat formatiert die Ausgabe in eine Hex-Zeichenfolge, um das Testen zu vereinfachen.

    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
Meilen
quelle