Kavakoss

Prep UTS Blockchain

Di bawah ada latihan soal essay & case, buat belajar bikin codingan buka: http://kavakoss.netlify.app/posts/how-to-make-smart-contract-in-solidity/

Panduan Mengajar Kriptografi LKS SMK: Bedah 4 Serangan Mematikan RSA (Versi CTF)

Halo semuanya! Di sini kita akan bahas tuntas empat kelemahan paling sering keluar di perlombaan CTF (Capture The Flag) untuk soal RSA. Kita akan pelajari cara kerjanya, melihat contoh kodenya (di sisi pembuat soal), dan membedah solver.py-nya baris demi baris!

1. Fermat Factorization (Jebakan Bilangan Berdekatan)

๐Ÿง Teori & Kelemahan

Fermat’s Factorization Method mengasumsikan bahwa suatu modulus $N = p \times q$ dapat direpresentasikan sebagai selisih dari dua bilangan kuadrat yang sempurna: $N = a^2 - b^2 = (a-b)(a+b)$. Kelemahannya: Metode ini akan beraksi secapat kilat bila selisih (jarak) antara bilangan prima $p$ dan $q$ sangat kecil. Jika mereka terlalu dekat, kita bisa langsung menemukan faktornya hanya dengan mengakar kuadratkan $N$, lalu menambahkannya perlahan sampai polanya membentuk kuadrat sempurna.

๐Ÿ’ป Mari Bedah Kode chall.py (Script Pembuat Soal)

from Crypto.Util.number import getPrime, bytes_to_long
import gmpy2

p = getPrime(512)
# Di sinilah malapetakanya! Nilai Q dipaksa berada tepat sejauh 2000 step dari P.
q = int(gmpy2.next_prime(p + 2000))

n = p * q
e = 65537

flag = b"PETIR{fermat_factor_gg_gaming123}"
m = bytes_to_long(flag)
c = pow(m, e, n)

print("=== SOAL ===")
print(f"n = {n}")
print(f"e = {e}")
print(f"c = {c}")

Analisis Logika: Sang pembuat soal menggunakan gmpy2.next_prime(p + 2000). Ini membuat $q$ nyaris menempel dengan $p$. Dalam sistem RSA yang benar, $p$ dan $q$ harusnya dipilih terpisah (acak independen) agar jarak mereka di garis bilangan itu sangat jauh.

๐Ÿ›  Mari Bedah Kode solver.py (Script Attacker)

import gmpy2
from Crypto.Util.number import inverse, long_to_bytes

n = 494514086429776321999596142164928714224189874015707592113499937... # (Disingkat)
e = 65537
c = 361673809994190589832591296837356266708033368012080510863417138... # (Disingkat)

# Langkah 1: Kita ambil akar kuadrat taksiran terdekat dari N
a = gmpy2.isqrt(n)
# Kita cari nilai b^2 dengan mengurangi a^2 dengan N (Karena N = a^2 - b^2)
b2 = gmpy2.square(a) - n

# Langkah 2: Selama b2 bukan kuadrat yang pas, geser maju (a = a + 1)
while not gmpy2.is_square(b2):
    a += 1
    b2 = gmpy2.square(a) - n

# Berhenti! Pasangan a dan b telah ditemukan.
b = gmpy2.isqrt(b2)
p = a - b   # Karena p = a - b
q = a + b   # Karena q = a + b

# RSA Decryptor normal menggunakan rumus m = c^d mod n
phi = (p-1) * (q-1)
d = inverse(e, phi)
m = pow(c, d, n)

print("Flag:", long_to_bytes(m))

2. Wiener’s Attack (Bencana Eksponen $E$ Raksasa)

๐Ÿง Teori & Kelemahan

Wiener’s Attack memanfaatkan “kecerobohan” si pembuat kunci yang menggunakan Private Key ($D$) yang ukurannya terlalu kecil. Biasanya demi efisiensi proses dekripsi. Sifat kalkulasi RSA membuat nilai Public Key ($E$) menjadi membesar menjadi skala raksasa agar dapat menetralisirnya. Kelemahannya: Menurut teoremanya, jika $d < \frac{1}{3} \times N^{\frac{1}{4}}$, kita bisa menebak nilai $d$ hanya dengan bermodalkan pecahan (Continued Fraction) dari fraksi $\frac{e}{N}$ yang mana KEDUANYA ADALAH DATA PUBLIK!

๐Ÿ’ป Mari Bedah Kode chall.py (Script Pembuat Soal)

from Crypto.Util.number import getPrime, bytes_to_long, inverse

with open("flag.txt", "rb") as f:
    FLAG = f.read().strip()
m = bytes_to_long(FLAG)

def get_wiener_vuln_params():
    p = getPrime(512)
    q = getPrime(512)
    n = p * q
    phi = (p-1) * (q-1)
    
    # Wiener's d harus keciiiil
    while True:
        # Nilai p dan q aslinya masing2 512 bit (Total N 1024 bit).
        # Tapi nilai d sengaja di-setup HANYA sebesar 200 bit.
        d = getPrime(200) 
        if inverse(d, phi) != -1: 
            break
            
    # Hasil efek samping inverse: E akan membengkak setara 1024 bit
    e = inverse(d, phi)
    return n, e, d

n, e, d = get_wiener_vuln_params()
c = pow(m, e, n)

Analisis Logika: Kita bisa lihat bahwa fungsi utama untuk mencelakakan algoritma ada pada pemaksaan variabel d = getPrime(200). Jika kalian menjumpai soal dengan $N$ raksasa dan $E$ juga raksasa (normalnya $E$ kan 65537 yang tergolong mungil), sudah bisa ditebak itu adalah target mainannya Wiener.

๐Ÿ›  Mari Bedah Kode solver.py (Script Attacker)

import owiener
from Crypto.Util.number import long_to_bytes

n = 5501353310648397736366543... # (Disingkat)
e = 4632072885111319448398306... # (Disingkat)
c = 9268024723429629192824656... # (Disingkat)

# Serangan brutal menggunakan library sakti owiener
# Algoritma owiener akan membongkar pecahan (fraksi berlanjut) dari e / n
d = owiener.attack(e, n)

