
Kami telah mengimplementasikan prototipe transaksi anonim berdasarkan zkSNARK untuk memastikan transaksi rahasia pada blockchain Waves. Dalam implementasi kami, kami menggunakan sistem bukti Groth16 pada kurva BN254 dan circom DSL.
Kami menjelaskan cara kerjanya.
zkSNARKs
zkSNARK adalah primitif kriptografi yang mengonfirmasi pengetahuan tentang kumpulan data khusus (bukti) yang terkait dengan serangkaian persamaan berikut (sistem kendala):
⟨ai,w⟩⟨bi,w⟩+⟨ci,w⟩=0
bagian dari bukti bersifat pribadi. Konstruksi ini memungkinkan kita untuk membuktikan, misalnya, pengetahuan tentang gambar terbalik hash tanpa mengungkapkan gambar terbalik. Ini juga dapat digunakan dalam mekanisme transaksi pribadi untuk model UTXO (Unspent Transaction (TX) Output), di mana hanya hash UTXO yang diterbitkan, dan validitas transaksi tersebut terbukti di dalam zkSNARK (bukti kepemilikan, bukti penghematan jumlah).
zkSNARK adalah teknologi non-interaktif tanpa pengungkapan, yaitu, itu tidak menyiratkan protokol interaksi antara peserta yang diimplementasikan untuk membuktikan pengetahuan. Dalam teknologi zkSNARK, prover mengkonstruksi bukti dan mengirimkannya ke prover - tidak diperlukan interaksi tambahan. Pemeriksa dapat memverifikasi kebenaran dan kebenaran penggunaan data bukti tanpa menggunakan informasi tambahan. Awalnya, zkSNARKs dibuat sebagai protokol "komputasi rahasia": ketika menghitung hasilnya, data yang terlibat dalam perhitungan tidak diungkapkan.
Menggunakan teknologi zkSNARK, skema pengungkapan komitmen dapat diimplementasikan: prover menghitung hash, memberikannya kepada prover, dan membuat bukti khusus bahwa ia tahu gambar terbalik hash x. Dengan mengganti nilai-nilai x dan hash ke dalam rumus, dan meneruskan rumus ini dan buktinya kepada pemeriksa, pemeriksa dapat memastikan bahwa pepatah tahu x. Ini adalah dasar untuk transaksi anonim: kita tahu kunci privat dan beberapa input spesifik (UTXO tidak terpakai) dengan jumlah tertentu yang dibuat pengguna pada kontrak pintar. Tanpa mengungkapkan data ini, pengguna dapat mengkonfirmasi dengan kontrak pintar bahwa ini adalah inputnya, bahwa ia dapat membuangnya dan memberikannya kepada seseorang untuk digunakan.
Sekarang teknologi tidak digunakan di mana-mana, karena buktinya dihasilkan selama beberapa menit, yang sangat tidak nyaman bagi pengguna.
Pelajari lebih lanjut tentang pemrograman zkSNARK dalam artikel Vitalik Buterin "Program Aritmatika Kuadratik: dari Nol ke Pahlawan" dan dalam artikel Iden3 tentang desain sirkuit circom.
Model akun
Untuk transaksi di Waves, mereka biasanya menggunakan kunci dan alamat berdasarkan curve25519
. Kurva ini tidak ramah zkSNARK, jadi untuk transaksi anonim kami menggunakan subkelompok Edwards dari kurva bengkok BabyJubJub
. Selain itu, kami menggunakan kunci publik sebagai alamat, karena saat mengirim, Anda harus mengenkripsi data untuk penerima.
Model UTXO
Dalam model kami, UTXO diwakili oleh serangkaian 3 parameter: saldo, kunci publik pemilik dan rahasia unik. Blockchain hanya berisi hash tanpa enkripsi tambahan. Pemiliknya diwakili oleh kunci publik, dan, seperti disebutkan sebelumnya, kami menggunakan kunci publik bukan pada curve25519
, tetapi pada kurva BabyJubJub
ramah BabyJubJub
. UTXO Id harus dibuat secara acak, karena jika pengguna menentukan dua id yang identik, ia dapat mengambil (menghabiskan) UTXO hanya pada salah satu dari mereka. Dalam hal ini, hanya UTXO dengan id yang sesuai untuk pengguna saat ini yang akan diblokir, tetapi tidak untuk sisanya. Adalah kepentingan pengguna untuk memilih id menggunakan generator angka acak (253 bit dialokasikan pada id, sehingga sulit untuk mendapatkan tabrakan).
Untuk menghabiskan UTXO, Anda harus menerbitkan nullifier, fungsi deterministik dari UTXO, yang didefinisikan sebagai hash (rahasia, owner_privkey). Nilai ini bersifat deterministik dan unik untuk setiap UTXO, hanya pemilik yang mengetahuinya. Selain pemilik, tidak ada yang dapat mengaitkan UTXO dengan pembatal yang terkait.
UTXO disimpan di dalam peta hash dApp, yaitu dalam gaya kontrak. Di blockchain, UTXO dienkripsi. Untuk mengambil uangnya, pengguna harus memindai blockchain dan mencoba mendekripsi setiap UTXO.
Sebutkan dapp
Gaya dApp berisi peta hash yang mewakili dua set:
Dengan demikian, dApp dapat memverifikasi keberadaan set anonim UTXO dan keunikan nullifiers. Ini cukup untuk memproses transfer anonim dengan perlindungan terhadap pemalsuan aset baru dan pengeluaran ganda.
DApp memiliki 3 metode yang sesuai dengan jenis transaksi dasar:
- Setoran
- Transfer
- Kesimpulan
Untuk mentransfer dan menarik dana, kami menggunakan pengukur sendiri yang memastikan interaksi dApp dengan akun anonim khusus berdasarkan pada kurva BabyJubJub. Setoran diproses dari akun Gelombang reguler.
Komisi
Untuk pengisian akun, biaya dibebankan dari curve25519
akun. Untuk transfer dan penarikan, komisi didebet dari akun anonim. Di tingkat dApp, tampilannya seperti ini:
dApp membayar untuk transaksi itu sendiri, yaitu token asli yang dihabiskan untuk membayar komisi didebit dari saldo
Antara pintu masuk dan keluar, bagian dari komisi dibakar untuk membatalkan aset yang sesuai dengan aset nyata pada kontrak pintar
Di tingkat UTXO, kami membakar jumlah tertentu sebagai komisi saat memproses transaksi.
Transaksi
Setoran adalah operasi sederhana, setiap setoran menambahkan elemen baru ke UTXO.

