pengantar
Beberapa waktu yang lalu saya menemukan algoritma enkripsi kecil ( TEA ) dan sejak itu saya merekomendasikannya setiap kali sifat keamanan kriptografi khusus tidak diperlukan dan implementasi mandiri adalah persyaratan.
Sekarang hari ini, kami ingin menggunakan algoritma enkripsi nama * tiny * secara harfiah dan tugas Anda adalah mengimplementasikan algoritma enkripsi terkecil !
Spesifikasi
Memasukkan
Input adalah daftar 8 byte (atau setara bahasa Anda), ini adalah plaintext , dan daftar 16 byte (atau setara bahasa Anda), inilah kuncinya .
Konversi input dari desimal, heksadesimal, oktal atau biner diperbolehkan.
Membaca 1 bilangan bulat 64-bit, 2 32-bit atau 4 16-bit sebagai output (opsional sebagai daftar) diperbolehkan (untuk plaintext, gandakan angka untuk kunci)
Keluaran
Outputnya adalah daftar 8 byte (atau setara bahasa Anda), ini adalah ciphertext .
Konversi keluaran ke desimal, heksadesimal, oktal atau biner diperbolehkan, tetapi tidak wajib.
Penulisan 1 bilangan bulat 64-bit, 2 32-bit atau 4 16-bit sebagai output (opsional sebagai daftar) diperbolehkan.
Apa yang harus dilakukan?
Tugas Anda adalah mengimplementasikan arah enkripsi dari algoritma enkripsi kecil ( TEA ), perhatikan XTEA dan XXTEA adalah algoritma lainnya.
Wikipedia memiliki contoh kode-C dan daftar referensi untuk beberapa implementasi dalam bahasa lain, ini adalah deskripsi asli (PDF) .
Lebih formal:
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.
Kasing sudut potensial
\0
adalah karakter yang valid dan Anda tidak dapat mempersingkat input atau output Anda.
Pengkodean integer diasumsikan sebagai little-endian (mis. Apa yang mungkin sudah Anda miliki).
Yang menang?
Ini adalah kode-golf sehingga jawaban tersingkat dalam byte menang!
Aturan standar berlaku tentu saja.
Kasus uji
Vektor uji dibuat menggunakan contoh kode Wikipedia C.
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
Berikut adalah beberapa vektor uji yang dibuat sendiri dengan kunci bukan nol:
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 )
sumber
Jawaban:
JavaScript (ES6),
122118114113 byteCatatan: Menggunakan aritmatika little-endian. Menerima dan mengembalikan nilai integer 32-bit yang tidak ditandatangani. Sunting: Disimpan 4 byte dengan menggunakan perkalian alih-alih shift kiri. Disimpan 4 byte dengan menguji
s
sehingga menghindari variabel loop terpisah. Disimpan 1 byte dengan memindahkan+=
s di dalamfor
.sumber
{return}
denganeval('')
tidak menghemat byte apa punRuby,
114113106 byteKarena Ruby tidak memiliki aritmatika 32-bit, operasi mod tambahan menyebabkannya hampir menyatu dengan Javascript meskipun ada operasi penghematan byte lain yang dimiliki Ruby ...
Cobalah online!
sumber
C, 116 byte
Mengambil plaintext sebagai v dan w ; kunci sebagai k , l , m , dan n ; dan menyimpan ciphertext di v dan w .
Uji di Ideone .
sumber
J, 149 byte
Yay! eksplisit (Boo!) J! Saya pikir ada cara untuk melakukan ini secara diam-diam, tetapi mungkin itu akan menjadi tidak dapat dibaca.
Pemakaian
Mengambil kunci sebagai empat bilangan bulat 32-bit pada LHS dan plaintext sebagai dua bilangan bulat 32-bit pada RHS. Awalan
16b
setara dengan0x
dalam bahasa lain dan mewakili nilai hex. Builtinhfd
memformat output menjadi string hex untuk kemudahan dalam pengujian.sumber