Rand Protocol
Dokumentasi
Panduan

Cara Kerja zkVM

Bagaimana Rand membuktikan bahwa suatu program berjalan dengan benar tanpa memperlihatkan inputnya - mesin RISC-V, jejak eksekusi yang dibagi menjadi sembilan tabel, bus yang menghubungkannya, aturan sebagai identitas polinomial, komitmen, FRI, Fiat-Shamir, dari mana zero knowledge berasal, apa yang diperiksa oleh validator, dan mengapa setiap parameter FRI dan hash memiliki nilai seperti adanya.

Baca halaman ini untuk memahami mesin di balik setiap bukti di Rand: apa yang dibuktikannya, bagaimana satu kali eksekusi program menjadi sesuatu yang dapat diperiksa validator dalam hitungan milidetik, dan dari mana privasi berasal. Untuk biaya sebuah bukti dan cara wallet membuatnya, lihat Proofs. Untuk parameter dan konstruksi hash, lihat Cryptography. Untuk set instruksi yang menjadi acuan penulisan program, lihat The RISC-V ISA.

Satu pernyataan yang dibuat setiap bukti

zkVM membuktikan satu jenis pernyataan, untuk setiap program yang dijalankan chain:

Sebuah program yang digest-nya hc, dimulai pada base_pc, dijalankan pada input privat yang di-commit oleh H_IN dan segmen input publik yang di-commit oleh H_PUB, berhenti dalam 2ᵗ − 1 siklus, menghabiskan gas paling banyak GAS_LIMIT, dan menulis delapan kata keluaran ini.

Sebuah transfer shielded adalah pernyataan itu tentang satu program tetap, yaitu hidden-asset bundle guest, yang hc-nya dipatok dalam file genesis sebagai hc_bundle. Sejak chain 17, pernyataan itu dibuat dua kali per transfer: bukti kedua yang kecil tentang auth guest (hc_auth dalam file genesis) menunjukkan bahwa pengirim memegang spend key (Proofs). Sebuah panggilan rahasia adalah pernyataan yang sama tentang program yang telah di-deploy. Hanya ada satu mesin, satu verifier, dan satu set constraint untuk semuanya. Karena itu, men-deploy program merupakan operasi data (menyimpan kata-katanya dan hc), bukan operasi kriptografis: tidak ada sirkuit per program dan tidak ada trusted setup.

Sistem pembuktiannya adalah STARK yang dibangun dengan Plonky3. Sistem ini tidak membutuhkan apa pun selain fungsi hash: tanpa upacara setup dan tanpa kurva eliptik, sehingga tidak ada yang dapat dipecahkan oleh algoritma Shor.

Alur kerja

 secret input ──► run the program ──► execution trace ──► polynomials ──► commit ──► FRI ──► proof
 (keys,           (RV32IM emulator)   (nine tables,      (one per       (8× code,   (80 queries,
  notes, paths)                        one row per step)  column)        Merkle)     20-bit grinding)

 every validator:  recompute the challenges from the Merkle roots, open 80 random positions,
                   check the rules there  →  ≈ 16 ms

Baris atas dijalankan satu kali, di mesin pengirim, dalam sekitar 100 detik untuk sebuah bundle dan sekitar 7 detik untuk bukti otorisasi yang menyertainya. Baris bawah dijalankan di setiap validator, hanya dari field publik dan bukti.

1. Jalankan program dan catat semuanya

Mesinnya adalah prosesor RISC-V 32-bit: RV32IM dikurangi FENCE, instruksi CSR, dan EBREAK (The RISC-V ISA). Prover pertama-tama menjalankan program pada sebuah emulator dan mencatat satu baris per detak clock. Catatan itu adalah execution trace. Siapa pun yang memegangnya dapat memutar ulang eksekusi langkah demi langkah; seluruh skema selebihnya ada agar verifier dapat diyakinkan bahwa trace itu benar tanpa memegangnya.

Sebuah program berhubungan dengan dunia luar melalui delapan syscall dan tidak ada yang lain:

syscallno.fungsinya
HALT0berhenti; kedelapan kata keluaran menjadi final
WRITE_OUTPUT1menetapkan salah satu dari delapan kata keluaran publik
READ_INPUT2membaca satu kata dari input privat
POSEIDON23meng-hash sebuah buffer di memori secara in-place
KECCAK4satu permutasi Keccak-f[1600]
SHA2565satu kompresi SHA-256
READ_PUBLIC6membaca satu kata dari segmen input publik
POSEIDON2_LEN7POSEIDON2 dengan panjang pesan terikat ke dalam hash (constraint set 7)

Komitmen note, nullifier, dan jalur Merkle tidak dibangun ke dalam mesin. Semuanya adalah kode guest biasa yang menyiapkan pesan bertag domain di memori lalu memanggil POSEIDON2. Syscall itu tidak melakukan padding, sehingga [a] dan [a, 0] menghasilkan hash yang sama. Guest yang disertakan hanya memanggilnya pada pesan dengan panjang tetap. Program baru yang meng-hash data dengan panjang yang dapat bervariasi menggunakan POSEIDON2_LEN (The RISC-V ISA).

Tidak ada abort

Prosesor tidak memiliki instruksi yang menolak untuk selesai, sehingga sebuah program tidak dapat berhenti ketika suatu pemeriksaan gagal. Bundle guest mencatat kegagalan itu sebagai gantinya: setiap pemeriksaan yang gagal melakukan OR dengan 1 ke sebuah register bernama bad, dan bad adalah kata terakhir yang di-hash ke dalam digest keluaran:

