Dalam FIPS-197 ( Advanced Encryption Standard , dikenal sebagai AES), ia digunakan secara berlebihan SubBytes
, yang dapat diimplementasikan sebagai
unsigned char SubBytes(unsigned char x) {
static const unsigned char t[256] = {
0x63,0x7C,0x77,0x7B,0xF2,0x6B,0x6F,0xC5,0x30,0x01,0x67,0x2B,0xFE,0xD7,0xAB,0x76,
0xCA,0x82,0xC9,0x7D,0xFA,0x59,0x47,0xF0,0xAD,0xD4,0xA2,0xAF,0x9C,0xA4,0x72,0xC0,
0xB7,0xFD,0x93,0x26,0x36,0x3F,0xF7,0xCC,0x34,0xA5,0xE5,0xF1,0x71,0xD8,0x31,0x15,
0x04,0xC7,0x23,0xC3,0x18,0x96,0x05,0x9A,0x07,0x12,0x80,0xE2,0xEB,0x27,0xB2,0x75,
0x09,0x83,0x2C,0x1A,0x1B,0x6E,0x5A,0xA0,0x52,0x3B,0xD6,0xB3,0x29,0xE3,0x2F,0x84,
0x53,0xD1,0x00,0xED,0x20,0xFC,0xB1,0x5B,0x6A,0xCB,0xBE,0x39,0x4A,0x4C,0x58,0xCF,
0xD0,0xEF,0xAA,0xFB,0x43,0x4D,0x33,0x85,0x45,0xF9,0x02,0x7F,0x50,0x3C,0x9F,0xA8,
0x51,0xA3,0x40,0x8F,0x92,0x9D,0x38,0xF5,0xBC,0xB6,0xDA,0x21,0x10,0xFF,0xF3,0xD2,
0xCD,0x0C,0x13,0xEC,0x5F,0x97,0x44,0x17,0xC4,0xA7,0x7E,0x3D,0x64,0x5D,0x19,0x73,
0x60,0x81,0x4F,0xDC,0x22,0x2A,0x90,0x88,0x46,0xEE,0xB8,0x14,0xDE,0x5E,0x0B,0xDB,
0xE0,0x32,0x3A,0x0A,0x49,0x06,0x24,0x5C,0xC2,0xD3,0xAC,0x62,0x91,0x95,0xE4,0x79,
0xE7,0xC8,0x37,0x6D,0x8D,0xD5,0x4E,0xA9,0x6C,0x56,0xF4,0xEA,0x65,0x7A,0xAE,0x08,
0xBA,0x78,0x25,0x2E,0x1C,0xA6,0xB4,0xC6,0xE8,0xDD,0x74,0x1F,0x4B,0xBD,0x8B,0x8A,
0x70,0x3E,0xB5,0x66,0x48,0x03,0xF6,0x0E,0x61,0x35,0x57,0xB9,0x86,0xC1,0x1D,0x9E,
0xE1,0xF8,0x98,0x11,0x69,0xD9,0x8E,0x94,0x9B,0x1E,0x87,0xE9,0xCE,0x55,0x28,0xDF,
0x8C,0xA1,0x89,0x0D,0xBF,0xE6,0x42,0x68,0x41,0x99,0x2D,0x0F,0xB0,0x54,0xBB,0x16};
return t[x];}
Fungsi ini tidak sewenang-wenang; ini adalah pemetaan yang dapat dibalik, yang terdiri dari inversi di Galois Field diikuti oleh transformasi affine. Semua detail ada di FIPS-197 bagian 5.1.1 atau di sini bagian 4.2.1 (dengan nama yang sedikit berbeda).
Satu masalah dengan implementasi sebagai tabel adalah bahwa ia terbuka untuk serangan yang disebut cache-timing .
Dengan demikian misi Anda adalah untuk merancang pengganti yang tepat untuk SubBytes()
fungsi di atas , yang menunjukkan perilaku waktu-konstan; kita akan berasumsi bahwa yang terjadi ketika tidak tergantung pada masukan x
dari SubBytes
digunakan baik:
- sebagai indeks array,
- sebagai kontrol operand dari
if
,while
,for
,case
, atau operator?:
; - karena setiap operan dari operator
&&
,||
,!
,==
,!=
,<
,>
,<=
,>=
,*
,/
,%
; - sebagai operan kanan operator
>>
,<<
,*=
,/=
,%=
,<<=
,>>=
.
Masuknya menang akan menjadi satu dengan biaya terendah, yang diperoleh dari jumlah operator dieksekusi di jalur data input-dependent, dengan berat 5 untuk operator unary -
dan ~
juga untuk <<1
, >>1
, +1
, -1
; bobot 7 untuk semua operator lain, shift dengan hitungan lain, atau tambah / subs konstanta lain (tipe gips dan promosi gratis). Secara prinsip, biaya itu tidak berubah dengan membuka gulungan (jika ada), dan independen dari input x
. Sebagai tie-breaker, jawaban dengan kode terpendek setelah menghapus spasi dan komentar menang.
Saya berencana untuk menunjuk sebuah entri sedini mungkin di tahun 2013, UTC. Saya akan mempertimbangkan jawaban dalam bahasa yang saya ketahui, rangking sebagai terjemahan langsung ke C yang tidak dioptimalkan untuk ukuran.
Permintaan maaf atas kelalaian awal +1
dan -1
dalam operator yang disukai, gips dan promosi gratis, dan peringkat ukuran. Catatan yang *
dilarang baik saat unary, maupun sebagai penggandaan.
sumber
Jawaban:
Nilai:
940 933 926910, pendekatan menara lapanganStruktur ini pada dasarnya sama dengan implementasi Boyar dan Peralta - mengurangi inversi di GF (2 ^ 8) menjadi inversi di GF (2 ^ 4), memecahnya menjadi prolog linier, badan non-linear, dan epilog linier, dan kemudian meminimalkannya secara terpisah. Saya membayar penalti untuk ekstraksi bit, tetapi saya mengimbanginya dengan bisa melakukan operasi secara paralel (dengan beberapa padding bit yang bijaksana
fwd
). Lebih detail ...Latar Belakang
Seperti yang disebutkan dalam deskripsi masalah, S-box terdiri dari inversi dalam implementasi khusus bidang Galois GF (2 ^ 8) diikuti oleh transformasi affine. Jika Anda tahu apa arti keduanya, lewati bagian ini.
Transformasi affine (atau linear) adalah fungsi
f(x)
yang menghormatif(x + y) = f(x) + f(y)
danf(a*x) = a*f(x)
.Bidang adalah serangkaian
F
elemen dengan dua elemen khusus, yang akan kita panggil0
dan1
, dan dua operator, yang akan kita panggil+
dan*
, yang menghormati berbagai properti. Pada bagian ini, menganggap bahwax
,y
, danz
unsurF
.F
bentuk kelompok abelian di bawah+
dengan0
sebagai identitas: yaitux + y
unsurF
;x + 0 = 0 + x = x
; masing-masingx
memiliki yang sesuai-x
sehinggax + (-x) = (-x) + x = 0
;x + (y + z) = (x + y) + z
; danx + y
=y + x
.F
selain0
membentuk kelompok abelian di bawah*
dengan1
sebagai identitas.x * (y + z) = (x * y) + (x * z)
.Ternyata ada beberapa batasan yang cukup parah pada bidang terbatas:
p
yang utama dank
kekuatannya) .F\{0}
bawah*
adalah siklik; yaitu ada setidaknya satu elemeng
sedemikian rupa sehingga setiap elemen adalah kekuatang
.k
bidang tatanan utama. Misalnya GF (2 ^ 8) memiliki representasi dalam hal polinomialx
lebih dari GF (2). Bahkan biasanya ada lebih dari satu representasi. Pertimbangkanx^7 * x
dalam GF (2 ^ 8); itu harus sama dengan beberapa polinomial order-7, tetapi yang mana? Ada banyak pilihan yang memberikan struktur yang tepat; AES memilih untuk membuatx^8 = x^4 + x^3 + x + 1
(polinomial terkecil yang bekerja secara leksikografis).Jadi bagaimana kita menghitung invers dalam representasi GF tertentu (2 ^ 8)? Ini masalah yang terlalu besar untuk ditangani secara langsung, jadi kita harus menguraikannya.
Menara menara: mewakili GF (2 ^ 8) dalam hal GF (2 ^ 4)
Alih-alih merepresentasikan GF (2 ^ 8) dengan polinomial 8 istilah di atas GF (2) kita bisa mewakilinya dengan polinomial 2 istilah di atas GF (2 ^ 4). Kali ini kita perlu memilih polinomial linier untuk
x^2
. Misalkan kita memilihx^2 = px + q
. Lalu(ax + b) * (cx + d) = (ad + bc + acp)x + (bd + acq)
.Apakah lebih mudah menemukan invers dalam representasi ini? Jika
(cx + d) = (ax + b)^-1
kita mendapatkan persamaan simultanad + (b + ap)c = 0
bd + (aq)c = 1
Biarkan
D = [b(b+ap) + a^2 q]
dan aturc = a * D^-1
;d = (b + ap) * D^-1
. Jadi kita dapat melakukan invers dalam GF (2 ^ 8) untuk biaya konversi ke GF (2 ^ 4), invers dan beberapa penambahan dan multiplikasi dalam GF (2 ^ 4), dan konversi kembali. Bahkan jika kita melakukan invers dengan menggunakan tabel, kita telah mengurangi ukuran tabel dari 256 menjadi 16.Detail implementasi
Untuk membangun representasi GF (4) kita dapat memilih antara tiga polinomial untuk mengurangi
x^4
:x^4 = x + 1
x^4 = x^3 + 1
x^4 = x^3 + x^2 + x + 1
Perbedaan yang paling penting adalah dalam penerapan multiplikasi. Untuk salah satu dari tiga (yang sesuai dengan
poly
3, 9, f) berikut ini akan berfungsi:Namun, jika kita memilih,
poly = 3
kita dapat menangani luapan jauh lebih efisien karena memiliki struktur yang bagus: tidak ada aliran berlipat ganda, karena kedua input sama-sama kubik danx^6 = x^2 (x + 1)
juga kubik. Selain itu kita dapat menyimpan perubahanb
: karena kita membiarkan overflow bertahan,a0 x^2
tidak memiliki bit set yang sesuai denganx
atau 1 dan jadi kita bisa menutupinya dengan -4 bukannya -1. Hasilnya adalahKita masih perlu memilih nilai-nilai
p
danq
untuk representasi GF (2 ^ 8) daripada GF (2 ^ 4), tetapi kami tidak memiliki banyak kendala pada mereka. Satu hal yang penting adalah kita bisa mendapatkan fungsi linear dari bit representasi asli kita ke bit representasi kerja. Ini penting karena dua alasan: pertama, mudah untuk melakukan transformasi linier, sedangkan transformasi non-linear akan membutuhkan pengoptimalan yang setara dalam kesulitan untuk hanya mengoptimalkan seluruh kotak-S; kedua, karena kita bisa mendapatkan beberapa manfaat sampingan. Untuk rekap struktur:Jika bit-bit
x
tersebutx7 x6 ... x0
maka karena transformasi linear kita dapatkana = f({x7}0000000 + 0{x6}000000 + ... + 0000000{x0}) = f({x7}0000000) + f(0{x6}000000) + ... + f(0000000{x0})
. Kuadratkan dan kami dapatkan dia^2 = f({x7}0000000)^2 + f(0{x6}000000)^2 + ... + f(0000000{x0})^2
mana persyaratan silang dibatalkan (karena dalam GF (2),1 + 1 = 0
). Jadia^2
dapat juga dihitung sebagai fungsi linear darix
. Kami dapat menambah transformasi linear maju untuk mendapatkan:dan kami turun ke tiga perkalian dan satu tambahan. Kita juga dapat memperluas kode perkalian untuk melakukan dua perkalian
Dinv
secara paralel. Jadi total biaya kami adalah transformasi linear ke depan, tambahan, dua perkalian, kebalikan dari GF (2 ^ 4), dan transformasi linear kembali. Kita dapat menggulirkan transformasi linear pasca-terbalik dari S-box dan mendapatkannya secara gratis.Perhitungan koefisien untuk transformasi linear tidak terlalu menarik, dan optimasi mikro juga tidak untuk menyelamatkan topeng di sini dan perubahan di sana. Bagian menarik yang tersisa adalah optimalisasi
inverse_GF16
. Ada 2 ^ 64 fungsi yang berbeda dari 4 bit hingga 4 bit, jadi pengoptimalan langsung membutuhkan banyak memori dan waktu. Apa yang saya lakukan adalah mempertimbangkan 4 fungsi dari 4 bit hingga 1 bit, letakkan batas atas total biaya yang diizinkan untuk satu fungsi (dengan biaya maksimum 63 per fungsi, saya dapat menghitung semua ekspresi yang sesuai dalam waktu kurang dari satu menit), dan untuk setiap tuple fungsi lakukan eliminasi subekspresi umum. Setelah 25 menit berderak, saya menemukan bahwa invers terbaik dengan cap itu memiliki total biaya 133 (rata-rata 33,25 per bit output, yang tidak buruk mengingat bahwa ekspresi termurah untuk setiap bit individu adalah 35) .Saya masih bereksperimen dengan pendekatan lain untuk meminimalkan inversi dalam GF (2 ^ 4), dan pendekatan yang membangun bottom-up daripada top-down telah menghasilkan peningkatan dari 133 menjadi 126.
sumber
& 1
dapat dipangkas (. Esp jikax
adalahunsigned char
;CHAR_BIT
adalah 8 di codegolf).Nilai: 980 = 7 * 5 + 115 * 7 + 7 * 5 + 15 * 7, minimalisasi Boyar dan Peralta
Saya menemukan teknik minimalisasi logika kombinasional baru dengan aplikasi kriptologi oleh Joan Boyar dan René Peralta, yang (kecuali untuk formalisme C) melakukan apa yang diperlukan. Teknik yang digunakan untuk menurunkan persamaan mereka dipatenkan oleh Amerika Serikat. Saya baru saja melakukan terjemahan C langsung dari persamaan mereka , silakan ditautkan di sini .
sumber
Nilai: 10965
Ini menggunakan prinsip yang sama untuk membuka gulungan array pencarian. Mungkin membutuhkan gips tambahan.
Terima kasih ugoren untuk menunjukkan cara meningkatkan
is_zero
.sumber
(c|-c)>>31
adalah 0 untuk 0 dan -1 jika tidak.c >> 4
sepertinya kau masuk dengan benar ke saya. Dan jika Anda benar-benar bersikeras -((unsigned int)(c|-c))>>31
adalahc?1:0
.c >>4
bekerja dengan atau tanpa ekstensi tanda. Tapi tangkapan yang bagus untuk menggunakan shift yang tidak ditandatangani: akan diedit ketika saya sampai di rumah dan dapat menggunakan komputer yang tepat daripada telepon. Terima kasih.Nilai: 9109, pendekatan aljabar
Saya akan meninggalkan pendekatan pencarian kalau-kalau ada yang bisa memperbaikinya secara drastis, tetapi ternyata pendekatan aljabar yang baik adalah mungkin. Implementasi ini menemukan invers multiplikasi dengan menggunakan algoritma Euclid . Saya telah menulisnya di Jawa tetapi pada prinsipnya bisa diporting ke C - Saya sudah berkomentar bagian yang akan berubah jika Anda ingin mengolahnya hanya menggunakan tipe 8-bit.
Terima kasih ugoren untuk menunjukkan cara mempersingkat
is_nonzero
cek dalam komentar atas jawaban saya yang lain.sumber
Nilai: 256 * (7+ (8 * (7 + 7 + 7) - (2 + 2)) + 5 + 7 + 7) = 48640 (dengan asumsi loop tidak terbuka)
Penjelasan:
Pada dasarnya pencarian array diimplementasikan kembali menggunakan operator bitwise dan selalu memproses seluruh array. Kita mengulang array, dan xor
x
dengan masing-masing indeks, kemudian menggunakan operator bitwise untuk meniadakan hasil secara logis, jadi kita mendapatkan 255 kapanx=i
dan 0 sebaliknya. Kami bitwise-dan ini dengan nilai array, sehingga nilai yang dipilih tidak berubah dan yang lain menjadi 0. Kemudian kita mengambil bitwise-atau array ini, dengan demikian hanya mengeluarkan nilai yang dipilih.Kedua
1 << j
operasi akan hilang sebagai bagian dari membuka gulungan, menggantinya dengan kekuatan 2 dari 1 hingga 128.sumber
-(2+2)
perhitungan perhitungan Anda berasal? Sunting: ah, sebaris menciptakan a<<1
dan a>>1
.Skor
19681692, menggunakan tabel pencarianCatatan: Solusi ini tidak lulus kriteria, karena
w >> b
.Menggunakan tabel pencarian, tetapi membaca 8 byte sekaligus.
3 * 7 + 32 * (6 * 7 + 2 * 5) + 7 = 692
sumber
w>>b
telah dihitung RHS darix
w >> b
manab
tergantung pada input; jugax/8
,x%8
, dan*= (1-badi)
. Yang pertama kemungkinan akan berubah menjadi ketergantungan waktu pada CPU low-end. Namun, gagasan menggunakan variabel luas tentu memiliki potensi.w >> b
sangat penting (saya perlu melihat apakah itu dapat diperbaiki tanpa menulis ulang semuanya.Tabel lookup dan mask, skor = 256 * (5 * 7 + 1 * 5) = 10240
Menggunakan pencarian tabel dengan masker untuk memilih hanya hasil yang kita inginkan. Menggunakan fakta yang
j|-j
negatif (ketika i! = X) atau nol (ketika saya == x). Pergeseran membuat topeng semua-satu atau semua-nol yang digunakan untuk memilih hanya entri yang kita inginkan.sumber