if d is not None:
    print("[+] Attack Wiener Berhasil! D:", d)
    m = pow(c, d, n)
    print("Flag:", long_to_bytes(m).decode())
else:
    print("Bukan Wiener. Coba metode lain!")

3. Hastad’s Broadcast Attack (Satu Pesan ke Mana-mana)

๐Ÿง Teori & Kelemahan

Bayangkan ada instruksi militer (Pesan yang sama) dan dikirim ke Tiga Panglima (3 Modulus $N$ yang berbeda), lalu semuanya di-enkripsi menggunakan eksponen kecil $e = 3$. Terlihat mulus, bukan? Kelemahannya: Karena sisa baginya ($C$) dan modulusnya ($N$) ada banyak (ada 3 set), kita bisa memotong sekat antar Modulus tersebut menggunakan Chinese Remainder Theorem. Karena $e=3$ dan kita tahu hasil gabungan dari Tiga Modulus, sistem modulus lenyap dan angka yang tersisa adalah murni persamaan matematika $C_{total} = M^3$. Untuk mendapatkan pesannya kembali, kita hanya perlu meng-akar pangkat tiganya!

๐Ÿ’ป Mari Bedah Kode chall.py (Script Pembuat Soal)

from Crypto.Util.number import getPrime, bytes_to_long

m = bytes_to_long(FLAG)
e = 3 # Di sinilah kuncinya! Eksponen sengaja dibikin kecil.

n_list = []
c_list = []

# Proses ini melooping enkripsi dengan payload pesan 'm' yang SAMA PERSIS 
for _ in range(3):
    p = getPrime(256)
    q = getPrime(256)
    n = p * q
    
    n_list.append(n)
    c_list.append(pow(m, e, n))

๐Ÿ›  OPSI 1: Solver Menggunakan SageMath

Cara paling effortless karena SageMath punya insting Built-in untuk operasi sisa bagi.

from sage.all import *

n1, c1 = 62771... , 10136...
n2, c2 = 12096... , 55380...
n3, c3 = 68536... , 51551...

N_list = [n1, n2, n3]
C_list = [c1, c2, c3]
e = 3

# Hubungkan 3 pesan parsial menjadi 1 Blok Besar tanpa sekatan Modulo N
m_cubed = crt(C_list, N_list)

# Ekstrak akar pangkat 3 karena The Cube sudah diruntuhkan!
m_real = m_cubed.nth_root(e)

# Karena hasilnya Integer, konversi dulu ke hex baru buang "0x" nya (indexing [2:]), baru decode.
print("Flag:", bytes.fromhex(hex(m_real)[2:]).decode('utf-8'))

๐Ÿ›  OPSI 2: Solver Menggunakan Pure Python + gmpy2

Bagaimana jika kita environment-nya tidak mendukung Sage? Ketik sendiri logikanya.

from Crypto.Util.number import inverse, long_to_bytes
import gmpy2

N_list = [n1, n2, n3]  # Anggap sudah berisi dari hasil chall.py
C_list = [c1, c2, c3]  # Anggap sudah berisi dari hasil chall.py
e = 3

# Fungsi implementasi Chinese Remainder Theorem (CRT) secara Manual
def crt(remainders, moduli):
    total = 0
    prod = 1
    # Kalikan ketiga-tiga nya
    for n in moduli:
        prod *= n
    # Konsep Bezout identity untuk sistem Chinese Remainder!
    for n_i, a_i in zip(moduli, remainders):
        p = prod // n_i
        total += a_i * inverse(p, n_i) * p
    return total % prod

# Terapkan CRT ke kasus kita
m_cubed = crt(C_list, N_list)

# Ekstrak akar pangkat 3 menggunakan gmpy2 (Python bawaan tidak punya precision float tinggi)
m_real, is_exact = gmpy2.iroot(m_cubed, e)

if is_exact:
    # m_real berupa tipe data mpz (gmpy2), cast (konversi paksa) ke int lalu ke bytes
    print("Flag:", long_to_bytes(int(m_real)).decode('utf-8'))
else:
    print("Gagal menemukan akar yang pas.")

4. Common Modulus Attack (Dua Eksponen di Atas N yang Sama)

๐Ÿง Teori & Kelemahan

Bencana terjadi jika sebuah sistem menggunakan nilai Modulus ($N$) yang persis sama-sama terus untuk mengenkripsi dua pesan identik (atau Flag M yang sama) dan mempublish TIGA KETIGA informasi ini: $N_{sama}, E_1, C_1$ dan $N_{sama}, E_2, C_2$. Kelemahannya: Memanfaatkan perhitungan Extended Euclidean Algorithm (EGCD). Jika Exponen pertama ($e_1$) dan Exponen kedua ($e_2$) ditarik EGCD-nya (Syarat: mereka harus saling Prima alias EGCD-nya = 1), kita akan mendapatkan dua koefisien penggali $a$ dan $b$. Sihir matematikanya bisa menyusun Ciphertext balasan: $C_1^a \times C_2^b \pmod N = M^1 \pmod N$ (PESAN ASLI TERBUKA!).

๐Ÿ’ป Mari Bedah Kode chall.py (Script Pembuat Soal)

from Crypto.Util.number import getPrime, bytes_to_long

p = getPrime(512)
q = getPrime(512)
n = p * q    # <- Pembuatan N cuman SEKALI saja 

e1 = 17
e2 = 65537

# N yang SAMA dikawinkan dengan kunci E yang BERBEDA untuk file yang SAMA
c1 = pow(m, e1, n)
c2 = pow(m, e2, n)

๐Ÿ›  Mari Bedah Kode solver.py (Script Attacker)

from Crypto.Util.number import inverse, long_to_bytes

n = 149776...  # Data dari chall
e1, c1 = 17, 338411...
e2, c2 = 65537, 723359...