D = H(64; anchor, nf₀..₃, cm₀..₃, fee, burn_a, burn_r, burn_asset, time, c, bad)

c adalah komitmen otorisasi yang juga dipublikasikan oleh bukti auth (sejak chain 17; digest pada chain 14 sampai 16 tidak memiliki c).

Chain tidak pernah menerima preimage D dari pengirim. Chain membangun ulang preimage itu dari field publik transaksi, menetapkan bad = 0 sendiri, meng-hash, lalu membandingkan. Seorang penipu dapat membuat bukti yang sepenuhnya valid untuk eksekusi di mana sebuah pemeriksaan gagal, tetapi eksekusi itu menghasilkan H(…, 1), sedangkan chain mencari H(…, 0). Untuk mencocokkan keduanya diperlukan tabrakan hash.

2. Pecah trace menjadi sembilan tabel

Satu tabel yang menggambarkan seluruh prosesor akan terlalu lebar dan boros, sehingga trace dipecah menjadi tabel-tabel khusus yang dibuktikan bersama sebagai satu batch:

tabeljumlah baris pada tier tyang dicatat
programdideklarasikan, ≥ 2⁷kata-kata instruksi program, didekode di dalam sirkuit; menetapkan apa yang boleh diambil CPU
cpu2ᵗsatu baris per siklus, didahului baris yang meng-hash program, input privat, dan segmen publik; menyimpan 35 nilai publik
memorydideklarasikan, ≥ 2ᵗ⁺²register dan RAM, diurutkan menurut (space, alamat, waktu)
alu2ᵗ⁺¹setiap operasi aritmetika, logika, geser, perbandingan, perkalian, dan pembagian, pada limb byte
range, nibblemasing-masing 256tabel look-up tetap: byte, pangkat dua, AND/OR/XOR 4-bit
poseidon22ᵗ⁺²permutasi hash, satu baris per ronde
inputdideklarasikan, ≥ 2⁷kata-kata input privat yang di-commit
publicdideklarasikan, ≥ 2⁷kata-kata segmen publik (untuk sebuah bundle, pengikatan transaksi)

Dua tabel lagi, keccak dan sha256, hanya hadir dalam bukti yang programnya memanggilnya, masing-masing sedikitnya 2⁷ baris bila hadir; bundle guest tidak menggunakan keduanya. Batas bawah 2⁷ baris pada setiap tabel yang dideklarasikan hadir bersama constraint set 7 (section 9).

Tier t adalah salah satu dari 10, 12, 14, 16, 18, atau 20 dan menentukan ukuran tabel. Setiap bundle dibuktikan pada tier 14: tabel CPU 16.384 baris, yang dipakai guest sekitar 12.400. Auth guest menjalankan 250 siklus pada tier 10. Sisanya adalah padding, sehingga sebuah bukti mengungkapkan tier yang dibutuhkan suatu program, tetapi tidak pernah berapa langkah yang dijalaninya di dalam tier itu (Tiers).

Tabel memori inilah yang membuat RAM dapat diperiksa. Karena diurutkan menurut alamat lalu waktu, “pembacaan mengembalikan nilai terakhir yang ditulis ke alamat itu” menjadi aturan antara dua baris yang berdampingan.

3. Hubungkan tabel dengan bus

Bagaimana verifier tahu bahwa jumlah yang digunakan CPU adalah jumlah yang dihitung ALU? Melalui bus. Ketika CPU membutuhkan penjumlahan, ia mengirim pesan (op, a, b, c); ALU menerima satu pesan untuk setiap baris yang dihitungnya. Mesin ini memiliki tujuh belas bus:

busantara
PROGRAM, PROGRAM_WORDcpu ← program: pengambilan instruksi, dan kata-kata yang diserap digest program
MEMORYcpu ↔ memory: setiap pembacaan dan penulisan
ALUcpu → alu
RANGE8, POW2, AND4, OR4, XOR4pemeriksaan rentang byte, geser, dan operasi bitwise terhadap tabel tetap
POSEIDON2cpu → poseidon2: satu pesan per permutasi
INPUT_DIGEST, INPUT_READcpu ← input: kata-kata yang diserap digest input, dan pembacaan program
PUBLIC_DIGEST, PUBLIC_READcpu ← public: pasangan yang sama untuk segmen publik
KECCAK, SHA256cpu → tabel hash opsional
BLINDsetiap tabel → tabel berikutnya dalam siklus tetap: satu nilai acak masing-masing, pada baris pertama (constraint set 7)

Bus-bus ini diperiksa dengan logarithmic-derivative argument (LogUp). Setelah tabel-tabel di-commit, sebuah nilai acak α ditarik, dan setiap tabel menyimpan jumlah berjalan dari ±1/(α − m) atas pesan-pesan yang dikirim atau diterimanya. Jumlah-jumlah itu saling meniadakan secara tepat jika dan hanya jika setiap pesan yang dikirim telah diterima, yaitu multiset yang sama di kedua sisi. Satu pesan palsu meninggalkan residu yang akan terungkap oleh α acak dengan probabilitas yang sangat besar. Bus memori menggunakan kerabat dekatnya, pemeriksaan permutasi multiset.