Transfer didasarkan pada terjemahan primitif 2-ke-2.

Beberapa input dan output mungkin nol. Sebagai contoh parsial dari konstruksi seperti itu, segala jenis terjemahan sederhana dapat diwakili (bergabung, dibagi dan transfer lainnya, dengan pengecualian pertukaran atom).
Kesimpulan berfungsi seperti transaksi lainnya, hanya alih-alih membuat UTXO kedua, mereka memungkinkan pengguna untuk menarik UTXO dari dApp. Bisa juga ada dua UTXO di input, UTXO di pintu keluar dengan sisa dana dan penarikan, yang diterbitkan di blockchain.

Saat menarik atau mentransfer, dApp memverifikasi bahwa nullifiers yang sesuai belum ditemukan di tumpukannya.
Menggunakan zkSNARK kita dapat menghitung bahwa jumlah input transaksi sama dengan jumlah output. Saat melakukan transaksi, kami membelanjakannya untuk UTXO dan beberapa nol UTXO lainnya, yang tidak ada di pohon merkle. Untuk menghabiskan UTXO, Anda perlu membuktikan pengetahuan tentang kunci pribadi pemiliknya. Pastikan kunci pribadi, ketika dikalikan dengan generator grup, menghasilkan kunci publik. Dengan demikian, tanpa mengetahui kunci privat, transaksi tidak dapat diselesaikan.
Kumpulan anonim
Kami menggunakan serangkaian 8 elemen anonim. Elemen target dipilih secara pribadi dari set yang diwakili dalam input publik zkSNARK. Metode ini memungkinkan Anda untuk mengaburkan grafik transaksi (jika dimungkinkan untuk mengembalikan grafik interaksi UTXO, maka ada kemungkinan melakukan deanonimisasi transaksi).
Selanjutnya, kolektor sederhana dengan 8 elemen dapat diganti dengan kolektor pohon Merkle. Pendekatan menyembunyikan grafik transaksi.
Untuk membuat transaksi yang valid, kami membuktikan bahwa kami menghabiskan beberapa UTXO dari set UTXO. Kami menempatkan bukti merkle zkSNARK dan data UTXO ke input pribadi dan root hash ke pintu masuk publik. Dengan demikian, menggunakan SNARK, kami membuktikan bahwa kami tahu UTXO.

Perlindungan Pengeluaran Ganda
Untuk melindungi dari pengeluaran ganda, kami menggunakan nullifiers - fungsi deterministik yang tidak bergantung langsung pada hash UTXO. Untuk menghitung nullifier, kami mengambil fungsi dari kunci privat, terbukti sesuai dengan kunci publik, id dan hash UTXO. Untuk setiap UTXO, hanya ada satu pembatal.
Untuk setiap transaksi, pembatal dari output UTXO yang dihabiskan harus disajikan sebagai entri publik untuk zkSNARK. Di dalam sirkuit zkSNARK, itu juga harus dipastikan bahwa itu milik UTXO yang dihabiskan.
Jika kontrak dApp menerima nilai nullifier yang tidak unik, transaksi ditolak. Dengan demikian, dijamin bahwa setiap UTXO dihabiskan satu kali.
Setelah mereka menghabiskan UTXO, nullifier diterbitkan dalam daftar nullifiers yang dihabiskan dalam artikel dApp. Artinya, dalam hash-map, berlawanan dengan nullifier ini, "true" diset. Sebelum menerbitkan nullifier dalam artikel, kami memeriksa apakah nullifier ini belum digunakan, yang berarti bahwa UTXO dengan id ini dapat dihabiskan.