<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Prime Numbers on kenji.blog</title><link>http://kenji.blog/id/tags/prime-numbers/</link><description>Recent content in Prime Numbers on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>id</language><copyright>kenjinote</copyright><lastBuildDate>Fri, 11 Sep 2026 16:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/id/tags/prime-numbers/index.xml" rel="self" type="application/rss+xml"/><item><title>Hipotesis Riemann dan Distribusi Bilangan Prima: Hubungan Mendalam dengan Kriptografi Modern</title><link>http://kenji.blog/id/p/riemann-hypothesis-prime-distribution-cryptography/</link><pubDate>Fri, 11 Sep 2026 16:00:00 +0900</pubDate><guid>http://kenji.blog/id/p/riemann-hypothesis-prime-distribution-cryptography/</guid><description>&lt;img src="http://kenji.blog/p/riemann-hypothesis-prime-distribution-cryptography/img/eyecatch.jpg" alt="Featured image of post Hipotesis Riemann dan Distribusi Bilangan Prima: Hubungan Mendalam dengan Kriptografi Modern" />&lt;h1 id="1-pendahuluan-misteri-alam-semesta-bilangan-prima-dan-hipotesis-riemann">1. Pendahuluan: Misteri Alam Semesta Bilangan Prima dan Hipotesis Riemann
&lt;/h1>&lt;p>&amp;ldquo;Bilangan prima (Prime Numbers)&amp;rdquo; adalah bilangan asli yang hanya bisa dibagi oleh 1 dan bilangan itu sendiri, yang juga sering disebut sebagai &amp;ldquo;atom&amp;rdquo; dalam dunia matematika. Deret bilangan 2, 3, 5, 7, 11, 13&amp;hellip; ini pada pandangan pertama terlihat tidak beraturan dan muncul secara acak. Sejak matematikawan Yunani kuno, Euclid, membuktikan bahwa &amp;ldquo;bilangan prima jumlahnya tak terhingga&amp;rdquo;, tak terhitung banyaknya matematikawan yang menantang diri mereka untuk mengungkap keteraturan yang tersembunyi di balik susunan bilangan prima ini.&lt;/p>
&lt;p>Yang paling mendekati misteri bilangan prima ini adalah &lt;strong>&amp;ldquo;Hipotesis Riemann (Riemann Hypothesis)&amp;rdquo;&lt;/strong>, yang diusulkan oleh matematikawan Jerman, Bernhard Riemann, pada tahun 1859. Hipotesis Riemann adalah salah satu dari masalah terpenting dan belum terpecahkan dalam matematika modern, serta merupakan salah satu dari Masalah Hadiah Milenium (Millennium Prize Problems) yang ditetapkan oleh Clay Mathematics Institute dengan hadiah sebesar 1 juta dolar.&lt;/p>
&lt;p>Sekilas, masalah sulit matematika murni terkait distribusi bilangan prima mungkin terasa tidak ada hubungannya dengan kehidupan kita sehari-hari. Namun, keamanan internet yang menopang infrastruktur masyarakat modern, terutama &lt;strong>teknologi kriptografi modern seperti kriptografi RSA dan kriptografi kurva eliptik (ECC)&lt;/strong>, sangat bergantung pada sifat-sifat bilangan prima yang sangat besar.&lt;/p>
&lt;p>Dalam artikel ini, kita akan melakukan perjalanan matematis dari distribusi bilangan prima menuju Teorema Bilangan Prima, fungsi Zeta Riemann, hingga ke inti dari Hipotesis Riemann, lalu menggali lebih dalam dan detail tentang bagaimana hal tersebut terhubung dengan teknologi kriptografi modern, serta apa yang akan terjadi pada dunia jika Hipotesis Riemann berhasil dibuktikan.&lt;/p>
&lt;hr>
&lt;h1 id="2-teorema-bilangan-prima-dan-distribusi-bilangan-prima-penemuan-gauss">2. Teorema Bilangan Prima dan Distribusi Bilangan Prima: Penemuan Gauss
&lt;/h1>&lt;p>Untuk memahami bagaimana bilangan prima terdistribusi, para matematikawan memikirkan &lt;strong>fungsi penghitungan bilangan prima (Prime-counting function)&lt;/strong> $\pi(x)$, yang menyatakan &amp;ldquo;berapa banyak bilangan prima yang ada di bawah suatu bilangan $x$&amp;rdquo;.&lt;/p>
&lt;p>Sebagai contoh:&lt;/p>
&lt;ul>
&lt;li>$\pi(10) = 4$ (2, 3, 5, 7)&lt;/li>
&lt;li>$\pi(100) = 25$&lt;/li>
&lt;li>$\pi(1000) = 168$&lt;/li>
&lt;/ul>
&lt;p>Carl Friedrich Gauss, seorang matematikawan jenius berusia 15 tahun, menghitung tabel bilangan prima yang sangat besar dan menemukan bahwa frekuensi kemunculan bilangan prima berkurang secara berbanding terbalik dengan logaritma natural $\ln x$. Dengan kata lain, ia memperkirakan bahwa peluang menemukan bilangan prima di sekitar suatu bilangan $x$ adalah sekitar $\frac{1}{\ln x}$.&lt;/p>
&lt;p>Representasi dari penemuan ini menggunakan integral disebut &lt;strong>integral logaritmik (Logarithmic integral)&lt;/strong> $\text{Li}(x)$.&lt;/p>
$$ \text{Li}(x) = \int_{2}^{x} \frac{dt}{\ln t} $$
&lt;p>Perkiraan Gauss kemudian dibuktikan secara independen oleh Jacques Hadamard dan Charles-Jean de La Vallée Poussin pada tahun 1896, yang memantapkannya sebagai &lt;strong>Teorema Bilangan Prima (Prime Number Theorem, PNT)&lt;/strong>.&lt;/p>
$$ \lim_{x \to \infty} \frac{\pi(x)}{\text{Li}(x)} = 1 $$
&lt;p>Atau secara pendekatan dinyatakan sebagai berikut.&lt;/p>
$$ \pi(x) \sim \frac{x}{\ln x} $$
&lt;p>Melalui teorema ini, kita mengetahui bahwa jika dilihat secara makroskopis, bilangan prima memiliki distribusi yang sangat mulus dan dapat diprediksi. Namun, jika dilihat secara mikroskopis, selalu terdapat &amp;ldquo;galat (error)&amp;rdquo; atau &amp;ldquo;fluktuasi&amp;rdquo; antara $\pi(x)$ dan $\text{Li}(x)$. Sifat asli dari fluktuasi inilah misteri terbesar yang coba dipecahkan oleh Hipotesis Riemann.&lt;/p>
&lt;hr>
&lt;h1 id="3-fungsi-zeta-riemann-dan-produk-euler">3. Fungsi Zeta Riemann dan Produk Euler
&lt;/h1>&lt;p>Senjata paling kuat dalam menganalisis distribusi bilangan prima adalah &lt;strong>Fungsi Zeta Riemann (Riemann Zeta Function)&lt;/strong>. Awalnya, fungsi ini adalah deret tak terhingga yang didefinisikan untuk bilangan real $s > 1$ oleh Leonhard Euler.&lt;/p>
$$ \zeta(s) = \sum_{n=1}^\infty \frac{1}{n^s} = 1 + \frac{1}{2^s} + \frac{1}{3^s} + \frac{1}{4^s} + \dots $$
&lt;p>Salah satu pencapaian terbesar Euler adalah membuktikan bahwa deret tak terhingga ini dapat dinyatakan sebagai produk tak terhingga (perkalian tak terhingga) atas semua bilangan prima $p$. Inilah yang disebut dengan &lt;strong>Produk Euler (Euler Product Formula)&lt;/strong>.&lt;/p>
$$ \zeta(s) = \prod_{p \text{ prime}} \frac{1}{1 - p^{-s}} = \left( \frac{1}{1 - 2^{-s}} \right) \left( \frac{1}{1 - 3^{-s}} \right) \left( \frac{1}{1 - 5^{-s}} \right) \dots $$
&lt;p>Pemahaman intuitif dari pembuktian ini adalah dengan mengekspansi setiap suku di ruas kanan sebagai deret geometri, lalu mengalikannya. Berdasarkan Teorema Dasar Aritmetika (setiap bilangan asli dapat direpresentasikan secara unik sebagai hasil kali bilangan prima), jumlah kebalikan dari bilangan asli pada ruas kiri akan direkonstruksi sepenuhnya.&lt;/p>
&lt;p>&lt;strong>Satu rumus matematika ini menjadi jembatan yang menghubungkan analisis (deret tak terhingga, fungsi kontinu) dengan teori bilangan (bilangan prima, angka diskrit).&lt;/strong> Menyelidiki fungsi zeta sama artinya dengan menyelidiki distribusi bilangan prima.&lt;/p>
&lt;hr>
&lt;h1 id="4-perluasan-analitik-dan-perluasan-ke-bidang-kompleks">4. Perluasan Analitik dan Perluasan ke Bidang Kompleks
&lt;/h1>&lt;p>Kejeniusan Riemann terletak pada kenyataan bahwa ia memperluas variabel $s$ dalam $\zeta(s)$, yang awalnya hanya dipertimbangkan Euler pada bilangan real, menjadi &lt;strong>bilangan kompleks $s = \sigma + it$ ($\sigma$ adalah bagian real, $t$ adalah bagian imajiner)&lt;/strong>.&lt;/p>
&lt;p>Deret tak terhingga aslinya hanya konvergen pada $\sigma > 1$, namun Riemann menggunakan metode yang disebut &amp;ldquo;Perluasan Analitik (Analytic Continuation)&amp;rdquo; untuk memperluas definisi sehingga $\zeta(s)$ memiliki arti di seluruh bidang kompleks, kecuali pada titik kutub $s = 1$.&lt;/p>
&lt;p>Lebih lanjut, ia menurunkan persamaan fungsional (Functional equation) indah yang dipenuhi oleh fungsi zeta.&lt;/p>
$$ \zeta(s) = 2^s \pi^{s-1} \sin\left(\frac{\pi s}{2}\right) \Gamma(1-s) \zeta(1-s) $$
&lt;p>Di sini, $\Gamma(x)$ adalah fungsi Gamma. Berdasarkan persamaan ini, kita dapat mengetahui sifat di bidang sebelah kiri dari sifat di bidang sebelah kanan.&lt;/p>
&lt;h3 id="pembuat-nol-zeros-of-the-zeta-function">Pembuat Nol (Zeros of the Zeta Function)
&lt;/h3>&lt;p>Bilangan kompleks $s$ yang membuat nilai fungsi zeta menjadi 0 disebut sebagai &amp;ldquo;pembuat nol&amp;rdquo; (titik nol).
Dari persamaan fungsional, ketika $s$ adalah bilangan genap negatif ($-2, -4, -6, \dots$), nilai $\sin(\pi s / 2)$ menjadi 0, sehingga $\zeta(s) = 0$. Ini disebut sebagai &lt;strong>pembuat nol trivial (Trivial zeros)&lt;/strong>.&lt;/p>
&lt;p>Namun, yang penting dalam distribusi bilangan prima adalah pembuat nol lainnya, yaitu &lt;strong>pembuat nol non-trivial (Non-trivial zeros)&lt;/strong> yang berada di dalam &amp;ldquo;jalur kritis (Critical strip)&amp;rdquo; $0 \le \sigma \le 1$.&lt;/p>
&lt;hr>
&lt;h1 id="5-inti-dari-hipotesis-riemann-dan-rumus-eksplisit">5. Inti dari Hipotesis Riemann dan Rumus Eksplisit
&lt;/h1>&lt;p>Riemann menghitung sejumlah kecil pembuat nol dan merumuskan sebuah dugaan yang mengejutkan. Inilah &lt;strong>Hipotesis Riemann&lt;/strong>.&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>Hipotesis Riemann (Riemann Hypothesis)&lt;/strong>
Semua pembuat nol non-trivial dari fungsi zeta Riemann $\zeta(s)$ berada pada garis dengan bagian real $1/2$ ($\text{Re}(s) = 1/2$).&lt;/p>
&lt;/blockquote>
&lt;p>Garis dengan bagian real 1/2 ini disebut sebagai &amp;ldquo;Garis kritis (Critical line)&amp;rdquo;.&lt;/p>
&lt;div class="mermaid">graph TD
A["Fungsi Zeta Riemann ζ(s)"] --> B["Perluasan ke bidang kompleks dengan perluasan analitik"]
B --> C["Pembuat nol trivial (s = -2, -4, -6 ...)"]
B --> D["Pembuat nol non-trivial (0 &lt;= Re(s) &lt;= 1)"]
D --> E["Hipotesis Riemann"]
E --> F["Semua pembuat nol non-trivial berada pada Re(s) = 1/2"]
F --> G["Menuju pembuktian limit suku galat dari distribusi bilangan prima"]&lt;/div>
&lt;p>Mengapa Hipotesis Riemann begitu penting? Hal itu karena pembuat nol dari fungsi zeta &lt;strong>sepenuhnya&lt;/strong> menentukan distribusi bilangan prima.&lt;/p>
&lt;p>Riemann dan kemudian matematikawan von Mangoldt, menurunkan &amp;ldquo;Rumus eksplisit (Explicit formula)&amp;rdquo; yang mendeskripsikan distribusi bilangan prima dengan akurat. Dengan menggunakan fungsi Chebyshev $\psi(x)$, hal tersebut diekspresikan sebagai berikut.&lt;/p>
$$ \psi(x) = x - \sum_{\rho} \frac{x^\rho}{\rho} - \ln(2\pi) - \frac{1}{2}\ln(1 - x^{-2}) $$
&lt;p>Di sini, $\rho$ adalah penjumlahan atas semua pembuat nol non-trivial dari fungsi zeta.
Suku utamanya adalah $x$ (yang berkorespondensi dengan Teorema Bilangan Prima), dan dengan menambahkan/mengurangkan suku berbentuk gelombang yang bergantung pada pembuat nol $\rho$, bentuk tangga distribusi bilangan prima yang akurat dapat dipulihkan. Dapat dikatakan bahwa pembuat nol non-trivial merepresentasikan &amp;ldquo;frekuensi (gelombang)&amp;rdquo; dari distribusi bilangan prima.&lt;/p>
&lt;p>Jika Hipotesis Riemann benar, dan bagian real dari semua pembuat nol non-trivial $\rho$ tepat bernilai $1/2$, maka suku galat pada Teorema Bilangan Prima secara teoretis akan berada pada rentang batas minimum yang mungkin terbayangkan.&lt;/p>
$$ |\pi(x) - \text{Li}(x)| \le \frac{1}{8\pi} \sqrt{x} \ln x \quad \text{untuk} \quad x \ge 2657 $$
&lt;p>Dengan kata lain, &lt;strong>jika Hipotesis Riemann terbukti benar, hal itu akan membuktikan bahwa bilangan prima terdistribusi dengan cara yang paling &amp;ldquo;teratur dan indah&amp;rdquo; yang dapat kita bayangkan&lt;/strong>.&lt;/p>
&lt;hr>
&lt;h1 id="6-hubungan-yang-tak-terpisahkan-antara-teknologi-kriptografi-modern-dan-bilangan-prima">6. Hubungan yang Tak Terpisahkan Antara Teknologi Kriptografi Modern dan Bilangan Prima
&lt;/h1>&lt;p>Sejauh ini kita berada di ranah matematika murni yang mendalam, namun sifat bilangan prima ini menjadi pondasi dasar bagi masyarakat digital modern. Contoh utamanya adalah kriptografi kunci publik seperti &lt;strong>Kriptografi RSA&lt;/strong>.&lt;/p>
&lt;p>Keamanan dari berbagai komunikasi, mulai dari pembayaran kartu kredit di internet, pengiriman kata sandi, hingga tanda tangan digital pada blockchain, semuanya bergantung pada &amp;ldquo;bilangan prima&amp;rdquo;.&lt;/p>
&lt;h3 id="cara-kerja-kriptografi-rsa">Cara Kerja Kriptografi RSA
&lt;/h3>&lt;p>Keamanan kriptografi RSA didasarkan pada fakta matematis (masalah faktorisasi prima) bahwa &amp;ldquo;memfaktorkan bilangan komposit (majemuk) dengan jumlah digit yang besar adalah hal yang sangat sulit&amp;rdquo;.&lt;/p>
&lt;ol>
&lt;li>
&lt;p>&lt;strong>Pembuatan Kunci&lt;/strong>:
Pilih secara acak bilangan prima $p$ dan $q$ yang berukuran besar (misalnya masing-masing 2048 bit).
Kalikan keduanya untuk menghitung $N = p \times q$. Nilai $N$ ini menjadi bagian dari kunci publik.
Gunakan fungsi totient Euler $\phi(N) = (p-1)(q-1)$ untuk menghasilkan kunci privat $d$.&lt;/p>
$$ e \times d \equiv 1 \pmod{\phi(N)} $$
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Enkripsi dan Dekripsi&lt;/strong>:
Teks terang (plaintext) $M$ diubah menjadi teks sandi (ciphertext) $C$ menggunakan kunci publik $e$ dan $N$.
&lt;/p>
$$ C \equiv M^e \pmod{N} $$
&lt;p>
Hanya orang yang memiliki kunci privat $d$ yang bisa melakukan dekripsi.
&lt;/p>
$$ M \equiv C^d \pmod{N} $$
&lt;/li>
&lt;/ol>
&lt;div class="mermaid">graph LR
A["Teks Terang (Plaintext)"] --> B["Enkripsi dengan Kunci Publik (e, N)"]
B --> C["Teks Sandi (Ciphertext)"]
C --> D["Dekripsi dengan Kunci Privat (d)"]
D --> E["Teks Terang Asli"]
F["Penyerang (Attacker)"] -- "Mencoba faktorisasi prima dari N" --> C
F -.-> G["Tanpa mengetahui p dan q, d tidak dapat dihitung"]&lt;/div>
&lt;p>Untuk memecahkan kriptografi RSA, seseorang harus menemukan (melakukan faktorisasi prima) bilangan prima asli $p$ dan $q$ dari nilai $N$ yang sangat besar. Meskipun menggunakan algoritma arus utama saat ini (seperti General Number Field Sieve: GNFS), memfaktorkan angka dengan ratusan digit akan membutuhkan waktu jauh melampaui usia alam semesta, bahkan jika menggunakan superkomputer sekalipun.&lt;/p>
&lt;hr>
&lt;h1 id="7-dampak-hipotesis-riemann-terhadap-teknologi-kriptografi">7. Dampak Hipotesis Riemann terhadap Teknologi Kriptografi
&lt;/h1>&lt;p>Lalu, bagaimana &amp;ldquo;Hipotesis Riemann&amp;rdquo; yang berada di puncak matematika murni, bersinggungan dengan &amp;ldquo;teknologi kriptografi&amp;rdquo;?&lt;/p>
&lt;h3 id="71-algoritma-pembangkitan-bilangan-prima-pengujian-keprimaan-dan-hipotesis-riemann-yang-diperluas-grh">7.1. Algoritma Pembangkitan Bilangan Prima (Pengujian Keprimaan) dan Hipotesis Riemann yang Diperluas (GRH)
&lt;/h3>&lt;p>Untuk mengoperasikan kriptografi RSA, pertama-tama kita perlu membangkitkan bilangan prima $p$ dan $q$ yang berukuran sangat besar. Akan tetapi, tidaklah mudah untuk memastikan dengan cepat dan pasti apakah &amp;ldquo;suatu bilangan merupakan bilangan prima atau bukan&amp;rdquo;.&lt;/p>
&lt;p>Saat ini, metode yang digunakan secara praktis adalah algoritma probabilistik yang disebut &lt;strong>Uji Keprimaan Miller-Rabin (Miller-Rabin primality test)&lt;/strong>. Algoritma ini sangat cepat, namun memiliki risiko bahwa bilangan komposit disalahartikan sebagai bilangan prima atau disebut &amp;ldquo;bilangan prima semu (pseudoprime)&amp;rdquo; dengan probabilitas yang sangat kecil.&lt;/p>
&lt;p>Namun, jika kita berasumsi bahwa &lt;strong>&amp;ldquo;Hipotesis Riemann yang Diperluas (Generalized Riemann Hypothesis, GRH)&amp;rdquo;&lt;/strong>, yang memperluas Hipotesis Riemann pada fungsi L-Dirichlet bernilai benar, maka ceritanya akan berubah secara dramatis.
Jika GRH benar, batas atas dari jumlah pengujian dalam uji Miller-Rabin akan dijamin secara matematis, sehingga meningkatkannya dari sekadar algoritma probabilistik menjadi &lt;strong>&amp;ldquo;Algoritma Waktu Polinomial Deterministik&amp;rdquo;&lt;/strong> (Ini adalah fakta penting yang telah diketahui bahkan sebelum Uji Keprimaan AKS ditemukan).&lt;/p>
&lt;p>Dengan kata lain, Hipotesis Riemann (dan perluasannya) memainkan peranan langsung dalam memberikan kepastian mutlak pada pondasi dasar kriptografi: &amp;ldquo;apakah kita dapat membangkitkan bilangan prima raksasa secara cepat dan dengan keyakinan yang pasti&amp;rdquo;.&lt;/p>
&lt;h3 id="72-hubungan-dengan-algoritma-faktorisasi-prima">7.2. Hubungan dengan Algoritma Faktorisasi Prima
&lt;/h3>&lt;p>Pengetahuan tentang distribusi bilangan prima juga mutlak diperlukan ketika mengevaluasi kompleksitas komputasi dari algoritma pihak pemecah sandi (seperti General Number Field Sieve). Banyak algoritma faktorisasi prima bergantung pada distribusi &amp;ldquo;bilangan mulus (Smooth numbers: bilangan yang hanya memiliki faktor prima kecil)&amp;rdquo;.&lt;/p>
&lt;p>Untuk mengevaluasi secara ketat seberapa sering bilangan mulus ini muncul, pemahaman yang mendalam mengenai distribusi bilangan prima sangatlah diperlukan, dan di sinilah teknik teori bilangan analitik yang berhubungan langsung dengan fungsi zeta dan Hipotesis Riemann banyak digunakan. Jika Hipotesis Riemann berhasil dibuktikan, dan batas galat dari distribusi bilangan prima ditetapkan sepenuhnya, maka kita akan mampu mengidentifikasi batas performa algoritma faktorisasi prima secara lebih akurat.&lt;/p>
&lt;hr>
&lt;h1 id="8-jika-hipotesis-riemann-terbukti-apakah-kriptografi-akan-terpecahkan">8. Jika Hipotesis Riemann Terbukti, Apakah Kriptografi Akan Terpecahkan?
&lt;/h1>&lt;p>Terkadang muncul legenda urban yang mengatakan, &amp;ldquo;Jika Hipotesis Riemann terpecahkan, kriptografi RSA akan runtuh seketika&amp;rdquo;, tetapi &lt;strong>secara matematis hal ini tidaklah tepat&lt;/strong>.&lt;/p>
&lt;p>Pembuktian Hipotesis Riemann itu sendiri tidak serta merta akan langsung menghasilkan algoritma ajaib yang mempercepat faktorisasi prima secara drastis. Hipotesis Riemann pada dasarnya adalah teorema tentang &amp;ldquo;keteraturan distribusi bilangan prima secara makroskopis&amp;rdquo;, dan hal ini tidak serta merta memberikan petunjuk langsung tentang bilangan prima manakah yang dapat membagi bilangan $N$ tertentu (sifat secara lokal).&lt;/p>
&lt;p>Namun, dampaknya tidaklah nol.
Sebab, dalam proses pembuktian Hipotesis Riemann, probabilitas ditemukannya &lt;strong>&amp;ldquo;peralatan matematis baru&amp;rdquo; atau &amp;ldquo;metode analisis yang belum pernah diketahui&amp;rdquo;&lt;/strong> sangatlah tinggi. Melihat sejarah ke belakang, ketika Teorema Terakhir Fermat atau Konjektur Poincaré dibuktikan, teori-teori baru yang dikembangkan selama proses tersebut telah mendorong lompatan besar bagi matematika secara keseluruhan.&lt;/p>
&lt;p>Jika suatu metode geometri aljabar atau geometri non-komutatif yang belum diketahui dapat dimantapkan, di mana metode ini bisa mengontrol secara penuh sifat dari pembuat nol fungsi zeta Riemann, bukan tidak mungkin hal itu pada akhirnya berujung pada penemuan algoritma faktorisasi prima yang revolusioner (contohnya, algoritma klasik yang dapat mereduksi kompleksitas komputasi menjadi waktu polinomial). Dalam artian tersebut, para ahli kriptografi tidak pernah bisa memalingkan pandangannya dari perkembangan Hipotesis Riemann.&lt;/p>
&lt;h3 id="komputer-kuantum-dan-algoritma-shor">Komputer Kuantum dan Algoritma Shor
&lt;/h3>&lt;p>Ancaman yang lebih langsung dan nyata bagi teknologi kriptografi bukanlah pembuktian Hipotesis Riemann, melainkan &lt;strong>komputer kuantum&lt;/strong>. &amp;ldquo;Algoritma Shor&amp;rdquo;, yang dipublikasikan oleh Peter Shor pada tahun 1994, membuktikan bahwa jika terdapat komputer kuantum dengan performa yang cukup, faktorisasi prima dapat dipecahkan dalam waktu polinomial. Hal ini secara mendasar akan mematahkan kriptografi RSA maupun kriptografi kurva eliptik.&lt;/p>
&lt;p>Saat ini, transisi menuju &amp;ldquo;Kriptografi Pasca-Kuantum (Post-Quantum Cryptography, PQC)&amp;rdquo; (seperti kriptografi kisi/lattice-based cryptography), yang bahkan tidak dapat dipecahkan oleh komputer kuantum, sedang digalakkan di seluruh dunia. Teknologi kriptografi yang bergantung pada bilangan prima dalam beberapa artian mungkin sedang mendekati akhir masa keemasannya, namun nilai matematis dari bilangan prima itu sendiri tidak akan pernah pudar selamanya.&lt;/p>
&lt;hr>
&lt;h1 id="9-penutup-persimpangan-antara-abstraksi-matematika-dan-dunia-nyata">9. Penutup: Persimpangan Antara Abstraksi Matematika dan Dunia Nyata
&lt;/h1>&lt;div class="mermaid">graph TD
A["Eksplorasi Matematika Murni"] --> B["Pengungkapan Hipotesis Riemann"]
B --> C["Pemahaman Sempurna atas Distribusi Bilangan Prima"]
C --> D["Perkembangan Pesat pada Teori Bilangan dan Geometri Aljabar"]
D -.-> E["Kemungkinan Algoritma Faktorisasi Prima yang Baru"]
E -.-> F["Pembaruan Evaluasi Keamanan Teknologi Kriptografi"]
A --> G["Matematika Terapan dan Ilmu Komputer"]
G --> H["Efisiensi Pengujian Keprimaan dan Pembangkitan Kriptografi"]
H --> F&lt;/div>
&lt;p>Pencarian tiada henti akan bilangan prima yang telah berlangsung sejak zaman Yunani Kuno, melalui tangan jenius bernama Riemann, disublimasikan menjadi sebuah simfoni yang indah di atas bidang kompleks (yaitu pembuat nol fungsi zeta). Dan yang sangat menakjubkan, kristalisasi dari matematika yang murni ini, melintasi waktu berabad-abad, kini diaplikasikan sebagai tameng terkuat yang menjamin keamanan masyarakat internet.&lt;/p>
&lt;p>Hipotesis Riemann adalah sebuah eksistensi yang secara bersamaan menyimbolkan &amp;ldquo;keindahan yang abstrak&amp;rdquo; yang dimiliki matematika dan &amp;ldquo;daya aplikatifnya yang menakjubkan terhadap dunia fisik serta masyarakat nyata&amp;rdquo;.&lt;/p>
&lt;p>Kelak suatu hari, ketika puncak gunung raksasa matematika yang belum pernah ditaklukkan oleh siapa pun ini berhasil didaki, kita tidak hanya akan memahami secara utuh kebenaran semesta dari bilangan prima, tetapi juga akan mendapatkan sudut pandang yang sama sekali baru mengenai landasan dari masyarakat informasi ini. Pada akhirnya, mempelajari teknologi kriptografi juga berarti menelusuri sejarah kebijaksanaan umat manusia itu sendiri.&lt;/p></description></item><item><title>Algoritma Pengujian Keprimaan Cepat Diimplementasikan dalam C++ (Metode Miller-Rabin, dll.)</title><link>http://kenji.blog/id/p/cpp-fast-prime-testing-miller-rabin/</link><pubDate>Fri, 11 Sep 2026 14:00:00 +0900</pubDate><guid>http://kenji.blog/id/p/cpp-fast-prime-testing-miller-rabin/</guid><description>&lt;img src="http://kenji.blog/p/cpp-fast-prime-testing-miller-rabin/img/eyecatch.jpg" alt="Featured image of post Algoritma Pengujian Keprimaan Cepat Diimplementasikan dalam C++ (Metode Miller-Rabin, dll.)" />&lt;h1 id="pendahuluan-mengapa-pengujian-keprimaan-yang-cepat-diperlukan">Pendahuluan: Mengapa Pengujian Keprimaan yang Cepat Diperlukan?
&lt;/h1>&lt;p>Dalam ilmu komputer, kriptografi, atau pemrograman kompetitif, menentukan secara cepat dan akurat &amp;ldquo;apakah suatu bilangan adalah bilangan prima&amp;rdquo; merupakan tugas yang sangat penting dan mendasar. Misalnya, kriptografi kunci publik seperti RSA, yang mendasari keamanan masyarakat internet modern, mendasarkan keamanannya pada pembuatan bilangan prima yang besar dan kesulitan mengalikannya (kesulitan faktorisasi prima). Oleh karena itu, teknologi untuk secara instan membedakan apakah bilangan yang sangat besar adalah bilangan prima atau bukan, bisa dikatakan sebagai teknologi yang menopang fondasi masyarakat digital.&lt;/p>
&lt;p>Selain itu, dalam pemrograman kompetitif (seperti AtCoder atau Codeforces), pengujian keprimaan adalah tema yang sering muncul. Untuk input besar dengan batasan seperti $N \le 10^{18}$, dalam situasi di mana puluhan ribu uji keprimaan perlu dilakukan dalam waktu 1 detik, algoritma tradisional dan naif tidak akan pernah bisa memenuhi batas waktu (Time Limit Exceeded: TLE).&lt;/p>
&lt;p>Artikel ini akan membahas secara menyeluruh, mulai dari latar belakang matematika hingga implementasi yang sangat dioptimalkan dalam C++, dari algoritma pengujian keprimaan naif, lalu &amp;ldquo;Uji Fermat&amp;rdquo; yang merupakan metode pengujian keprimaan probabilistik, dan algoritma pengujian sangat cepat tingkat paling praktis yang mengatasi kelemahannya: &amp;ldquo;Uji Keprimaan Miller-Rabin&amp;rdquo;. Khususnya untuk bilangan bulat 64-bit ($N &lt; 2^{64}$), artikel ini akan menjelaskan secara rinci bukan hanya pengujian probabilistik tetapi juga metode untuk &amp;ldquo;100% pasti melakukan pengujian keprimaan (pengujian deterministik)&amp;rdquo;, dan menyediakan kode sumber C++ yang dapat langsung digunakan dalam praktik.&lt;/p>
&lt;hr>
&lt;h1 id="1-dasar-dasar-pengujian-keprimaan-dan-pembagian-coba-coba-trial-division">1. Dasar-dasar Pengujian Keprimaan dan Pembagian Coba-coba (Trial Division)
&lt;/h1>&lt;p>Bilangan prima (Prime number) adalah bilangan asli lebih besar dari 1 yang tidak memiliki pembagi positif selain 1 dan dirinya sendiri. Mengikuti definisi bilangan prima secara ketat, untuk menguji apakah suatu bilangan bulat $N$ adalah bilangan prima, kita bisa membagi $N$ dengan semua bilangan bulat dari $2$ hingga $N-1$. Jika tidak pernah habis dibagi, maka ia adalah bilangan prima; jika habis dibagi walau hanya sekali, maka ia adalah bilangan komposit (bukan bilangan prima).&lt;/p>
&lt;p>Namun, metode ini memiliki kompleksitas waktu $O(N)$. Jika $N$ adalah bilangan besar seperti $10^{18}$, bahkan komputer modern pun akan membutuhkan waktu yang sangat lama untuk menghitungnya.&lt;/p>
&lt;h2 id="optimasi-pembagian-coba-coba-pencarian-hingga-sqrtn">Optimasi Pembagian Coba-coba: Pencarian hingga $\sqrt{N}$
&lt;/h2>&lt;p>Ketika bilangan komposit $N$ dinyatakan sebagai $a \times b = N$ ($a \le b$), maka selalu berlaku $a \le \sqrt{N}$. Oleh karena itu, loop pengujian keprimaan tidak perlu dijalankan hingga $N-1$; cukup memeriksa hingga $\sqrt{N}$ sudah memadai.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Uji keprimaan dengan pembagian coba-coba (O(sqrt(N)))
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kt">bool&lt;/span> &lt;span class="nf">is_prime_trial_division&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">2&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="nb">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="mi">2&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Hanya periksa bilangan ganjil 3 atau lebih
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nb">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Kompleksitas waktu dari algoritma ini adalah $O(\sqrt{N})$. Jika $N \le 10^{12}$, ia dapat dihitung dalam sekejap, tetapi jika $N \approx 10^{18}$, jumlah perulangan menjadi sekitar $10^9$ kali, dan bahkan implementasi C++ membutuhkan waktu ratusan milidetik hingga beberapa detik, membuatnya tidak cocok untuk evaluasi berulang.&lt;/p>
&lt;hr>
&lt;h1 id="2-uji-fermat-awal-dari-pengujian-keprimaan-probabilistik">2. Uji Fermat: Awal dari Pengujian Keprimaan Probabilistik
&lt;/h1>&lt;p>Untuk mengatasi batasan metode pembagian coba-coba, &amp;ldquo;Algoritma Probabilistik (Probabilistic Algorithm)&amp;rdquo; menggunakan teorema teori bilangan dirancang. Perwakilan dari ini adalah &amp;ldquo;Uji Keprimaan Fermat (Fermat Primality Test)&amp;rdquo;, yang menggunakan Teorema Kecil Fermat.&lt;/p>
&lt;h2 id="teorema-kecil-fermat-fermats-little-theorem">Teorema Kecil Fermat (Fermat&amp;rsquo;s Little Theorem)
&lt;/h2>&lt;p>Teorema yang ditemukan oleh Pierre de Fermat ini menyatakan sebagai berikut.&lt;/p>
&lt;blockquote>
&lt;p>Untuk sembarang bilangan prima $p$ dan sembarang bilangan bulat $a$ yang koprima dengannya (bukan kelipatan $p$), kongruensi berikut berlaku.
&lt;/p>
$$ a^{p-1} \equiv 1 \pmod p $$
&lt;/blockquote>
&lt;p>Mengambil kontraposisi dari teorema ini, kita dapat mengatakan bahwa &amp;ldquo;Untuk suatu bilangan bulat $N$ dan bilangan bulat $a$ yang koprima dengan $N$, jika $a^{N-1} \not\equiv 1 \pmod N$, maka $N$ pasti bilangan komposit&amp;rdquo;. Menggunakan properti ini, Uji Fermat memilih basis (base) acak $a$ untuk bilangan $N$ yang akan diuji, lalu menghitung $a^{N-1} \pmod N$ dan memeriksa apakah hasilnya $1$.&lt;/p>
&lt;h2 id="eksponensiasi-modular-cepat-exponentiation-by-squaring">Eksponensiasi Modular Cepat (Exponentiation by Squaring)
&lt;/h2>&lt;p>Untuk melakukan Uji Fermat, perhitungan eksponensiasi yang besar $a^{N-1} \pmod N$ harus dihitung dengan cepat. &amp;ldquo;Eksponensiasi Modular (Modular Exponentiation / Binary Exponentiation)&amp;rdquo; digunakan untuk ini. Kompleksitas waktunya adalah $O(\log N)$, membuatnya sangat cepat.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Menghitung a^b mod m menggunakan eksponensiasi modular
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="nf">mod_pow&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">res&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">a&lt;/span> &lt;span class="o">%=&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">b&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">b&lt;/span> &lt;span class="o">&amp;amp;&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="n">res&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">__int128_t&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="n">res&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">__int128_t&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="n">a&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">b&lt;/span> &lt;span class="o">&amp;gt;&amp;gt;=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">res&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;ul>
&lt;li>Di sini, untuk mencegah overflow, perkalian perantara dipertahankan menggunakan ekstensi GCC/Clang &lt;code>__int128_t&lt;/code> (bilangan bulat 128-bit).&lt;/li>
&lt;/ul>
&lt;h2 id="pseudoprima-dan-bilangan-carmichael-carmichael-numbers">Pseudoprima dan Bilangan Carmichael (Carmichael Numbers)
&lt;/h2>&lt;p>Uji Fermat sangat kuat, tetapi memiliki kelemahan yang fatal. Artinya, ada bilangan sedemikian rupa sehingga meskipun $N$ adalah komposit, $a^{N-1} \equiv 1 \pmod N$ berlaku untuk semua $a$ ($a$ koprima dengan $N$).&lt;/p>
&lt;p>Bilangan semacam itu disebut &amp;ldquo;pseudoprima absolut (absolute pseudoprimes)&amp;rdquo; atau &amp;ldquo;Bilangan Carmichael&amp;rdquo;. Bilangan Carmichael terkecil adalah $561 = 3 \times 11 \times 17$.
Karena adanya bilangan Carmichael, pengujian deterministik dengan &amp;ldquo;probabilitas 100%&amp;rdquo; tidak mungkin dilakukan hanya dengan Uji Fermat. Tidak peduli berapa banyak nilai $a$ berbeda yang dicoba, bilangan seperti $561$ akan selalu berpura-pura menjadi bilangan prima.&lt;/p>
&lt;hr>
&lt;h1 id="3-uji-keprimaan-miller-rabin-miller-rabin-primality-test">3. Uji Keprimaan Miller-Rabin (Miller-Rabin Primality Test)
&lt;/h1>&lt;p>&amp;ldquo;Uji Keprimaan Miller-Rabin&amp;rdquo;, yang dirancang oleh Gary L. Miller dan Michael O. Rabin, dengan luar biasa mengatasi kelemahan Uji Fermat (adanya bilangan Carmichael).
Saat ini, ini paling banyak digunakan sebagai algoritma pengujian keprimaan berkecepatan tinggi yang praktis dalam perpustakaan internal berbagai bahasa pemrograman dan pembuatan kunci dalam sistem kriptografi.&lt;/p>
&lt;h2 id="prinsip-matematika">Prinsip Matematika
&lt;/h2>&lt;p>Selain Teorema Kecil Fermat, algoritma Miller-Rabin menggunakan properti bahwa &amp;ldquo;dalam bidang sisa (residual field) modulo bilangan prima ($\mathbb{Z}/p\mathbb{Z}$), solusi dari $x^2 \equiv 1 \pmod p$ terbatas pada $x \equiv 1$ atau $x \equiv -1$&amp;rdquo; (jika modulo bilangan komposit, mungkin ada akar kuadrat non-trivial lainnya).&lt;/p>
&lt;p>Jika Anda mengurangi $1$ dari bilangan ganjil $N$ yang akan diuji, $N-1$ selalu menjadi genap. Oleh karena itu, $N-1$ dibagi dengan $2$ sebanyak mungkin, dan dinyatakan dalam bentuk berikut.
&lt;/p>
$$ N-1 = d \cdot 2^s $$
&lt;p>
(Di mana $d$ ganjil dan $s \ge 1$)&lt;/p>
&lt;p>Untuk basis acak $a$ ($1 &lt; a &lt; N-1$), diverifikasi apakah $a^{N-1} \equiv 1 \pmod N$ sesuai dengan Teorema Kecil Fermat, tetapi perhitungannya dilakukan secara bertahap.
Secara khusus, ini terus mengkuadratkan dalam urutan: $a^d, a^{d \cdot 2}, a^{d \cdot 4}, \ldots, a^{d \cdot 2^s}$.&lt;/p>
&lt;p>Kondisi agar Uji Miller-Rabin menentukan $N$ sebagai &amp;ldquo;prima (atau kemungkinkan besar prima)&amp;rdquo; adalah jika &lt;strong>salah satu&lt;/strong> dari hal berikut berlaku.&lt;/p>
&lt;ol>
&lt;li>$a^d \equiv 1 \pmod N$&lt;/li>
&lt;li>Terdapat suatu $r$ ($0 \le r &lt; s$) sedemikian rupa sehingga $a^{d \cdot 2^r} \equiv -1 \pmod N$.
&lt;ul>
&lt;li>Dalam aritmatika modulo C++, $-1 \pmod N$ adalah $N-1$.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;p>Jika $N$ adalah bilangan prima, kondisi ini pasti akan dipenuhi untuk sembarang $a$. Sebaliknya, jika $N$ adalah bilangan komposit, secara matematis terbukti bahwa ketika $a$ acak dipilih, probabilitas bahwa kondisi ini terpenuhi (probabilitas tertipu) kurang dari $\frac{1}{4}$.
Dengan $k$ pengujian independen, probabilitas positif palsu menjadi kurang dari $\left(\frac{1}{4}\right)^k$, yang pada praktiknya dapat dianggap nol. Tidak ada bilangan yang &amp;ldquo;benar-benar bisa menipu&amp;rdquo; seperti bilangan Carmichael.&lt;/p>
&lt;h2 id="alur-algoritma-metode-miller-rabin-flowchart-mermaid">Alur Algoritma Metode Miller-Rabin (Flowchart Mermaid)
&lt;/h2>&lt;p>Gambar di bawah ini menunjukkan alur logika dari satu uji Miller-Rabin (uji untuk satu basis $a$).&lt;/p>
&lt;div class="mermaid">graph TD
Start["Mulai pengujian (Input: N, a)"] --> CalcDS["Hitung d (ganjil) dan s sedemikian sehingga N-1 = d * 2^s"]
CalcDS --> CalcX["Hitung x = a^d mod N"]
CalcX --> CheckX1{"x == 1 atau x == N-1 ?"}
CheckX1 -- "Ya" --> ReturnTrue["Kemungkinan Prima (Probably Prime)"]
CheckX1 -- "Tidak" --> LoopStart["Mulai loop dari r = 1 hingga s-1"]
LoopStart --> LoopCondition{"r &lt; s ?"}
LoopCondition -- "Tidak" --> ReturnFalse["Pasti Komposit (Composite)"]
LoopCondition -- "Ya" --> SquareX["Hitung x = (x * x) mod N"]
SquareX --> CheckXMinus1{"x == N - 1 ?"}
CheckXMinus1 -- "Ya" --> ReturnTrue
CheckXMinus1 -- "Tidak" --> CheckXOne{"x == 1 ?"}
CheckXOne -- "Ya" --> ReturnFalse
CheckXOne -- "Tidak" --> LoopNext["Tingkatkan r sebanyak 1 lalu lanjut"]
LoopNext --> LoopCondition&lt;/div>
&lt;hr>
&lt;h1 id="4-pengujian-deterministik-untuk-bilangan-bulat-64-bit">4. Pengujian Deterministik untuk Bilangan Bulat 64-bit
&lt;/h1>&lt;p>Meskipun Uji Keprimaan Miller-Rabin pada asalnya adalah algoritma &amp;ldquo;probabilistik&amp;rdquo;, saat batasan atas $N$ tetap, kita dapat melakukan pengujian keprimaan &amp;ldquo;100% pasti&amp;rdquo; dengan mencoba sekumpulan spesifik $a$ (basis).
Ini disebut &lt;strong>Uji Miller-Rabin Deterministik (Deterministic Miller-Rabin Test)&lt;/strong>.&lt;/p>
&lt;p>Penelitian oleh Jim Sinclair dan lainnya telah menunjukkan bahwa untuk semua bilangan bulat $N &lt; 2^{64}$ (sekitar $1.8 \times 10^{19}$), pengujian yang cukup dan sepenuhnya deterministik dapat dicapai dengan menguji menggunakan $7$ bilangan prima berikut sebagai basis $a$.&lt;/p>
&lt;p>&lt;strong>Daftar basis $a$ yang akan diuji:&lt;/strong>
&lt;code>{2, 325, 9375, 28178, 450775, 9780504, 1795265022}&lt;/code>&lt;/p>
&lt;p>Sebagai alternatif, pengujian sempurna untuk $N &lt; 2^{64}$ dapat dilakukan dengan kumpulan yang banyak diketahui dengan menggunakan $12$ bilangan prima berikut.
&lt;code>{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}&lt;/code>&lt;/p>
&lt;p>Kali ini, untuk meningkatkan kesederhanaan dan keandalan algoritma, kita akan menggunakan pendekatan yang memakai $12$ bilangan prima tersebut sebagai basis (atau pendekatan $7$ basis yang lebih optimal). Dalam implementasi C++, kita akan melakukan optimasi untuk meminimalkan jumlah tes dengan memisahkan rentang menggunakan pencabangan kondisi.&lt;/p>
&lt;hr>
&lt;h1 id="5-implementasi-tingkat-lanjut-di-c-highly-optimized-c-implementation">5. Implementasi Tingkat Lanjut di C++ (Highly Optimized C++ Implementation)
&lt;/h1>&lt;p>Sekarang, mari satukan teori matematika dan desain algoritma dari penjelasan di atas, dan menyajikan kode implementasi fungsi pengujian keprimaan Miller-Rabin tingkat paling kuat di C++ modern.&lt;/p>
&lt;h2 id="poin-penting-implementasi">Poin Penting Implementasi
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>&lt;strong>Menghindari Overflow pada Perkalian Bilangan Bulat 64-bit:&lt;/strong>
Ketika $N \approx 10^{18}$, nilai dari $x \times x$ dalam perkalian modulo dapat mencapai hingga $10^{36}$, yang dengan mudah melewati nilai maksimum dari bilangan bulat 64-bit standar (&lt;code>uint64_t&lt;/code> atau &lt;code>long long&lt;/code>), yaitu $1.8 \times 10^{19}$.
Untuk mengatasi masalah ini, kita menggunakan tipe data diperluas dari GCC dan Clang, yaitu &lt;code>__int128_t&lt;/code> (atau &lt;code>unsigned __int128&lt;/code>), dan setelah menghitung dengan akurasi 128-bit, kita akan memodulokannya. Ini memungkinkan perkalian sisa yang cepat tanpa menggunakan algoritma kompleks.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Pemilihan Basis Deterministik:&lt;/strong>
Ketika nilai $N$ kecil, kita mengoptimalkannya sehingga hanya sedikit basis (base) yang perlu diuji.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="kode-sumber-c-lengkap">Kode Sumber C++ Lengkap
&lt;/h2>&lt;p>Berikut adalah kode sumber versi lengkap yang siap digunakan dalam praktiknya. Kode ini dapat langsung disalin dan digunakan dalam lingkungan seperti pemrograman kompetitif.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;span class="lnt">48
&lt;/span>&lt;span class="lnt">49
&lt;/span>&lt;span class="lnt">50
&lt;/span>&lt;span class="lnt">51
&lt;/span>&lt;span class="lnt">52
&lt;/span>&lt;span class="lnt">53
&lt;/span>&lt;span class="lnt">54
&lt;/span>&lt;span class="lnt">55
&lt;/span>&lt;span class="lnt">56
&lt;/span>&lt;span class="lnt">57
&lt;/span>&lt;span class="lnt">58
&lt;/span>&lt;span class="lnt">59
&lt;/span>&lt;span class="lnt">60
&lt;/span>&lt;span class="lnt">61
&lt;/span>&lt;span class="lnt">62
&lt;/span>&lt;span class="lnt">63
&lt;/span>&lt;span class="lnt">64
&lt;/span>&lt;span class="lnt">65
&lt;/span>&lt;span class="lnt">66
&lt;/span>&lt;span class="lnt">67
&lt;/span>&lt;span class="lnt">68
&lt;/span>&lt;span class="lnt">69
&lt;/span>&lt;span class="lnt">70
&lt;/span>&lt;span class="lnt">71
&lt;/span>&lt;span class="lnt">72
&lt;/span>&lt;span class="lnt">73
&lt;/span>&lt;span class="lnt">74
&lt;/span>&lt;span class="lnt">75
&lt;/span>&lt;span class="lnt">76
&lt;/span>&lt;span class="lnt">77
&lt;/span>&lt;span class="lnt">78
&lt;/span>&lt;span class="lnt">79
&lt;/span>&lt;span class="lnt">80
&lt;/span>&lt;span class="lnt">81
&lt;/span>&lt;span class="lnt">82
&lt;/span>&lt;span class="lnt">83
&lt;/span>&lt;span class="lnt">84
&lt;/span>&lt;span class="lnt">85
&lt;/span>&lt;span class="lnt">86
&lt;/span>&lt;span class="lnt">87
&lt;/span>&lt;span class="lnt">88
&lt;/span>&lt;span class="lnt">89
&lt;/span>&lt;span class="lnt">90
&lt;/span>&lt;span class="lnt">91
&lt;/span>&lt;span class="lnt">92
&lt;/span>&lt;span class="lnt">93
&lt;/span>&lt;span class="lnt">94
&lt;/span>&lt;span class="lnt">95
&lt;/span>&lt;span class="lnt">96
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;vector&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;cstdint&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;initializer_list&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="k">namespace&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// (a * b) mod m yang cepat dengan bilangan bulat 128-bit
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kr">inline&lt;/span> &lt;span class="kt">uint64_t&lt;/span> &lt;span class="nf">mod_mul&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">uint64_t&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">uint64_t&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">uint64_t&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">uint64_t&lt;/span>&lt;span class="p">)((&lt;/span>&lt;span class="kt">unsigned&lt;/span> &lt;span class="n">__int128&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="n">a&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">b&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Menghitung (base^exp) mod m menggunakan eksponensiasi modular
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kt">uint64_t&lt;/span> &lt;span class="nf">mod_pow&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">uint64_t&lt;/span> &lt;span class="n">base&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">uint64_t&lt;/span> &lt;span class="n">exp&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">uint64_t&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">uint64_t&lt;/span> &lt;span class="n">res&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">base&lt;/span> &lt;span class="o">%=&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">exp&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">exp&lt;/span> &lt;span class="o">&amp;amp;&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="n">res&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mod_mul&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">res&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">base&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">base&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mod_mul&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">base&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">base&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">exp&lt;/span> &lt;span class="o">&amp;gt;&amp;gt;=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">res&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Pengujian deterministik bilangan bulat 64bit menggunakan metode pengujian keprimaan Miller-Rabin
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kt">bool&lt;/span> &lt;span class="nf">is_prime_miller_rabin&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">uint64_t&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Pengecekan awal untuk nilai batas dan bilangan prima kecil
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">2&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">3&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">5&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">7&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="nb">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="mi">2&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="mi">3&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="mi">5&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="mi">7&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Faktorisasi n-1 menjadi bentuk d * 2^s
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">uint64_t&lt;/span> &lt;span class="n">d&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">s&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="p">((&lt;/span>&lt;span class="n">d&lt;/span> &lt;span class="o">&amp;amp;&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">d&lt;/span> &lt;span class="o">&amp;gt;&amp;gt;=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">s&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Daftar basis yang digunakan untuk pengujian
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// Optimasi untuk meminimalkan jumlah basis yang diuji berdasarkan ukuran N
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">uint64_t&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">bases&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="mi">4759123141ULL&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">bases&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">7&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">61&lt;/span>&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span> &lt;span class="k">else&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="mi">1122004669633ULL&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">bases&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">13&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">23&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1662803&lt;/span>&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span> &lt;span class="k">else&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 7 basis yang bersifat deterministik untuk semua bilangan N &amp;lt; 2^64
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">bases&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">325&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">9375&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">28178&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">450775&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">9780504&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1795265022&lt;/span>&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Jalankan pengujian untuk setiap basis
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">uint64_t&lt;/span> &lt;span class="nl">a&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">bases&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">a&lt;/span> &lt;span class="o">%=&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">continue&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// Jika a kelipatan n, tak bisa diuji tapi ia bukan prima
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">uint64_t&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mod_pow&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">d&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">1&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">continue&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// Kondisi 1 terpenuhi, lanjut ke basis berikutnya
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">bool&lt;/span> &lt;span class="n">composite&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Loop sebanyak s-1 kali (x = x^2 mod n)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">r&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">r&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">s&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">r&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">x&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mod_mul&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">composite&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// Kondisi 2 terpenuhi, kemungkinan prima
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">break&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Pasti komposit jika tak satu pun kondisi yang terpenuhi
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">composite&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Pasti prima jika lolos kondisi di semua basis
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="nb">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">int&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Sampel uji coba
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">uint64_t&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">test_cases&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="mi">1000000007&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// Bilangan prima yang terkenal
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="mi">998244353&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// Bilangan prima yang terkenal
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="mi">1000000000000000003&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// Prima di sekitar 10^18
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="mi">1000000000000000007&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// Bilangan komposit (10^18 + 7)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="mi">561&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// Bilangan Carmichael (Bilangan komposit)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="mi">18446744073709551557ULL&lt;/span> &lt;span class="c1">// Salah satu bilangan prima terbesar di sekitar 2^64
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">uint64_t&lt;/span> &lt;span class="nl">n&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">test_cases&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34; is &amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">is_prime_miller_rabin&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">?&lt;/span> &lt;span class="s">&amp;#34;Prime&amp;#34;&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s">&amp;#34;Composite&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h1 id="6-kompleksitas-algoritma-dan-evaluasi-performa">6. Kompleksitas Algoritma dan Evaluasi Performa
&lt;/h1>&lt;p>Mari bahas performa dari algoritma yang diimplementasikan.&lt;/p>
&lt;h2 id="kompleksitas-waktu-time-complexity">Kompleksitas Waktu (Time Complexity)
&lt;/h2>&lt;ul>
&lt;li>&lt;strong>Pembagian Coba-coba:&lt;/strong> $O(\sqrt{N})$&lt;/li>
&lt;li>&lt;strong>Uji Fermat:&lt;/strong> Penghitungan pangkat $O(\log N) \times k$ ($k$ adalah jumlah percobaan)&lt;/li>
&lt;li>&lt;strong>Metode Miller-Rabin:&lt;/strong> Penghitungan pangkat dan loop $O(\log N) \times k$&lt;/li>
&lt;/ul>
&lt;p>Pada lingkungan 64-bit ($N \le 2^{64}$), metode Miller-Rabin deterministik di atas memeriksa paling banyak hanya $7$ basis. Oleh karena itu, kita dapat menganggap $k \le 7$ sebagai konstanta, dan keseluruhan kompleksitas waktu secara ketat adalah $O(\log N)$.
Bahkan untuk kasus maksimum ($N \approx 10^{19}$), jumlah eksekusi langkah tertahan pada maksimum $7 \times 64 = 448$ operasi dasar, dan waktu eksekusi kurang dari beberapa mikrodetik ($10^{-6}$ detik). Dibandingkan dengan $O(\sqrt{N})$ dari metode pembagian coba-coba (jumlah perulangan $\approx 4 \times 10^9$ kali), peningkatan kecepatannya mencapai &lt;strong>jutaan kali&lt;/strong>.&lt;/p>
&lt;h2 id="optimasi-lebih-lanjut-perkalian-montgomery-montgomery-multiplication">Optimasi Lebih Lanjut: Perkalian Montgomery (Montgomery Multiplication)
&lt;/h2>&lt;p>Dalam implementasi artikel ini, kita menggunakan tipe data diperluas &lt;code>__int128_t&lt;/code> untuk bilangan bulat 128-bit dalam melakukan pembagian (operasi modulo &lt;code>%&lt;/code>). Bahkan pada CPU modern, operasi pembagian bilangan bulat (instruksi DIV) adalah operasi berbiaya tinggi yang membutuhkan puluhan siklus dibandingkan dengan penambahan atau perkalian.&lt;/p>
&lt;p>Pembuat pustaka dan pemrogram kompetitif yang mencari optimasi batas maksimal kadang menerapkan metode yang disebut &lt;strong>Perkalian Montgomery (Montgomery Multiplication)&lt;/strong>. Perkalian Montgomery adalah algoritma luar biasa yang menggantikan operasi modulo berbiaya tinggi (pembagian) dengan &amp;ldquo;hanya pergeseran bit dan perkalian&amp;rdquo; dengan memetakan angka ke &amp;ldquo;ruang Montgomery&amp;rdquo; khusus.
Dengan menyematkan fungsi ini ke dalam perkalian modular uji Miller-Rabin, kecepatan eksekusi dapat ditingkatkan lebih jauh sekitar dua hingga tiga kali lipat. Karena topik ini sangat mendalam, kita akan membahasnya lebih rinci dalam artikel terpisah.&lt;/p>
&lt;hr>
&lt;h1 id="7-kesimpulan">7. Kesimpulan
&lt;/h1>&lt;p>Artikel ini telah merangkum penjelasan lengkap mengenai pengujian keprimaan, mulai dari prinsip dasar hingga lanjutan.
Mari kita lihat kembali poin-poin utamanya.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Metode pembagian coba-coba&lt;/strong> sangat pasti, tetapi karena kompleksitas perhitungannya adalah $O(\sqrt{N})$, itu tidak praktis ketika $N$ lebih besar dari $10^{12}$.&lt;/li>
&lt;li>&lt;strong>Uji Fermat&lt;/strong> sangat cepat dengan $O(\log N)$, tetapi memiliki kelemahan fatal yaitu bisa tertipu oleh pseudoprima absolut seperti bilangan Carmichael.&lt;/li>
&lt;li>&lt;strong>Uji Keprimaan Miller-Rabin&lt;/strong> memecahkan kelemahan dari Uji Fermat, dan ini adalah algoritma paling kuat dan praktis.&lt;/li>
&lt;li>Dalam implementasi C++, kita dapat menangani overflow secara aman dalam perkalian 64-bit menggunakan &lt;code>__int128_t&lt;/code>.&lt;/li>
&lt;li>Selama bilangan bulat berada dalam rentang 64-bit ($N &lt; 2^{64}$), kita bisa membuat algoritmanya menjadi &lt;strong>deterministik (100% akurat) dan bukan probabilistik&lt;/strong> dengan memilih sekumpulan tertentu $7$ atau $12$ bilangan prima sebagai basis.&lt;/li>
&lt;/ol>
&lt;p>Pengujian keprimaan berkecepatan tinggi adalah teknik yang tak terhindarkan saat melakukan komputasi yang menangani angka sangat besar. Kode sumber Miller-Rabin di C++ yang disediakan dalam artikel ini terbukti kuat untuk diterapkan langsung di praktik. Silakan gunakan untuk proyek atau kompetisi algoritma Anda sendiri.&lt;/p>
&lt;div class="mermaid">graph LR
TrialDivision["Pembagian Coba-coba (O(√N))"] --> Fermat["Uji Fermat (O(log N), punya kelemahan)"]
Fermat --> MillerRabin["Metode Miller-Rabin (O(log N), dapat dideterministikkan)"]
MillerRabin --> Montgomery["+ Perkalian Montgomery (Peningkatan kecepatan konstanta)"]
style MillerRabin fill:#f9f,stroke:#333,stroke-width:2px&lt;/div>
&lt;p>Dunia algoritma tempat pemrograman dan matematika saling berpapasan sangat indah dan dalam. Semoga artikel ini bisa membantu proses belajar Anda.&lt;/p>
&lt;hr>
&lt;p>&lt;em>Referensi:&lt;/em>&lt;/p>
&lt;ul>
&lt;li>&lt;em>Pomerance, C., Selfridge, J. L., &amp;amp; Wagstaff, S. S. (1980). The pseudoprimes to 25.10^9. Mathematics of Computation.&lt;/em>&lt;/li>
&lt;li>&lt;em>Sinclair, J. (2011). Deterministic Miller-Rabin primality testing.&lt;/em>&lt;/li>
&lt;/ul></description></item></channel></rss>