Setiap tabel mempublikasikan nilai akhir dari jumlah berjalannya, yaitu terminal-nya, dan verifier memeriksa bahwa terminal-terminal itu berjumlah nol. Hingga constraint set 6, sebuah terminal adalah fungsi yang dapat diperiksa dari isi tabelnya. Sejak constraint set 7, setiap tabel membawa lima kolom tambahan dan, pada baris pertamanya, mengirim satu nilai acak serta menerima nilai tetangganya pada bus BLIND. Setiap terminal bergeser sebesar elemen seragam dari challenge field, dan jumlahnya tetap nol.

Pasangan bus digest dan bus read sengaja dipisahkan. LogUp menyeimbangkan per pesan, bukan per konsumen, sehingga satu bus bersama akan memungkinkan prover menghapus sebuah kata dari digest sementara pembacaan kata itu tetap berhasil.

4. Tambatkan trace ke dunia luar

Tiga puluh lima nilai publik keluar dari trace, semuanya di tabel CPU:

nilaiketerangan
1pc masuk
1tier
8kata keluaran (untuk bundle, digest D)
8hc, digest program, dihitung di dalam trace dari kata-kata tabel program
8H_IN, digest input privat, atas input dengan salt 128-bit baru di awal
8H_PUB, digest segmen publik, tanpa salt
1GAS_LIMIT, batas atas gas yang dinyatakan prover (constraint set 8)

Karena hc dihitung di dalam sirkuit, bukti tentang program lain tidak dapat lolos sebagai bukti tentang guest bundle. Verifier tidak pernah melihat satu pun kata instruksi; ia hanya membandingkan hc dengan digest yang diharapkannya. Karena H_IN diberi salt, digest ini mengikat input privat tanpa mengungkapkannya, bahkan kepada pihak yang mampu menebaknya. Karena H_PUB tidak diberi salt, verifier dapat menghitungnya ulang dari kata-kata yang sudah dimilikinya. Untuk sebuah bundle, kata-kata tersebut adalah pengikatan transaksi (transaction binding), blake3("rand-tx-bind-1" ‖ chain_id ‖ tx) atas transaksi dengan byte buktinya dikosongkan, sehingga bukti yang disalin ke transaksi dengan tujuan, memo, envelope, atau chain id yang berbeda tidak lolos verifikasi. Pada chain 20 (genesis binding_domain: 1) nilainya blake3("rand-tx-bind-2" ‖ genesis_hash ‖ chain_id ‖ tx), sehingga sebuah bukti tidak lolos verifikasi pada chain lain, bahkan dengan chain id yang sama; kata-kata tersebut merupakan input publik, sehingga perubahan ini tidak menggeser apa pun di dalam sirkuit. Bukti autentikasi dibuat atas delapan kata yang sama. Bukti pemanggilan (call proof) pada chain 20 diikat dengan cara yang sama: segmennya adalah kata-kata publik program saat deploy, diikuti delapan kata pengikatan pemanggilan (rand-call-bind-2, atau rand-call-bind-1 sebelum chain 20), sehingga bukti pemanggilan yang disalin ke bundle biaya lain tidak lolos verifikasi.

Gas adalah ukuran mesin atas bobot sebuah eksekusi, yang berada di dalam sirkuit sejak constraint set 8. Tabel CPU memuat kolom GAS yang dimulai dari 1 dan bertambah 1 untuk setiap baris, 3 untuk baris absorb Poseidon2, 64 untuk baris SHA256, dan 192 untuk baris KECCAK. Pada baris HALT, sirkuit membuktikan GAS ≤ GAS_LIMIT melalui empat limb selisih yang diperiksa rentangnya dan tidak pernah dibuka: batasnya publik, sedangkan gas yang dihabiskan sebuah eksekusi tidak. Sebelum membangun sebuah key, verifier menolak batas yang melebihi kebutuhan yang mungkin dari header bukti itu sendiri:

gas_max(t, k, s) = (2ᵗ − 1) + 2ᵗ⁻² + 191·(2ᵏ / 32) + 63·(2ˢ / 64)

dengan k dan s adalah tinggi log yang dinyatakan untuk tabel keccak dan sha256, dan masing-masing suku bernilai nol untuk tabel yang tidak ada. Batas atas untuk header tier-10 tanpa hash adalah 1.279 dan untuk tier-14 adalah 20.479. Chain menetapkan harga sebuah pemanggilan berdasarkan batas yang dinyatakannya (Fees).

5. Ubah aturan menjadi identitas polinomial

Setiap kolom adalah daftar bilangan dalam field Goldilocks, yaitu bilangan bulat modulo p = 2⁶⁴ − 2³² + 1. Daftar yang terdiri atas n bilangan sama saja dengan polinomial berderajat di bawah n: polinomial yang melalui bilangan-bilangan itu ketika diletakkan pada subgrup {1, ω, ω², …} dari field tersebut. Goldilocks memiliki subgrup semacam itu untuk setiap ukuran pangkat dua hingga 2³², sehingga konversinya merupakan transformasi Fourier cepat.

Sebuah aturan mesin kemudian menjadi persamaan antar polinomial kolom. “Program counter maju empat kecuali instruksinya melompat” menjadi, secara skematis:

is_jump(x)·(pc(ωx) − target(x)) + (1 − is_jump(x))·(pc(ωx) − pc(x) − 4) = 0

