|
Cipher Fayadh
Block cipher Feistel 128-bit dengan fungsi putaran sigma-delta
|
Dokumentasi ini menjelaskan API C++ block cipher Cipher Fayadh (Tugas 2 IF4020 Kriptografi, Kelompok 15): cipher blok 128-bit, lima mode operasi, padding PKCS#7, autentikasi CMAC, dan format kontainer berkas yang dipakai aplikasi cipher_cli.
API tersusun dalam empat layer.
| Lapisan | Header | Isi |
|---|---|---|
| Aplikasi | src/main.cpp | CLI cipher_cli (encrypt, decrypt, keygen) |
| Kontainer & integritas | container.hpp, mac.hpp | SecureEnvelope (Encrypt-then-MAC), Cmac, derive_keys |
| Mode operasi & padding | modes.hpp, padding.hpp | modes::ecb_*, cbc_*, cfb_*, ofb_crypt, ctr_crypt, pkcs7_pad, pkcs7_unpad |
| Inti cipher | cipher.hpp, round.hpp, key_schedule.hpp, sbox.hpp, permutation.hpp, bits.hpp | BlockCipher, CustomCipher, round_f, key_schedule |
| Utilitas | util.hpp | util::Bytes, hex, XOR, CSPRNG OS, I/O berkas, secure_zero |
Parameter cipher:
| Parameter | Nilai | Konstanta |
|---|---|---|
| Ukuran blok | 128 bit (16 byte) | BLOCK_SIZE |
| Ukuran kunci | 128 bit (16 byte) | KEY_SIZE |
| Jumlah round | 16 (Feistel 2 cabang, 64 bit per cabang) | ROUNDS |
| Tag MAC | 128 bit (16 byte) | MAC_TAG_SIZE |
Tipe data umum: util::Bytes = std::vector<uint8_t>. Pointer const uint8_t* selalu menunjuk ke buffer dengan panjang tetap yang disebut di tabel.
| Fungsi | Masukan | Keluaran |
|---|---|---|
| CustomCipher(const uint8_t master_key[16]) | master key 16 byte | objek cipher (round key dibangkitkan sekali) |
| void encrypt_block(const uint8_t* in, uint8_t* out) const | in: plaintext 16 byte | out: ciphertext 16 byte (boleh sama dengan in) |
| void decrypt_block(const uint8_t* in, uint8_t* out) const | in: ciphertext 16 byte | out: plaintext 16 byte |
| uint64_t round_f(uint64_t r, uint64_t k) | setengah blok 64 bit, round key 64 bit | masker 64 bit |
| void key_schedule(uint64_t a, uint64_t b, uint64_t rk[16]) | dua separuh master key | 16 round key 64 bit |
Semua fungsi mode punya signature yang sama:
util::Bytes f(const BlockCipher& cipher, const uint8_t* iv, const util::Bytes& in);
| Fungsi | iv | Syarat in | Panjang keluaran | Exception |
|---|---|---|---|---|
| ecb_encrypt, ecb_decrypt | diabaikan (boleh nullptr) | kelipatan 16 | = in.size() | std::invalid_argument |
| cbc_encrypt, cbc_decrypt | 16 byte | kelipatan 16 | = in.size() | std::invalid_argument |
| cfb_encrypt, cfb_decrypt | 16 byte | bebas | = in.size() | std::invalid_argument jika iv null |
| ofb_crypt (= ofb_encrypt/ofb_decrypt) | 16 byte | bebas | = in.size() | idem |
| ctr_crypt (= ctr_encrypt/ctr_decrypt) | counter awal 16 byte | bebas | = in.size() | idem |
| ctr_at(iv, i, out) | counter awal | indeks blok uint64_t | out = (IV + i) mod 2^128 | std::invalid_argument |
ECB dan CBC membutuhkan input yang sudah dipad. CFB, OFB, dan CTR bekerja seperti stream cipher (tanpa padding). Untuk data ≥ modes::PARALLEL_THRESHOLD_BLOCKS blok, ECB, CTR, dan dekripsi CBC/CFB dijalankan paralel dengan OpenMP. Hasilnya identik dengan versi serial.
| Fungsi | Masukan | Keluaran | Exception |
|---|---|---|---|
| util::Bytes pkcs7_pad(const util::Bytes& in) | data sembarang | panjang kelipatan 16, selalu bertambah 1..16 byte | - |
| util::Bytes pkcs7_unpad(const util::Bytes& in) | data berpadding | data asli | PaddingError |
| Fungsi | Masukan | Keluaran | Exception |
|---|---|---|---|
| SecureEnvelope(const uint8_t master_key[16]) | master key | objek (kunci enkripsi dan kunci MAC diturunkan dari master key) | - |
| util::Bytes seal(const util::Bytes& pt, Mode mode, const uint8_t* iv = nullptr) const | plaintext, Mode, IV opsional (null = acak dari CSPRNG OS) | kontainer biner | std::runtime_error jika CSPRNG gagal |
| util::Bytes open(const util::Bytes& blob) const | kontainer | plaintext | FormatError, AuthenticationError |
| static void Cmac::compute(cipher, data, len, tag) | data sembarang | tag 16 byte | std::invalid_argument |
| static bool Cmac::verify(cipher, data, len, tag) | data, tag 16 byte | true jika cocok (constant-time) | std::invalid_argument |
| DerivedKeys derive_keys(const BlockCipher& master) | cipher berkunci master key | enc = E(0..01), mac = E(0..02) | - |
Format kontainer v1 (keluaran seal, masukan open):
| Offset | Panjang | Isi |
|---|---|---|
| 0 | 4 | magic IF15 |
| 4 | 1 | versi 0x01 |
| 5 | 1 | mode: 1 ECB, 2 CBC, 3 CFB, 4 OFB, 5 CTR |
| 6 | 16 | IV / counter awal (nol untuk ECB) |
| 22 | m | ciphertext (dipad PKCS#7 untuk ECB/CBC) |
| 22 + m | 16 | tag CMAC atas byte 0 .. 22 + m − 1 |
cipher_cli keygen -o secret.key cipher_cli encrypt -m cbc --key-file secret.key -i dokumen.pdf -o dokumen.enc cipher_cli encrypt -m ctr -k 000102030405060708090a0b0c0d0e0f --iv 0f0e0d0c0b0a09080706050403020100 -t "Pesan" -o pesan.enc cipher_cli decrypt --key-file secret.key -i dokumen.enc -o dokumen.pdf
Exit code: 0 sukses, 1 argumen salah, 2 I/O, 3 format/padding tidak valid, 4 integritas gagal.