# 1) Extended GCD mencari kunci sakti a dan b sedemikian hingga e1*a + e2*b = 1
def egcd(a, b):
    if a == 0: return b, 0, 1
    g, y, x = egcd(b % a, a)
    # y dan x menggeser posisi selama rekrusi untuk mencetak dua kunci balasan
    return g, x - (b // a) * y, y

_, a, b = egcd(e1, e2)

# Mengatur Perpangkatan Minus (Kondisi Wajib!)
# Di pemrograman konvensional, perpangkatan modulo tidak menerima (-).
# Contoh: c1^a mod N tidak bisa dieksekusi jika a = negatif.
# Solusinya: Kita pakai inverse() pada ciphernya, dan membalik tanda a menjadi positif!
if a < 0:
    c1 = inverse(c1, n)
    a = abs(a)
if b < 0:
    c2 = inverse(c2, n)
    b = abs(b)

# 2) Melakukan Penggabungan "Bezout's Identity"
# C1^a * C2^b (Mod n) = M^(e1*a) * M^(e2*b) = M^1 = Murni Plaintext M!
m = (pow(c1, a, n) * pow(c2, b, n)) % n
print("Flag:", long_to_bytes(m).decode())

Siap dipraktikkan langsung? Jangan lupa pastikan gmpy2, owiener, dan pycryptodome sudah terinstal!

Panduan Mengajar Kriptografi LKS SMK: RSA & CRT (Versi Kasual-Formal)

Dokumen ini dirancang sebagai panduan presentasi dengan gaya bahasa yang lebih santai (kasual) namun tetap menjaga profesionalitas (formal), sehingga materi matematis yang berat menjadi lebih renyah dan mudah dicerna oleh siswa SMK.


๐ŸŸข BAGIAN 1: FONDASI MODULAR ARITHMETIC (Slide 16 - 28)

Slide 16-18: Modulo (Konsep Jam Dinding)

Penyampaian: “Halo semuanya. Sebelum kita masuk ke hacking kriptografi, kita harus paham dulu medan pertempurannya. Di kriptografi modern, kita tidak menghitung sampai angka tak terhingga, tapi kita menggunakan sistem yang berputar seperti jam dinding. Ini yang kita sebut dengan Modulo. Bayangkan jam analog. Kalau sekarang jam 10, lalu lewat 5 jam, hasilnya bukan jam 15, kan? Tapi jam 3. Kenapa? Karena kita berada di sistem Modulo 12. Angkanya me-reset kembali ke 0 setiap melewati 12. Jadi, $15 \bmod 12 = 3$.”

Slide 22-23: GCD (Greatest Common Divisor)

Penyampaian: “Selanjutnya adalah GCD, atau dalam bahasa Indonesianya FPB (Faktor Persekutuan Terbesar) yang sudah kita pelajari saat SD. Intinya, kita mencari angka terbesar yang bisa membagi dua bilangan hingga habis tanpa sisa. Dalam kriptografi, jika GCD dari dua angka adalah 1, artinya kedua angka tersebut tidak memiliki pembagi yang sama (selain 1). Kondisi ini kita sebut sebagai Saling Prima (Coprime).”

from math import gcd
print(gcd(14, 15))  # Hasilnya 1, berarti mereka Coprime.

Slide 24: Extended Euclidean Algorithm (EGCD)

Penyampaian: “Nah, kalau GCD hanya mencari faktor terbesarnya saja, Extended GCD (EGCD) ini lebih canggih. Algoritma ini mencari dua angka ‘ajaib’ (yaitu variabel $x$ dan $y$) agar persamaan $A(x) + B(y) = GCD(A, B)$ bisa terpenuhi. Mungkin kalian bertanya, buat apa ribet-ribet mencari $x$ dan $y$? Nilai $x$ dan $y$ ini nantinya akan sangat kita butuhkan sebagai ‘kunci inggris’ untuk menyelesaikan salah satu serangan keren di RSA, yaitu Common Modulus Attack. Jadi, simpan dulu konsep ini di pikiran kalian.”

Slide 25: Modular Inverse (Kebalikan di Dunia Modulo)

Penyampaian: “Di matematika matematika biasa, kalau kita mau menetralkan perkalian, kita pakai pecahan (desimal). Misalnya, kebalikan dari 3 adalah $\frac{1}{3}$, karena $3 \times \frac{1}{3} = 1$. Masalahnya, di dunia Modulo tidak ada bilangan desimal! Jadi, Invers Modulo adalah mencari sebuah angka bulat yang apabila dikalikan akan menghasilkan sisa 1. Contoh, pada Modulo 11, invers dari 3 adalah 4. Mengapa? Karena $3 \times 4 = 12$, dan $12 \bmod 11 = 1$. Fungsi inverse() inilah yang akan digunakan komputer untuk membuat Private Key kalian nanti.”

from Crypto.Util.number import inverse
print(inverse(3, 11)) # Output: 4

Slide 26-27: Eksponen & Kongruen

Penyampaian: “Kenapa RSA bertumpu pada konsep perpangkatan (Eksponen)? Karena pangkat di dalam sistem modulo bertindak sebagai pintu satu arah (one-way function). Sangat mudah untuk menghitung pangkatnya, tapi nyaris mustahil untuk di-akar-kan kembali tanpa mengetahui kuncinya. Tambahan sedikit, jika kalian melihat tanda kongruen ($\equiv$), seperti $15 \equiv 3 \pmod{12}$, itu artinya nilai 15 dan 3 dianggap setara (memiliki nasib sisa yang sama) di dalam wilayah perhitungan Modulo 12.”

Slide 28: Latihan Modular Arithmetic

Penyampaian: “Mari kita uji pemahaman singkat.

  1. Berapa $25 \bmod 10$? (Ya, betul, 5)
  2. Berapa GCD dari 10 dan 20? (Benar, 10). Materi dasar ini penting, karena ini adalah akar seluruh kode RSA yang akan kita perbaiki nanti.”

๐ŸŸก BAGIAN 2: SYMMETRIC VS ASYMMETRIC CRYPTO (Slide 29 - 33)

Penyampaian: “Kriptografi terbagi menjadi dua konsep utama:

  1. Symmetric Crypto (Seperti AES): Bayangkan sebuah brankas dengan satu anak kunci. Untuk mengunci dan membuka, pakai kunci yang sama. Tantangannya: Bagaimana cara saya mengirim kunci ini ke teman saya dengan aman tanpa dicuri orang di tengah jalan?
  2. Asymmetric Crypto (Seperti RSA): Ini solusi super pintar. Setiap orang punya DUA kunci. Public Key (Boleh disebar ke publik, fungsinya hanya untuk mengunci kotak) dan Private Key (Disimpan sendiri rapt-rapat, fungsinya untuk membuka kotak). Dengan begini, komunikasi jauh lebih aman.”

๐Ÿ”ด BAGIAN 3: MEMBEDAH MESIN RSA (Slide 34 - 35)

Penyampaian: “Selamat datang di RSA (Rivest-Shamir-Adleman). Mari kita lihat komponen penyusun mesinnya:

  • $p$ dan $q$ = Dua buah bilangan prima acak.
  • $N$ = Modulus ($N = p \times q$). Angka ini di-publish. <- modulus perkalian 2 bilangan
  • Totient / $\phi(n)$ = $(p-1) \times (q-1)$. Ini roh dari sistem, harus sangat dirahasiakan! Ini fungsi euler yang menentukan private key
  • $e$ = Public Key. (Biasanya angka baku $65537$).
  • $d$ = Private Key. Ini dicari menggunakan Modular Inverse dari $e$ dan Totient.
  • $M$ = Plaintext (Pesan Asli).
  • $C$ = Ciphertext (Pesan Rahasia).

Skemanya sangat sederhana: Encrypt: Cipher = $M^e \bmod N$ Decrypt: Asli = $C^d \bmod N$”

from Crypto.Util.number import inverse

# Simulasi sederhana
p = 11; q = 13
n = p * q
phi = (p-1) * (q-1)

e = 7
d = inverse(e, phi) # Bikin Private Key

m = 50 # Pesan asli
c = pow(m, e, n) # Berubah jadi cipher
m_asli = pow(c, d, n) # Balik lagi ke M

๐ŸŸฃ BAGIAN 4: TIPE-TIPE SERANGAN RSA (Pendekatan CTF)

Penyampaian: “Dalam kompetisi CTF, tujuan kita sebagai Attacker hanya satu: Mencari nilai $D$ atau membongkar nilai $P$ dan $Q$. Berikut adalah 4 skenario kerentanan yang paling sering kalian temukan di soal nasional.”

1. Fermat Factorization (Jebakan Bilangan Berdekatan)

  • Inti Masalah: Pembuat soal ceroboh karena menggunakan nilai prima $p$ dan $q$ yang jaraknya terlalu berdekatan.
  • Cara Solve: Karena angkanya dekat, mereka pasti berada tepat di sebelah kiri dan kanan dari akar kuadrat $\sqrt{N}$. Kita cukup menebak nilai tengahnya, lalu diuji perlahan.
  • Solusi Script: Kita gunakan iterasi isqrt pada library gmpy2 hingga menemukan pasangannya.

2. Wiener’s Attack (Bencana Eksponen $e$ Raksasa)

  • Inti Masalah: Ciri fisiknya sangat jelas di mata. Kalau normalnya $e$ itu bernilai $65537$ (kecil), pada soal ini $e$ ukurannya raksasa hingga setara dengan panjang $N$! Ini menandakan ada yang salah: yaitu komponen privat $d$-nya ternyata sangat kecil.
  • Cara Solve: Secara matematis ini mengandalkan kalkulasi pecahan.
  • Solusi Script: Kalian cukup panggil library khusus import owiener, masukkan nilai $E$ dan $N$, dan boom, kunci $D$ langsung didapatkan.

3. Hastad’s Broadcast Attack (Bantuan Teorema Sisa Cina/CRT)

  • Inti Masalah: Sang komandan mengirim pesan yang sama persis, dikunci dengan eksponen $e$ yang angkanya kecil banget (biasanya $e=3$), dan dikirim ke 3 orang berbeda.
  • Cara Solve: Dengan 3 Cipher dan 3 Modulus, kita bisa menyatukannya menggunakan Chinese Remainder Theorem (CRT) untuk menghilangkan efek Modulo sama sekali.
  • Solusi Script: Ini paling cepat dikerjakan menggunakan lingkungan SageMath dengan fungsi crt(Array_C, Array_N).nth_root(3).

4. Common Modulus Attack (Modulus yang Diulang-ulang)

  • Inti Masalah: Bayangkan ada dua pesan ditransfer ke dalam satu ruter/server yang menggunakan Modulus ($N$) yang kembar, hanya eksponen publiknya ($e$) saja yang berbeda.
  • Cara Solve: Kalian ingat fungsi EGCD di Slide 24 tadi? Di sinilah fungsi itu bekerja! Kita mencari variabel $x$ dan $y$ dari dua $e$ tersebut untuk dijadikan pangkat balasan.
  • Solusi Script: Kita mengolah egcd(e1, e2) dan memangkatkan masing-masing ciphertext untuk membuatnya saling menghancurkan dan mengembalikan pesan asli.

๐ŸŸค BAGIAN 5: PRAKTIK SOAL CTF BERSAMA

Penyampaian Final: “Baiklah, teori tanpa praktik itu buta. Saya sudah menyiapkan studi kasus nyata yang biasa keluar di perlombaan. Mari buka direktori soal kita dan jalankan terminal Python masing-masing.”

(Instruksi untuk Pengajar:)

  1. Arahkan siswa menginstal library wajib: pip install pycryptodome pwntools owiener gmpy2.
  2. Buka folder cases (Fermat, Wiener, Hastad, Common Modulus) yang sudah kita persiapkan.
  3. Pandu mereka memasukkan variabel dari deskripsi.txt ke dalam solver.py masing-masing agar mereka paham di mana letak kelemahan script-nya!
  4. Jelaskan pelan-pelan alur kodenya saat mereka mengeksekusi solver dan flag CTF muncul di layar.

Bedah Kasus Mendalam: 5 Teknik RSA & CRT

Dokumen ini ditujukan untuk pendalaman materi (Deep Dive). Jika di dokumen sebelumnya kita lebih fokus pada variasi input dan template script, di sini kita akan menguliti satu soal spesifik per metodenya untuk benar-benar memahami “Mengapa serangan ini bisa terjadi?” dan “Apa maksud dari setiap baris kode di solver-nya?”.

Pahami konsep ini dengan baik, karena di LKS Nasional, soal tidak selalu copy-paste dari internet; terkadang logikanya diputar sedikit, dan hanya mereka yang paham base-math yang bisa survive!


1. Serangan Faktorisasi Fermat (Fermat’s Factorization)

๐Ÿ“Œ Problem (Studi Kasus)

Kalian diberikan $N$, $e$, dan Ciphertext $c$:

n = 31250212006763445585091765275815611414441460144007554907936173003051390499703
e = 65537
c = 9425482329188049380629737175402500350414966675005165977932822453835693006326

Sekilas $N$ terlihat besar (mungkin sulit jika di-brute-force biasa). Tetapi, ada kesalahan fatal dari si pembuat soal: Dia memilih nilai prima $P$ dan $Q$ yang nilainya bersebelahan/sangat dekat.

๐Ÿง  Konsep Matematika (Mengapa ini rentan?)

Menurut Pierre de Fermat, setiap angka ganjil $N$ (dan dalam RSA, $N$ PASTI ganjil karena hasil kali 2 bilangan prima) bisa ditulis sebagai selisih dari dua bilangan kuadrat sempurna: $$N = a^2 - b^2 = (a-b)(a+b)$$ Dalam RSA, artinya: $P = a - b$, $Q = a + b$

Jika $P$ dan $Q$ nilainya berdekatan, maka nilai $a$ (yang merupakan titik tengah di antara $P$ dan $Q$) posisinya sangat dekat dengan $\sqrt{N}$. Nilai $b$ (jarak dari titik tengah ke $P$ atau $Q$) pastilah angka yang sangat kecil. Maka kita tinggal mencari angka $a$ yang lebih besar dari $\sqrt{N}$, lalu kita cek apakah $a^2 - N$ menghasilkan bilangan kuadrat sempurna ($b^2$). Jika ya, kita merobohkan enkripsinya!

๐Ÿ’ป Block Solver & Penjelasan Baris

import gmpy2
from Crypto.Util.number import inverse, long_to_bytes

n = 31250212006763445585091765275815611414441460144007554907936173003051390499703
e = 65537
c = 9425482329188049380629737175402500350414966675005165977932822453835693006326

# Langkah 1: Tebak titik tengah 'a' dengan mengakarkan N
a = gmpy2.isqrt(n) + 1

# Langkah 2: Hitung b^2 = a^2 - N
b2 = gmpy2.square(a) - n

# Langkah 3: Selama b^2 BUKAN kuadrat sempurna, naikkan nilai 'a' sebesar 1
while not gmpy2.is_square(b2):
    a += 1
    b2 = gmpy2.square(a) - n

# Berhenti! Kita menemukan 'a' dan 'b' yang pas.
b = gmpy2.isqrt(b2)
p = a - b
q = a + b

# Langkah 4: RSA standar dekripsi
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
m = pow(c, d, n)
print("Flag:", long_to_bytes(m))

2. Wiener’s Attack (Small d)

๐Ÿ“Œ Problem (Studi Kasus)

n = 100782390310243452654316049286... # (Sangat Panjang)
e = 277987820790374158499946849491... # (Sangat Panjang, mendekati nilai N)
c = 918737222851996530510363242091...

Biasanya $e$ bernilai 65537 (5 digit). Tapi di sini $e$ angkanya masif sekali sampai menyamai ukuran $N$. Ini adalah indikasi terkuat adanya Wiener’s Attack.

๐Ÿง  Konsep Matematika

Mengingat rumus pembuatan kunci privat adalah $e \cdot d \equiv 1 \pmod{\phi(n)}$, maka jika $e$ bernilai ekstrim besar, maka nilai pendampingnya ($d$) otomatis sangat kecil agar hasilnya selaras dengan modulonya. Michael J. Wiener membuktikan bahwa jika $d < \frac{1}{3} N^{1/4}$, fraksi $\frac{k}{d}$ bisa didapatkan dari Pecahan Berlanjut (Continued Fractions) dari nilai $\frac{e}{N}$. Library eksternal akan meng-generate kandidat-kandidat $k$ dan $d$, lalu mengetesnya satu per satu.

๐Ÿ’ป Block Solver & Penjelasan Baris

import owiener # Jangan lupa: pip install owiener
from Crypto.Util.number import long_to_bytes

# (Masukkan N, E, C penuh disini)

# Langkah 1: Panggil fungsi serangan. 
# owiener akan mengolah N dan E menjadi pecahan berlanjut dan 
# mensimulasikan tebakan 'd'. Jika d benar, fungsi mengembalikan angkanya.
d = owiener.attack(e, n)

# Langkah 2: Pengecekan
if d is not None:
    print("[+] Key Dektripsi ditemukan:", d)
    
    # Langkah 3: Eksekusi pow(cipher, private_key, modulus N) RSA standar
    m = pow(c, d, n)
    print("Flag:", long_to_bytes(m))
else:
    print("[-] Eksponen d ternyata tidak cukup kecil untuk di hack lewat Wiener.")

3. Hastad’s Broadcast Attack (Chinese Remainder Theorem)

๐Ÿ“Œ Problem (Studi Kasus)

Jenderal A membagikan 1 Ciphertext rahasia identik ke 3 prajuritnya. Eksponennya seragam $e=3$. Karena disebarkan 3 kali ke $N$ yang berbeda-beda, kita menyadap 3 blok parameter ini:

e = 3
N = [205634584283921, 281488133544759, 243204987013927]
C = [129035251662998, 91932608401314, 39818815152345]

๐Ÿง  Konsep Matematika (Kekuatan CRT)

Sebenarnya, persamaan pesan $(m^3)$ di 3 prajurit itu adalah: $m^3 \equiv c_1 \pmod{N_1}$ $m^3 \equiv c_2 \pmod{N_2}$ $m^3 \equiv c_3 \pmod{N_3}$

Ingat hukum matematika: Jika sebuah angka $m^3$ dikunci pakai Modulo 3 buah $N$ yang berbeda (dan saling prima antar $N$), kita bisa MENGGABUNGKANNYA menembus sekat modulo dengan Chinese Remainder Theorem (CRT). Saat digabungkan, sistem CRT memproduksi angka gabungan raksasa yang berada dalam semesta modul $N_{gabungan} = N_1 \times N_2 \times N_3$. Karena $e = 3$, maka nilai $m^3$ secara matematis TIDAK AKAN MUNGKIN lebih besar dari nilai $N_{gabungan}$. Karena dia terjebak di ukuran yang kecil, batasan Modulo hilang alias “menguap”. Angka yang kita pegang murni $m^3$ murni! Kita bebas menarik akar pangkat 3 dari nilai tersebut di kalkulator ilmiah/SageMath biasa.

๐Ÿ’ป Block Solver & Penjelasan Baris (Dalam SageMath)

import gmpy2
from functools import reduce
from Crypto.Util.number import inverse, long_to_bytes

C = [129035251662998, 91932608401314, 39818815152345]
N = [205634584283921, 281488133544759, 243204987013927]
e = 3

# Langkah 1: Buat Fungsi Chinese Remainder Theorem manual
def crt(n_list, c_list):
    sum_c = 0
    prod_n = reduce(lambda a, b: a * b, n_list) # Kalikan semua N
    
    for n_i, c_i in zip(n_list, c_list):
        p = prod_n // n_i
        # Rumus CRT: C_i * modular_inverse(P, N_i) * P
        sum_c += c_i * inverse(p, n_i) * p
        
    return sum_c % prod_n

# Langkah 2: Gabungkan Ciphertext dengan CRT
m_cubed = crt(N, C)

# Langkah 3: Tarik akar pangkat 3 murni (karena e=3)
# gmpy2.iroot me-return (hasil_akar, boolean_is_exact)
m, is_exact = gmpy2.iroot(m_cubed, e)

if is_exact:
    print("Flag:", long_to_bytes(int(m)).decode('utf-8', errors='ignore'))
else:
    print("[-] Gagal, M^3 tampaknya bocor melampaui N_gabungan.")

4. Common Modulus Attack (Modulus Ulang-Alik)

๐Ÿ“Œ Problem (Studi Kasus)

Dua pesan didekripsi menggunakan satu router yang sama. $N$-nya sama. Eksponen ($e_1$ dan $e_2$) berbeda.

n  = 14221142502690494301552550186591702755353067... # (Sama)
e1 = 17
c1 = 27814917179047355182962325852924195156683515...
e2 = 65537
c2 = 72151608786938945763028302143171353242858546...

๐Ÿง  Konsep Matematika (Bezout’s Identity)

Jika $e_1$ dan $e_2$ itu Saling Prima (Nilai $FPB = 1$), hukum Bezout’s Identity dalam Algoritma Euclidean menyatakan bahwa PASTI akan selalu ada angka ajaib $a$ dan $b$ sedemikian rupa sehingga: $a \cdot e_1 + b \cdot e_2 = 1$

Lalu, apa hubungannya dengan Ciphertext $C_1$ dan $C_2$? Coba kita pangkatin mereka berdua pakai $a$ dan $b$: $(C_1)^a \cdot (C_2)^b = (m^{e_1})^a \cdot (m^{e_2})^b$ $(C_1)^a \cdot (C_2)^b = m^{(a \cdot e_1 + b \cdot e_2)}$ (Karena pangkat bagian kanan sama dengan 1, maka…) $(C_1)^a \cdot (C_2)^b = m^1 = M$

Hanya dengan memangkatkan dua Cipher yang bocor dengan $a$ dan $b$, kita mendapatkan Plaintext $M$ asli kita!

๐Ÿ’ป Block Solver & Penjelasan Baris

from Crypto.Util.number import long_to_bytes

n = 14221142502690494301552550186591702755353067
e1 = 17
c1 = 27814917179047355182962325852924195156683515
e2 = 65537
c2 = 72151608786938945763028302143171353242858546

def egcd(a, b):
    if a == 0: return b, 0, 1
    g, y, x = egcd(b % a, a)
    return g, x - (b // a) * y, y

# Langkah 1: Dapatkan a dan b dari Extended Euclidean
_, a, b = egcd(e1, e2)

# Langkah 2: Gunakan pow() bawaan Python
# Di Python 3.8+, jika 'a' atau 'b' negatif, pow() OTOMATIS melakukan inverse!
# Tidak perlu lagi if a < 0 atau if b < 0 secara manual.
m = (pow(c1, a, n) * pow(c2, b, n)) % n

print("Flag:", long_to_bytes(m).decode('utf-8', errors='ignore'))

5. Pure Math - Mempercepat Komputer pakai RSA-CRT

๐Ÿ“Œ Problem (Studi Kasus)

Bayangkan soal memberikan Ciphertext ukuran nyaris 16 Ribu Byte (sangat fatal jika diload dengan c^d mod n). Namun server sangat baik dengan menyertakan hint dp dan dq. Apa sebenarnya mereka?

๐Ÿง  Konsep Matematika (Optimalisasi Server RSA Asli)

Daripada mengerjakan 1 matematika yang luuuuar biasa berat ($C^D \bmod N$), pakar kriptografi RSA membuat metode di mana dekripsi dipecah jadi 2 pekerjaan kecil nan paralel di komputer: Menghitung sisi The $P$ saja dan Mod The $Q$ saja, di mana: $m_1 \equiv ({C \bmod P})^{DP} \bmod P$ di mana $DP = d \pmod{P-1}$ $m_2 \equiv ({C \bmod Q})^{DQ} \bmod Q$ di mana $DQ = d \pmod{Q-1}$

Sesudah 2 perhitungan kecil itu didapatkan, komputer menempelkannya menggunakan Chinese Remainder Theorem ($CRT$). Kombinasi ini mempercepat dekripsi RSA hingga puluhan dan ratusan kali lipat kecepatan!

๐Ÿ’ป Block Solver & Penjelasan Baris

from Crypto.Util.number import inverse, long_to_bytes

# (Nilai P, Q, C, DP, DQ masuk disini)

# Langkah 1: Dapatkan balasan nilai Plaintext dalam dimensi P dan Q.
# (Jauh lebih ringan dibanding dimensinya si N. Buktikan sendiri!)
m1 = pow(c, dp, p)
m2 = pow(c, dq, q)

# Langkah 2: Fase Penyatuan CRT.
# inverse(q, p) berfungsi mendapat bobot keseimbangan faktor.
# h adalah perbedaannya yang digeser mod p.
h = (inverse(q, p) * (m1 - m2)) % p

# Langkah 3: Gabungkan dan hasil M akan keluar secara presisi.
m = m2 + (h * q)

print("Flag RSA-CRT:", long_to_bytes(m))

๐Ÿงฉ 1. Ethereum Consensus Algorithm

๐Ÿ“˜ Pengertian Umum

Konsensus adalah mekanisme bagaimana jaringan Ethereum menyetujui transaksi dan menambah blok baru ke blockchain. Tujuannya agar semua node memiliki salinan data yang sama tanpa otoritas pusat.


๐Ÿงฎ a. Proof of Work (PoW)

  • Konsep: Miner memecahkan teka-teki matematika (hash puzzle). Siapa yang berhasil, menambah blok baru dan mendapat reward.
  • Contoh: Bitcoin, Ethereum sebelum The Merge.
  • Kelebihan: Aman, sudah teruji.
  • Kekurangan: Boros energi, transaksi lambat.

๐Ÿ“˜ Analogi: Seperti lomba siapa paling cepat memecahkan teka-teki rumit. Yang menang menulis transaksi ke buku besar.


๐Ÿช™ b. Proof of Stake (PoS)

  • Konsep: Tidak pakai mining, tapi validator dipilih berdasarkan jumlah koin (stake). Semakin besar stake, semakin tinggi peluang dipilih.
  • Contoh: Ethereum setelah The Merge (2022-sekarang).
  • Kelebihan: Hemat energi, lebih cepat.
  • Kekurangan: Risiko sentralisasi (validator besar berkuasa).

๐Ÿ“˜ Analogi: Seperti rapat pemilik saham. Siapa yang punya saham lebih banyak, lebih sering dapat kesempatan memvalidasi.


๐Ÿงพ c. Delegated Proof of Stake (DPoS)

  • Konsep: Pemilik token memilih delegate (perwakilan) untuk memvalidasi transaksi.
  • Contoh: TRON, EOS.
  • Kelebihan: Cepat, efisien.
  • Kekurangan: Kurang desentralisasi.

๐Ÿ“˜ Analogi: Seperti memilih perwakilan di DPR untuk mengambil keputusan atas nama rakyat.


๐Ÿงฑ d. Proof of Authority (PoA)

  • Konsep: Validator adalah pihak terpercaya yang identitasnya jelas (biasanya organisasi).
  • Contoh: VeChain, Binance Smart Chain (PoSA).
  • Kelebihan: Cepat dan stabil.
  • Kekurangan: Tidak cocok untuk blockchain publik karena tergantung kepercayaan.

๐Ÿ“˜ Analogi: Seperti notaris resmi yang memiliki izin pemerintah untuk mencatat transaksi hukum.


๐Ÿง  Ringkasan

MekanismeKunciContohKelebihanKekurangan
PoWKerja komputasiBitcoinAmanBoros energi
PoSStake tokenEthereum (baru)EfisienRisiko sentralisasi
DPoSVoting validatorTRONCepatKurang desentralisasi
PoAIdentitas terpercayaVeChainStabilTidak permissionless

โš™๏ธ 2. Design Principles in Ethereum (Solidity Functions)

a. receive()

  • Fungsi khusus untuk menerima Ether tanpa data.
  • Dipanggil otomatis ketika kontrak menerima ETH via transfer atau send.
receive() external payable {
    // menerima ETH tanpa data
}

b. fallback()

  • Dipanggil ketika function tidak ditemukan atau ketika menerima data yang tidak dikenal.
fallback() external payable {
    // menerima ETH dengan data atau panggilan salah
}

c. payable

  • Modifier agar fungsi bisa menerima Ether.
function deposit() public payable {}

d. pure & view

JenisDeskripsiContoh
pureTidak membaca atau menulis statereturn x + y;
viewHanya membaca statereturn balance[msg.sender];

e. memory vs storage

JenisSifatDigunakan untuk
storagePermanen di blockchainVariabel state
memorySementara, di RAM eksekusiData sementara di fungsi

๐Ÿ“˜ Kesimpulan: receive() & fallback() untuk menerima ETH, pure/view mengatur akses data, memory/storage menentukan tempat penyimpanan.


๐Ÿ’ป 3. Solidity Development & Programming

a. Built-in Variables

VariabelKeterangan
msg.senderAlamat pengirim transaksi
msg.valueJumlah ETH yang dikirim
block.timestampWaktu blok (Unix time)
tx.originPengirim awal transaksi (hindari untuk auth)
address(this)Alamat kontrak sendiri

b. Validation & Error Handling

FungsiTujuanContoh
require()Validasi input/aksesrequire(msg.sender == owner);
revert()Batalkan transaksi manualrevert("Failed");
assert()Cek kondisi logika (bug internal)assert(total > 0);

Pattern Aman: Gunakan urutan Checks โ†’ Effects โ†’ Interactions agar terhindar dari reentrancy attack.


c. Data Types dan Structures

  • Value types: uint, bool, int, address.
  • Reference types: string, array, mapping, struct.
  • Enum: daftar nilai tetap.
enum Status { Pending, Approved, Rejected }

d. Modifier

Digunakan untuk menambahkan syarat di fungsi.

modifier onlyOwner() {
    require(msg.sender == owner, "Not owner");
    _;
}

๐Ÿ“˜ Contoh: hanya owner yang bisa insert/update/delete data.


๐Ÿช™ 4. Ethereum Standard for Public Usage

a. ERC20 โ€“ Fungible Token

  • Semua token identik dan bernilai sama.
  • Contoh: DAI, USDT, LINK, UNI.
  • Fungsi utama: totalSupply, balanceOf, transfer, approve, transferFrom.
  • Event: Transfer, Approval.

๐Ÿ“˜ Analogi: Seperti uang kertas Rp100.000 โ€” semua lembar nilainya sama.


b. ERC721 โ€“ Non-Fungible Token (NFT)

  • Tiap token memiliki ID unik (tokenId).
  • Tidak bisa ditukar satu sama lain.
  • Contoh: Bored Ape, CryptoPunk.
  • Fungsi utama: ownerOf, balanceOf, safeTransferFrom, approve.
  • Event: Transfer, ApprovalForAll.

๐Ÿ“˜ Analogi: Seperti sertifikat rumah โ€” tiap sertifikat punya nomor unik dan tidak bisa ditukar begitu saja.


๐Ÿ” Perbandingan

AspekERC20ERC721
Nilai TokenSama semuaUnik per ID
ContohDAI, BNBNFT, Game item
PenggunaanUang digitalKoleksi unik
Fungsi Transfertransfer()transferFrom()

๐ŸŒ 5. Blockchain Implementation in Real Life

BidangContoh ImplementasiManfaat
Finance (DeFi)Uniswap, AAVE, PancakeSwapTanpa bank, transparan, cepat
Supply ChainIBM Food Trust, VeChainLacak asal barang, anti pemalsuan
NFT / Digital ArtOpenSea, Axie InfinityKepemilikan & royalti digital
Identity & CertificateSertifikat akademik digital, DIDAnti-pemalsuan identitas
Government / VotingE-voting berbasis blockchainTransparansi & audit trail tinggi

๐Ÿ“˜ Kesimpulan: Blockchain bukan hanya kripto โ€” bisa dipakai untuk DeFi, NFT, logistik, sertifikasi, hingga voting.


๐Ÿงพ Contoh Soal UTS & Case Study

๐Ÿง  Bagian A: Esai (Teori)

  1. Jelaskan perbedaan antara Proof of Work dan Proof of Stake dalam Ethereum. Sertakan kelebihan dan kekurangannya.
  2. Apa perbedaan antara fungsi receive() dan fallback() dalam Solidity?
  3. Jelaskan perbedaan antara pure, view, payable, dan berikan contoh penggunaannya.
  4. Bandingkan standar ERC20 dan ERC721 dengan analogi dunia nyata.
  5. Jelaskan mengapa konsep storage dan memory penting dalam manajemen data Solidity.

  1. Perbedaan Proof of Work dan Proof of Stake

    • Proof of Work (PoW): menggunakan daya komputasi untuk memecahkan puzzle kriptografi agar bisa menambah blok. Miner yang berhasil mendapatkan reward. Aman dan terbukti, tetapi boros energi dan lambat.
    • Proof of Stake (PoS): validator dipilih berdasarkan jumlah koin yang di-stake. Lebih hemat energi dan cepat, tetapi berisiko sentralisasi karena validator besar lebih berkuasa.

  1. Perbedaan receive() dan fallback()

    • receive(): fungsi khusus untuk menerima Ether tanpa data. Dipanggil otomatis jika kontrak menerima ETH dari transfer() atau send() tanpa calldata.
    • fallback(): fungsi cadangan yang dipanggil saat kontrak menerima data atau panggilan ke fungsi yang tidak ada. Bisa juga menerima ETH jika receive() tidak didefinisikan.
    • Perbedaan utama: receive() hanya untuk ETH tanpa data, sedangkan fallback() menangani data tidak dikenal.

  1. pure, view, payable

    • pure: tidak membaca atau menulis data di blockchain, hanya melakukan perhitungan matematis. Contoh: function sum(uint a, uint b) public pure returns(uint) { return a + b; }
    • view: membaca data blockchain tanpa mengubahnya. Contoh: function getBalance() public view returns(uint) { return address(this).balance; }
    • payable: fungsi yang dapat menerima Ether. Contoh: function deposit() public payable {}
    • Kesimpulan: pure = hitung saja, view = baca saja, payable = bisa menerima ETH.

  1. Perbandingan ERC20 dan ERC721 (dengan analogi)

    • ERC20: token bersifat fungible, setiap unit nilainya sama. Contoh: DAI, USDT, BNB. Analogi seperti uang kertas โ€” semua lembar Rp100.000 nilainya sama.
    • ERC721: token bersifat non-fungible, tiap token unik dengan tokenId. Contoh: Bored Ape, sertifikat digital. Analogi seperti sertifikat rumah โ€” tiap dokumen punya nomor unik.
    • Kesimpulan: ERC20 cocok untuk mata uang digital; ERC721 cocok untuk aset digital unik seperti NFT.

  1. Pentingnya storage dan memory dalam Solidity

    • storage: menyimpan data secara permanen di blockchain, biaya gas tinggi, digunakan untuk variabel state.
    • memory: menyimpan data sementara selama eksekusi fungsi, tidak permanen, digunakan untuk variabel lokal.
    • Pentingnya: menentukan efisiensi gas dan hasil akhir eksekusi fungsi. Jika salah memilih, data bisa hilang atau gas boros.
    • Contoh: variabel User storage u = users[i]; menyimpan perubahan ke blockchain, sedangkan User memory u = users[i]; hanya membuat salinan sementara.

๐Ÿงฉ Bagian B: Case Study / Coding

  1. Buat smart contract sederhana dengan fitur insert, read, update, delete (CRUD) untuk data mahasiswa. Hanya owner yang bisa mengubah data.
  2. Tambahkan fitur validasi agar tidak bisa menambah data dengan ID yang sama.
  3. Gunakan konsep mapping, struct, dan modifier untuk menyelesaikan tugas.

Hint Struktur Jawaban:

pragma solidity ^0.8.24;

contract StudentCRUD {
    struct Student {
        uint id;
        string name;
    }

    mapping(uint => Student) public students;
    mapping(uint => bool) private exists;
    address public owner;

    constructor() { owner = msg.sender; }

    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }

    function insert(uint _id, string memory _name) public onlyOwner {
        require(!exists[_id], "ID exists");
        students[_id] = Student(_id, _name);
        exists[_id] = true;
    }

    function read(uint _id) public view returns (string memory) {
        require(exists[_id], "Not found");
        return students[_id].name;
    }

    function update(uint _id, string memory _newName) public onlyOwner {
        require(exists[_id], "Not found");
        students[_id].name = _newName;
    }

    function remove(uint _id) public onlyOwner {
        require(exists[_id], "Not found");
        delete students[_id];
        exists[_id] = false;
    }
}

๐ŸŽ“ Kesimpulan Akhir (Ulasan Cepat UTS)

MateriFokus UtamaKata Kunci Penting
Consensus AlgorithmCara node menyetujui & menambah blokPoW, PoS, DPoS, PoA
Design PrinciplesFungsi & perilaku dasar Solidityreceive(), fallback(), payable, pure/view
Solidity ProgrammingStruktur, error handling, modifierrequire, revert, assert, onlyOwner
Ethereum StandardsPerbandingan ERC20 vs ERC721Fungible vs Non-Fungible
Blockchain in Real LifeImplementasi nyataDeFi, NFT, Supply Chain, Voting