untuk setiap x dalam subgrup, dengan pc(ωx) berarti “baris berikutnya”. Seluruh himpunan aturan semacam itu pada sebuah tabel disebut AIR (algebraic intermediate representation). Aturan CPU dan ALU mencapai derajat 8; tabel lainnya tetap pada derajat 2 hingga 4.

Polinomial yang bernilai nol di setiap titik subgrup habis dibagi Z(x) = xⁿ − 1. Prover menggabungkan semua aturan, dengan bobot acak, menjadi satu polinomial C(x) lalu membaginya dengan Z(x). Jika setiap aturan berlaku pada setiap baris, hasil bagi adalah polinomial berderajat rendah yang sejati. Jika satu aturan gagal pada satu baris, hasil bagi bukan polinomial semacam itu. “Apakah setiap langkah dalam eksekusi 16.000 siklus benar?” telah menjadi “apakah fungsi ini mendekati polinomial berderajat rendah?”, dan pertanyaan itu dapat dijawab dengan memeriksa beberapa nilai yang dipilih secara acak.

6. Lakukan komitmen sebelum pertanyaan diketahui

Prover harus menetapkan polinomialnya sebelum melihat pertanyaan acak dari verifier, atau ia dapat menyesuaikan jawabannya. Prover mengevaluasi setiap kolom pada domain yang delapan kali lebih besar daripada tabel (blow-up 8, code rate 1/8) dan menerbitkan akar Merkle atas evaluasi tersebut. Redundansi itu adalah kode Reed–Solomon: polinomial berderajat rendah ditentukan oleh seperdelapan nilainya mana pun, sehingga penipu yang mengubah satu baris saja pada trace harus mengubah sebagian besar codeword yang diperluas agar tetap konsisten, dan pemeriksaan acak akan mengenai bagian yang rusak.

Pohon Merkle menggunakan Poseidon2 atas Goldilocks: lebar 8, S-box x⁷, 4 putaran penuh, 22 putaran parsial, dan 4 putaran penuh, dengan digest berupa empat elemen field (sekitar 256 bit). Setiap leaf di-hash bersama empat elemen acak yang baru, sehingga sebuah akar tidak mengungkapkan apa pun tentang nilai di bawahnya. Permutasi yang sama menjadi komitmen note dan hash nullifier di dalam mesin. 86 konstanta putarannya berupa tabel literal dalam kode sumber node (poseidon2_constants.rs), sehingga tidak ada pembaruan pustaka yang dapat mengubahnya.

7. Pemeriksaan acak dengan FRI

Verifier kini memegang akar-akar Merkle. Pertama-tama ia mengikat hasil bagi pada trace: ia memilih titik acak z di luar domain tabel, meminta nilai setiap kolom dan nilai hasil bagi di titik itu, lalu memeriksa C(z) = Q(z)·Z(z) secara langsung. Yang tersisa adalah memastikan bahwa fungsi-fungsi yang dikomit memang polinomial berderajat rendah, dan itulah yang diuji oleh FRI.

FRI bekerja dengan pelipatan. Pisahkan sebuah polinomial menjadi bagian genap dan ganjil, f(x) = fₑ(x²) + x·fₒ(x²). Untuk β acak dari verifier, f′(y) = fₑ(y) + β·fₒ(y) berderajat setengahnya pada domain berukuran setengahnya. Prover berkomitmen pada f′, menerima β baru, lalu melipat lagi (Rand melipat hingga delapan per putaran) sampai tersisa sebuah konstanta, yang dikirimkannya apa adanya. Sebuah query kemudian memilih satu posisi acak pada lapisan pertama dan menelusurinya ke bawah, memeriksa pada setiap lapisan bahwa nilai-nilai yang dibuka di atas terlipat menjadi nilai di bawahnya. Fungsi yang jauh dari berderajat rendah tidak dapat menjaga semua janji itu tetap konsisten.

Rand menjalankan 80 query. Berdasarkan teorema proximity gaps yang telah terbukti, setiap query menyisakan peluang paling banyak 9/16 bagi penipu, sehingga 80 query menghasilkan (9/16)⁸⁰ ≈ 2⁻⁶⁶·⁴. Berdasarkan konjektur ethSTARK, yang menjadi sandaran STARK yang telah diterapkan, setiap query menyisakan 1/8, yang jauh lebih kecil.

8. Hilangkan percakapan

Segala sesuatu di atas dijelaskan sebagai dialog, tetapi sebuah transaksi harus berupa satu pesan yang dapat diperiksa sendirian oleh validator mana pun. Transformasi Fiat–Shamir menghilangkan verifier: prover menghitung setiap tantangan “acak” sebagai hash dari semua yang telah dikomit sejauh itu, dengan duplex sponge Poseidon2. Mengubah komitmen apa pun akan mengubah setiap tantangan sesudahnya, sehingga prover tidak dapat memilih komitmen yang disesuaikan dengan tantangan.

