S-box Rijndael adalah operasi yang sering digunakan di AES enkripsi dan dekripsi . Ini biasanya diimplementasikan sebagai tabel pencarian 256-byte. Itu cepat, tetapi berarti Anda perlu menghitung tabel pencarian 256-byte dalam kode Anda. Saya yakin seseorang dalam kerumunan ini bisa melakukannya dengan kode lebih sedikit, mengingat struktur matematika yang mendasarinya.
Tulis fungsi dalam bahasa favorit Anda yang mengimplementasikan S-box Rijndael. Kode terpendek menang.
code-golf
math
cryptography
Keith Randall
sumber
sumber
Jawaban:
Ruby, 161 karakter
Untuk memeriksa output, Anda dapat menggunakan kode berikut untuk mencetaknya dalam bentuk tabel:
sumber
GolfScript, 60 karakter
Kode ini mendefinisikan fungsi bernama
S
yang mengambil dalam byte dan menerapkan Rijndael S-box untuk itu. (Ini juga menggunakan fungsi pembantu internal bernamar
untuk menyimpan beberapa karakter.)Implementasi ini menggunakan tabel logaritma untuk menghitung invers GF (2 8 ), seperti yang disarankan oleh Thomas Pornin . Untuk menyimpan beberapa karakter, seluruh tabel logaritma dihitung ulang untuk setiap byte input; Meski begitu, dan meskipun GolfScript menjadi bahasa yang sangat lambat secara umum, kode ini hanya membutuhkan sekitar 10 ms untuk memproses byte pada laptop lama saya. Pra-perhitungan tabel logaritma (as
L
) mempercepatnya hingga sekitar 0,5 ms per byte, dengan biaya sederhana dari tiga karakter lagi:Untuk kenyamanan, berikut ini adalah test harness sederhana yang memanggil fungsi
S
, sebagaimana didefinisikan di atas, untuk menghitung dan mencetak seluruh S-box dalam hex seperti di Wikipedia :Coba kode ini secara online.
(Demo online menghitung ulang tabel logaritma untuk menghindari mengambil terlalu banyak waktu. Meski begitu, situs GolfScript online kadang-kadang secara acak waktu habis; ini adalah masalah yang diketahui dengan situs, dan memuat ulang biasanya memperbaikinya.)
Penjelasan:
Mari kita mulai dengan perhitungan tabel logaritma, dan secara khusus dengan fungsi helper
r
:Fungsi ini mengambil dua input pada stack: satu byte dan bitmask reduksi (sebuah konstanta antara 256 dan 511). Ini menggandakan byte input, mengalikan salinan dengan 2 dan, jika hasilnya melebihi 255, XOR dengan bitmask untuk mengembalikannya di bawah 256.
Di dalam kode penghasil log-tabel, fungsinya
r
disebut dengan bitmask reduksi 283 = 0x11b (yang sesuai dengan Rijndael GF (2 8 ) polinomial reduksi x 8 + x 4 + x 3 + x + 1), dan hasilnya XORed dengan byte asli, secara efektif mengalikannya dengan 3 (= x + 1, sebagai polinomial) dalam bidang hingga Rijndael. Perkalian ini diulang 255 kali, mulai dari byte 1, dan hasilnya (ditambah byte nol awal) dikumpulkan ke dalam array 257-elemenL
yang terlihat seperti ini (bagian tengah dihilangkan):Alasan mengapa ada 257 elemen adalah bahwa, dengan 0 yang diawali dan dengan 1 terjadi dua kali, kita dapat menemukan invers modular dari byte yang diberikan hanya dengan melihat indeks (berbasis-nol) dalam array ini, meniadakannya, dan mencari naik byte pada indeks yang dinegasikan dalam array yang sama. (Dalam GolfScript, seperti dalam banyak bahasa pemrograman lainnya, indeks array negatif dihitung mundur dari akhir array.) Memang, inilah yang dilakukan oleh kode
L?~)L=
pada awal fungsiS
.Sisa kode memanggil fungsi helper
r
empat kali dengan bitmask reduksi 257 = 2 8 + 1 untuk membuat empat bit-rotated copy dari byte input terbalik. Ini semua dikumpulkan ke dalam array, bersama dengan konstanta 99 = 0x63, dan XOR bersama-sama untuk menghasilkan hasil akhir.sumber
x86-64 Kode mesin -
23 22 2019 byteMenggunakan set instruksi AES-NI
Menggunakan konvensi pemanggilan Windows, mengambil byte dan menghasilkan byte. Tidak perlu membalikkan
ShiftRows
karena tidak mempengaruhi byte pertama.sumber
Tabel dapat dihasilkan tanpa menghitung invers di bidang terbatas GF (256), dengan menggunakan logaritma. Akan terlihat seperti ini (kode Java, gunakan
int
untuk menghindari masalah denganbyte
tipe yang ditandatangani ):Idenya adalah bahwa 3 adalah generator multiplikasi GF (256) *. Tabelnya
t[]
sedemikian sehinggat[x]
sama dengan 3 x ; karena 3 255 = 1, kita mendapatkan bahwa 1 / (3 x ) = 3 255-x .sumber
0x1B
(satu 1 dalam hex literal) alih-alih0x11B
int
jenis adalah 32-bit di Jawa; Saya harus membatalkan bit yang lebih tinggi.GolfScript (82 karakter)
Menggunakan variabel global
A
danB
, dan menciptakan fungsi sebagai variabel globalS
.Inversi Galois adalah kekerasan; Saya bereksperimen dengan memiliki
mul
fungsi terpisah yang dapat digunakan kembali untuk transformasi affine pasca-inversi, tetapi ternyata lebih mahal karena perilaku luapan yang berbeda.Ini terlalu lambat untuk demo online - itu akan habis bahkan pada dua baris pertama dari tabel.
sumber
Python, 176 karakter
Jawaban ini untuk komentar-komentar Paŭlo Ebermann tentang membuat fungsi waktu konstan. Kode ini sesuai dengan tagihan.
sumber
d
ini dapat menghasilkan tabel pencarian pada waktu kompilasi, saya bisa menghemat beberapa dengan membuat ubyte sebagai param generik
sunting langsung
ubyte
keubyte
tanpa pencarian array, tidak ada percabangan dan loop sepenuhnya tidak bisa dikendalikanedit2 menggunakan @Thomas 'algo untuk membuat tabel pencarian
sumber
Stax , 53 byte
Jalankan dan debug itu
Saya tidak memiliki pemahaman khusus tentang S-box. Ini adalah konversi dari solusi Thomas Pornin (8 tahun!) .
sumber