Dua langkah tambahan menutup celah yang tersisa:

  • Extension field. Field dengan 2⁶⁴ elemen terlalu kecil untuk menarik tantangan darinya: penipu hanya memerlukan tantangan yang jatuh pada salah satu dari sedikit nilai buruk sebuah polinomial, dan berhasil dengan peluang sekitar N/2⁶⁴ berapa pun jumlah query yang dijalankan. Karena itu trace tetap berada di Goldilocks, tetapi setiap tantangan ditarik dari perluasan kuadratiknya, sekitar 2¹²⁸ elemen.
  • Grinding. Sebelum posisi query diturunkan, prover harus menemukan sebuah nonce yang hash-nya bersama transkrip diawali 20 bit nol, sekitar satu juta hash. Prover yang jujur membayarnya sekali. Penipu yang mengulang pengundian posisi query hingga luput dari pemalsuannya membayarnya pada setiap percobaan. Ini satu-satunya proof of work di seluruh Rand, dan tidak ada kaitannya dengan konsensus.

Jika dijumlahkan: 66,4 bit dari query ditambah 20 dari grinding menghasilkan 86 bit terbukti, dan sekitar 100 bit di bawah konjektur, di mana suku extension field menjadi batasnya.

9. Dari mana zero knowledge berasal

STARK tidak bersifat zero-knowledge dengan sendirinya: nilai-nilai yang dibuka pada posisi query adalah nilai polinomial trace, dan tanpa kehati-hatian nilai-nilai itu membocorkan informasi. Konfigurasi Rand menambahkan empat lapisan:

  1. setiap polinomial yang dikomit diacak (FRI hiding milik Plonky3 mencampurkan empat codeword acak), sehingga 80 nilai yang dibuka dapat direproduksi, dalam distribusi, oleh pihak yang tidak pernah melihat trace;
  2. setiap leaf Merkle diberi salt, sehingga akar dan jalur autentikasi tidak mengungkapkan apa pun;
  3. keacakan prover diambil baru dari sistem operasi untuk setiap bukti, sehingga dua bukti untuk pembayaran yang sama tampak tidak berkaitan;
  4. setiap tabel yang dinyatakan memiliki sedikitnya 2⁷ baris dan setiap terminal LogUp dibutakan (constraint set 7). Sebuah bukti membuka setiap tabel pada 80 titik query dan dua titik di luar domain, dan komitmen hiding mencampurkan baris acak sebanyak baris yang dimiliki tabel, sehingga sebuah tabel tersembunyi hanya selama ia memiliki sedikitnya 82 baris. 128 adalah pangkat dua terkecil yang memenuhinya.

Lapisan 4 adalah sebuah koreksi. Tinjauan 2026-09-27 berhasil memulihkan input privat dari panggilan dengan 31 kata input atau kurang dari proof produksi, membaca jumlah fetch sebuah program dari tabel programnya yang pendek, dan membedakan slot input asli sebuah bundle dari slot dummy-nya melalui terminal-terminalnya yang tidak di-blind. Proof-proof tersebut adalah yang dibuat pada chain 15 dan sebelumnya. Chain 16 (constraint set 7, dengan guest bundle bebas cabang) menutup ketiganya, dan chain 18 sampai 20 mempertahankan perbaikan itu.

Jaminannya adalah zero knowledge statistik dalam model random-oracle. Apa yang tidak disembunyikan oleh sebuah proof bersifat pasti: tier-nya, tinggi tabel yang dideklarasikannya, dan nilai publiknya, termasuk batas gas. Tinggi keccak atau sha256 yang dideklarasikan sebesar 0 berarti eksekusi tidak pernah memakai hash tersebut, sehingga header proof panggilan menunjukkan apakah panggilan itu melakukan hashing dan, di atas batas bawah, seberapa sering dalam kisaran faktor dua. Untuk sebuah bundle, nilai publik dan kolomnya adalah anchor, empat nullifier, empat commitment, fee, burn, aset burn, waktu, commitment otorisasi, dan binding transaksi. Aset yang dipindahkan sebuah transfer adalah input privat, sehingga pembayaran zUSD dan pembayaran RAND tampak sama di chain. hc bersifat deterministik, sehingga siapa pun dapat mengetahui bahwa sebuah proof menyangkut guest bundle (setiap proof yang memindahkan nilai demikian) atau, untuk sebuah panggilan, program terdeploy mana yang dijalankannya.

10. Apa yang diperiksa validator

Machine::verify_public(hc, words, proof) menjalankan pemeriksaan berikut, dari yang termurah:

  1. tier dan tinggi tabel yang dideklarasikan proof dibatasi (check_declared_heights) sebelum ada yang diukur dari nilai-nilai itu, sehingga header yang cacat hanya memakan beberapa perbandingan, bukan pembangunan key selama beberapa detik; sebuah bundle harus mendeklarasikan tier 14 tanpa tabel hash apa pun, dan proof auth tier 10;
  2. terdapat 35 nilai publik, masing-masing elemen field kanonik, dengan pv[HC] = hc, pv[TIER] sama dengan tier proof, setiap kata output di bawah 2³², dan GAS_LIMIT paling banyak gas_max dari header;
  3. STARK batch terverifikasi terhadap verifier key yang di-cache per bentuk (tier, program, input, keccak, sha256, public heights), bukan per program;
  4. H_PUB sama dengan digest dari words, yang untuk sebuah bundle adalah binding transaksi yang dihitung sendiri oleh node.

Sebelum semua itu, node menyaring setiap proof yang dikirim atau digossip untuk memastikan encoding kanonik: jadwal pelipatan FRI-nya harus sama dengan yang dibuat prover jujur untuk derajat yang dideklarasikan header. Sejak fullnode v0.6.8 (audit v6, ZKV-4), penyaringan ini terlebih dahulu menolak setiap derajat yang dideklarasikan di atas 25 bit (MAX_HONEST_DEGREE_BITS, batas atas 2²⁴ pada tabel memori ditambah penggandaan zero-knowledge, yang merupakan nilai terbesar yang dibawa proof yang diterima). Sebelum batas itu ada, header yang mendeklarasikan derajat yang sangat besar membuat node menurunkan ulang jadwal pelipatan yang sangat besar pada event loop-nya, menahannya selama pengirim menghendaki; verifier toh akan menolak proof itu, sehingga batas ini hanya mengubah biaya untuk mengatakan tidak. Panic di dalam penyaringan kini hanya menolak satu transaksi itu, bukan menghentikan node.

Ledger kemudian menghitung ulang digest bundle D dengan bad = 0 dan membandingkannya dengan kedelapan kata output proof. Pada chain 20 ledger juga mensyaratkan GAS_LIMIT proof bundle persis sama dengan bundle_gas_limit genesis, yaitu 20.479, dan milik proof auth 1.279, sehingga setiap transfer mendeklarasikan nilai yang sama. Dengan key yang hangat, seluruh pemeriksaan memakan waktu sekitar 16 ms.

Parameter, dan alasan pemilihannya

Setiap angka di bawah ini adalah konsensus: verifier memeriksanya, proof yang dibuat dengan nilai lain tidak terverifikasi, dan mengubah satu angka berarti constraint set baru dan hard fork (Himpunan constraint). Profil FRI ditetapkan oleh file genesis (fri_profile: production pada chain 20), tidak pernah oleh proof.

parameternilaialasan pemilihan nilai ini
base fieldGoldilocks, p = 2⁶⁴ − 2³² + 1Bilangan prima 64-bit yang aritmetikanya hanya membutuhkan beberapa instruksi mesin, dengan subgrup multiplikatif untuk setiap ukuran pangkat dua hingga 2³², sehingga mengubah sebuah kolom menjadi polinomial cukup dengan fast Fourier transform. Trace berada di sini karena ini adalah field yang murah.
challenge fieldekstensi kuadratik F_p² (≈ 2¹²⁸)Challenge yang diambil dari Goldilocks sendiri akan menyisakan batas bawah soundness sekitar N/2⁶⁴ yang tidak dapat diturunkan oleh query sebanyak apa pun. Ekstensi ini menekan suku tersebut hingga paling besar 2⁻¹⁰⁰ untuk trace hingga 2²⁵ baris. Hanya challenge yang menanggung biaya field yang lebih besar; trace tidak. Ekstensi kubik (≈ 2¹⁹²) adalah margin yang telah ditetapkan apabila 128 bit suatu saat diwajibkan.
blow-up8 (rate ρ = 1/8, log_blowup = 3)Dua alasan sekaligus. Tabel CPU dan ALU memiliki aturan berderajat 8, dan dengan flag zero-knowledge, quotient berderajat 9, yaitu batas maksimum yang dapat ditampung blow-up 8; aturan berderajat lebih tinggi akan memaksa blow-up 16. Selain itu, kemampuan setiap query untuk menangkap pihak yang curang bergantung pada rate: (1 + ρ)/2 = 9/16 per query secara terbukti, ρ = 1/8 secara konjektural. Blow-up yang lebih besar akan mengurangi jumlah query, tetapi dengan biaya low-degree extension yang ukurannya bertambah sebanding, yang harus dihitung dan disimpan dalam memori oleh prover.
query FRI80Jumlah yang menjaga soundness terbukti pada sekitar 86 bit. Jumlah ini pernah dipangkas menjadi 27 (constraint set 3 dan 4), yang memenuhi target 100 bit secara konjektural (3·27 + 20 = 101) tetapi hanya menyisakan sekitar 42 bit terbukti; audit zk 2026-09-12 (temuan ZM1) mengembalikannya ke 80. Query merupakan sebagian besar ukuran sebuah bukti, itulah sebabnya bukti bundle berukuran ≈ 1.50 MB. Untuk 100 bit terbukti dibutuhkan 97 query.
grinding20 bit, pada fase querySebelum posisi query ditarik, prover harus menemukan sebuah nonce yang hash-nya diawali 20 bit nol: sekitar satu juta hash, yang dibayar sekali oleh prover yang jujur dan pada setiap percobaan ulang oleh pihak curang yang mengundi ulang posisi. Cara ini menambah 20 bit dengan murah; grinding yang lebih banyak (34 bit juga akan memberi 100 bit terbukti) membuat setiap bukti yang jujur menjadi lebih lambat. Fase commit tidak memakai grinding.
folding arityhingga 8 per putaran (max_log_arity = 3)Melipat delapan sekaligus, bukan dua, menghasilkan seperti tiga kali lebih sedikit lapisan FRI, sehingga setiap query membuka lebih sedikit jalur Merkle dan bukti menjadi lebih kecil, dengan sedikit tambahan kerja per lapisan.
polinomial akhirsebuah konstanta (log_final_poly_len = 0)FRI melipat hingga ke dasar dan mengirim satu nilai secara terbuka, pemeriksaan akhir yang paling sederhana bagi verifier.
hash (dalam sirkuit, Merkle, transkrip)Poseidon2, lebar 8, S-box x⁷, 4 + 22 + 4 putaran, rate 4, capacity 4Hash yang dirancang agar murah sebagai aritmetika field, sehingga melakukan hashing di dalam sebuah bukti (komitmen, nullifier, jalur Merkle, digest program) memakan baris, bukan ribuan operasi bit. Eksponen S-box tidak boleh memiliki faktor persekutuan dengan p − 1 = 2³²·3·5·17·257·65537, dan 7 adalah yang terkecil yang memenuhi syarat. Lebar 8 pada rate 4 menghasilkan digest empat elemen, sekitar 256 bit. Ke-86 konstanta putaran merupakan tabel literal di dalam node (poseidon2_constants.rs).
lebar digest4 elemen field (≈ 256 bit)Cukup untuk peran preimage (nullifier, komitmen: 128 bit terhadap Grover). Ini tidak cukup untuk ketahanan tabrakan kuantum 128 bit pada transkrip (2²⁵⁶/³ ≈ 2⁸⁵); rancangan dalam whitepaper meminta hash transkrip 384 bit, dan chain yang sedang berjalan belum mengadopsinya.
hiding4 codeword acak dalam FRI; 4 elemen salt per daun Merkle; keacakan OS yang baru untuk setiap buktiMinimum yang membuat 80 posisi yang dibuka dan jalur Merkle dapat disimulasikan hanya dari nilai publik, sehingga bukti bersifat zero-knowledge secara statistik. Bukti dari pembayaran yang sama yang dibuat dua kali tampak tidak berkaitan.
batas bawah tabel2⁷ baris untuk setiap tabel yang dideklarasikan (constraint set 7)Sebuah bukti membuka 80 titik query dan 2 titik out-of-domain dari setiap tabel, seluruhnya 82, dan tabel dengan h baris diburamkan oleh h baris acak. 64 baris terlalu sedikit dan 128 adalah pangkat dua berikutnya. Jumlah query di atas 126 akan membutuhkan 2⁸.
terminal blindsatu nilai F_p² per tabel, pada bus BLIND (constraint set 7)Terminal LogUp dihitung dari trace mentah, sehingga tanpa blind ia merupakan komitmen tanpa salt terhadap tabelnya. Blind berupa elemen extension field karena satu koordinat base field akan membatasi pergeseran pada himpunan tipis yang dapat diuji terhadap sebuah witness kandidat.
bobot gas1 per baris; 3 per baris absorb Poseidon2; 64 per baris SHA256; 192 per baris KECCAK (constraint set 8)Setiap bobot menghitung baris yang ditarik oleh baris tersebut ke tabel lain: satu baris absorb menarik satu permutasi 32 baris, satu baris SHA256 menarik 64 baris dengan 466 kolom, satu baris KECCAK menarik 32 baris dengan 2,612 kolom dan 100 baris memori.
derajat constraint maksimum8Ditetapkan oleh blow-up di atas; derajat setiap tabel dikunci oleh sebuah pengujian agar aturan baru tidak dapat melampauinya secara diam-diam.
tier10, 12, 14, 16, 18, 20Tabel berukuran dalam enam langkah tetap, masing-masing empat kali langkah sebelumnya, dan sebuah bukti hanya mengungkapkan tier-nya: sebuah bucket kasar yang diberi padding dari panjang eksekusi, bukan jumlah siklusnya. Setiap bundle berada pada tier 14 dan setiap bukti auth pada tier 10; panggilan dibatasi pada tier 14 sejak fullnode v0.5.6.
trace maksimum2²⁴ baris (2²⁵ dengan bit zero-knowledge)Ukuran yang menjadi dasar pembuktian suku extension-field; trace yang lebih panjang ditolak, bukan dibuktikan di bawah klaim soundness yang tidak berlaku.
nilai publik35 elemen fieldpc masuk, tier, delapan kata keluaran, tiga digest delapan kata hc, H_IN, H_PUB, dan batas gas yang dideklarasikan: pernyataan terkecil yang menyebutkan program, input privat, input publik, dan batas atas kerja. Jumlahnya 34 hingga constraint set 7.
batas ukuran bukti2 MiB bawaan; 4 MiB pada chain 20 (max_proof_bytes)2 MiB berada di atas setiap bukti yang dibuat guest yang telah dideploy tanpa tabel hash dan di bawah bukti yang memuat keccak (≈ 3.3 MB); genesis chain 20 menetapkan 4,194,304 agar keduanya diterima, seperti chain 17 hingga 19. Chain 13 hingga 16 menetapkan 8 MiB. Batas ini diperiksa sebelum sebuah bukti didekode.

Apa yang dihasilkan oleh angka-angka ini: soundness 86 bit secara terbukti, sekitar 100 di bawah konjektur ethSTARK (di mana extension field, bukan query, yang menjadi batasnya), dan sekitar 85 bit terhadap adversari kuantum, yang ditetapkan oleh hash transkrip 256 bit. Whitepaper sengaja menampilkan kedua angka soundness berdampingan: setiap FRI-STARK yang telah dideploy bergantung pada konjektur untuk bit-bit terakhirnya, dan pembaca yang menentukan ukuran suatu deployment perlu mengetahui asumsi mana yang menopang bit yang mana.

Bukti tentang bukti

Pada sekitar 1.50 MB, sebuah bukti bundle tergolong berat, bukti auth 1.37 MB menyertainya, dan setiap node menyimpan semuanya. Solusi yang telah dibangun adalah rekursi: sebuah bukti dengan pernyataan “saya telah memverifikasi bukti-bukti ini”. Fullnode membawa mesin kedua yang lebih kecil untuk keperluan ini, yaitu recursion VM, yang kata aslinya adalah satu elemen Goldilocks dan yang instruksinya adalah operasi milik verifier sendiri (aritmetika field, Poseidon2, langkah Merkle dan FRI). Program agregatnya memutar ulang seluruh verifikasi N bukti bundle dan menerbitkan sebuah digest atas nilai publik bukti-bukti tersebut, terikat pada chain, aggregator, dan sebuah nonce. Memverifikasi satu bukti bundle di dalamnya memakan 1,968,619 baris di bawah constraint set 6 dan 2,044,506 di bawah constraint set 7; belum diukur ulang di bawah set 8. Mesin ini telah diimplementasikan dan dimatikan oleh genesis pada setiap chain sejauh ini, termasuk chain 20. Program agregat hanya memverifikasi bukti bundle, sehingga pada chain dengan otorisasi terpisah, bukti auth tetap ada. Bukti produksinya juga membutuhkan memori lebih banyak daripada yang direncanakan: diukur di bawah constraint set 7, 133 GB atau lebih (Mendatang: agregasi blok).

Apa yang tidak diklaim oleh skema ini

  • Margin kuantum adalah sekitar 85 bit, bukan 128. Pencarian tabrakan kuantum pada hash n-bit berbiaya sekitar 2ⁿ/³. Rancangan whitepaper menetapkan hash transkrip 384-bit; chain yang berjalan menggunakan digest Poseidon2 256-bit. Memperlebarnya berarti constraint set baru dan hard fork.
  • 100 bit adalah konjektur; 86 terbukti. Menaikkan angka yang terbukti menjadi 100 akan memerlukan 97 query, sekitar seperlima lebih banyak data query per proof.
  • Konstanta Poseidon2 adalah hasil pengundian dengan seed, bukan instansiasi yang dipublikasikan. Tidak ada serangan terhadapnya yang diketahui; mengadopsi set standar akan mengubah setiap hash pada chain.
  • Sebagian pernyataan diperiksa di samping proof, bukan di dalamnya. Nilai publik TIER dibandingkan dengan bentuk proof oleh verifier tetapi tidak dikekang oleh sirkuit (audit ZL1), dan disiplin taint pada bundle guest didukung oleh argumen struktural, harness guest yang dilemahkan, dan mutation fuzzing, bukan diverifikasi secara mekanis.
  • Header sebuah proof tidak disembunyikan. Tier dan kedua tinggi tabel hash terlihat jelas, sehingga proof panggilan menunjukkan apakah panggilan tersebut menggunakan KECCAK atau SHA256. Ada opsi prover yang menambahkan padding pada kedua tabel dan tidak ada wallet yang mengaturnya: opsi ini menaikkan proof tier-10 dari sekitar 1,3 MB menjadi sekitar 3,6 MB.
  • Syscall POSEIDON2 tidak injektif untuk input dengan panjang variabel. Syscall ini dipertahankan apa adanya karena setiap commitment, nullifier, root, dan digest program bergantung padanya. Belum ada guest yang dikirim yang menggunakan POSEIDON2_LEN.
  • Proving berjalan lambat dan dilakukan oleh pengirim, atau oleh prover yang dipasangkan dengan pengirim: sekitar 100 s dan 5,7 GB pada CPU laptop untuk sebuah bundle. Kernel GPU pertama kali dijalankan pada GPU (NVIDIA H100) pada 2026-09-28 dan cocok dengan referensi CPU; wallet masih melakukan proving pada CPU.

Untuk bacaan lebih lanjut

  • Bagian whitepaper “The Zero-Knowledge Scheme: How a Rand Proof Works” (randprotocol.tex) menguraikan ketujuh unsur yang sama beserta teorema soundness-nya.
  • Makalah implementasi (randprotocol_implementation.tex) menspesifikasikan set instruksi dan syscall, bundle guest, sponge dan digest, setiap tabel dan bus, konfigurasi mesin, serta VM rekursi.
  • Kodenya: crates/randprotocol-zkvm/src/ di fullnode — emulator.rs, tables/, machine.rs, gas.rs, guests.rs, hash.rs, poseidon2_constants.rs.

Terakhir diverifikasi terhadap commit fullnode c0878c3f (chain 21) pada 2026-10-12, dan fullnode `90e7716` (v0.6.7 on chain 18, `crates/randprotocol-zkvm`, constraint set 8), fullnode `c9c9bd3c` (v0.6.8 on chain 20: ZKV-4 in `crates/randprotocol-zkvm/src/executor.rs`, `binding_domain` in `crates/randprotocol-core/src/types/binding.rs`; no constraint change), fullnode `c0878c3f` (v0.8.0 on chain 21: `docs/zkvm.md` §8a, constraint set 9 — the `MODQ` syscall and the optional `modq` table; `docs/shielded.md` §2, the multisig auth guest's pinned shape), circuits `aeacf31`, `research/docs/02-tables-and-buses.md`, `research/docs/03-privacy.md` (the FRI profile, the degree ceiling, the table floor and the blinded terminals), whitepapers `8f4275b` (`randprotocol.tex` §“The Zero-Knowledge Scheme”, `randprotocol_implementation.tex` §§4.10–4.15). Jika kode dan halaman ini tidak sesuai, kodelah yang benar; beri tahu kami.