./research / verifiable-audit-layer
Lapisan audit yang dapat diverifikasi untuk AI.
Lapisan audit yang menunjukkan bukti gangguan untuk inferensi model dan eksekusi agen: serialisasi kanonik, hashing dengan pemisahan domain, tanda tangan DSSE, sebuah Merkle DAG per eksekusi, dan Merkle Mountain Range antar-eksekusi yang membuktikan tidak ada eksekusi yang dihapus. Setiap primitif dipilih dari benchmark langsung melawan alternatif nyata, dengan data mentah yang di-commit. Catatan ini adalah rancangan dan eksperimen di baliknya.
Model ancaman
Kami mengasumsikan lawan yang menguasai penyimpanan dan dapat menulis ulang catatan setelah kejadian, termasuk operator yang memproduksinya. Tujuannya adalah agar setiap penyuntingan pada eksekusi yang tersegel dapat dideteksi, agar catatan tetap dapat diverifikasi selama periode retensi yang diukur dalam tahun, dan agar verifikasi tidak mengungkap masukan pribadi apa pun. Dua sifat dijaga tetap terpisah sepanjang waktu: integritas satu eksekusi dan kelengkapan himpunan eksekusi. Sebuah tanda terima per eksekusi memberi yang pertama dan tak berkata apa pun tentang yang kedua, jadi keduanya dirancang terpisah.
Setiap pilihan di bawah dibuat dengan cara yang sama. Kami tidak menyatakan sebuah primitif adalah yang terbaik; kami membandingkannya dengan alternatif yang kredibel pada mesin yang sama dan meng-commit data mentahnya, sehingga angka mana pun di sini bereproduksi dalam satu perintah. Waktu adalah yang tercepat dari beberapa eksekusi setelah membuang pemanasan, dengan rata-rata dan simpangan baku dipertahankan agar pengukuran yang tak stabil ditandai alih-alih disembunyikan. Angka-angka berasal dari satu host AMD64 pada CPython 3.14 dan bermakna sebagai rasio, bukan nilai mutlak.
Eksperimen dan hasil
Setiap tonggak adalah uji langsung melawan alternatif nyata, bukan pengukuran tunggal. Ringkasannya di bawah; hasil terperinci masing-masing ada di bagian berikutnya.
| Tonggak | Diuji melawan | Hasil |
|---|---|---|
| Bentuk kanonik | JSON naif, CBOR | JCS, identik bita demi bita, ~3x biaya |
| Hashing | SHA-256, BLAKE3, keccak-256 | keccak natif 17x, bita yang sama |
| Inti natif | backend pip vs Rust | penyegelan 6x, akar identik bita demi bita |
| Tanda tangan | ECDSA, BLS, ML-DSA | Ed25519, 64 B, deterministik |
| Pasca-kuantum | ML-DSA 44 / 65 / 87 | bertahap, verifikasi setara, 38x ukuran |
| Jejak per eksekusi | 8 serangan pemalsuan, overhead | semua tertangkap, ~121 us / peristiwa |
| Log antar-eksekusi | pembangunan ulang Merkle biasa | MMR, penambahan datar, 483x |
Serialisasi kanonik
Sebuah kapsul harus di-hash ke bita yang sama di inti Python kami, di klien TypeScript kami, dan di perkakas milik seorang auditor, atau catatan yang sah gagal diverifikasi. Kami memakai RFC 8785 (JSON Canonicalization Scheme), yang menetapkan format angka, urutan kunci menurut satuan kode UTF-16, dan penolakan nilai tak-hingga. Kami mengujinya melawan JSON dengan kunci diurut secara naif dan melawan CBOR.
| Pendekatan | Python vs Node | Biaya |
|---|---|---|
| JSON terurut naif | menyimpang pada Unicode dan angka | dasar |
| RFC 8785 JCS | identik bita demi bita | sekitar 3x saat serialisasi |
| CBOR | biner, perlu dekoder untuk dibaca | ringkas |
JSON naif menyimpang antar-runtime pada pengurutan Unicode dan format angka, sehingga diam-diam merusak verifikasi antar-bahasa. JCS identik bita demi bita pada keduanya, pada sekitar 3x waktu serialisasi, dibayar sekali per hash dan dapat diabaikan dibanding hashing serta kerja jaringan di sekitarnya. Kami menyimpan tepat satu implementasinya. Ketika modul natif kami membawa serializer JSON-nya sendiri, kami menghapusnya, karena kanonikalisator kedua yang sepakat pada masukan biasa dan menyimpang pada kasus batas yang dapat dipilih lawan lebih buruk daripada tidak ada.
Hashing dan inti natif
Daun di-hash dengan BLAKE3 dan simpul Merkle dengan keccak-256, keduanya dengan pemisahan domain RFC 6962 (awalan berbeda untuk daun dan simpul internal) guna menutup kelas praimej kedua di mana sebuah simpul internal disajikan sebagai daun. keccak-256 bukan SHA3-256; keduanya berbagi permutasi tetapi berbeda pada satu bita padding, dan verifikator on-chain berbicara keccak, jadi substitusi diam-diam akan membuat setiap akar gagal on-chain. Karena itu lapisan hashing menghitung algoritma yang diminta atau melempar galat, tak pernah kembarannya, dan mencatat algoritma di setiap kapsul agar seorang verifikator mereproduksi fungsi yang persis alih-alih menyimpulkannya dari apa yang terpasang secara lokal.
| Primitif, masukan 64 B | Throughput | Catatan |
|---|---|---|
| SHA-256 (stdlib) | 1,50M ops/s | dasar, selalu ada |
| BLAKE3 (pip) | 1,44M ops/s | setara dengan SHA-256 |
| keccak-256 (pip) | 99k ops/s | 15x lebih lambat, si penyempit |
| keccak-256 (inti Rust) | 1,69M ops/s | 17x lebih cepat dari pip |
keccak tak punya implementasi di pustaka standar, dan itulah yang membuat modul natif layak dibangun. Selisihnya terlebar pada masukan seukuran peristiwa karena biaya pycryptodome di sana adalah alokasi objek per panggilan, bukan hashing, tepat ukuran yang paling sering di-hash oleh jejak audit; dari ujung ke ujung, inti natif menaikkan penyegelan eksekusi 1000 peristiwa dari 78 menjadi 491 segel per detik, sekitar 6x. Yang krusial: mengaktifkan akselerator tak dapat mengubah hasil: menyegel eksekusi yang sama dengan dan tanpa crate menghasilkan akar yang identik bit demi bit, sebuah suite konformansi memeriksa kedua jalur terhadap vektor yang diterbitkan penulis algoritma, dan CI membangun satu wheel ABI stabil (abi3) dan memverifikasi satu artefak itu pada setiap Python dari 3.10 hingga 3.14. Memasangnya mengubah kecepatan dan tak lebih.
Tanda tangan untuk catatan sepuluh tahun
Sebuah tanda tangan pada catatan audit harus bertahan selama catatan itu dapat disengketakan, dan kewajiban pencatatan AI kini merangkak menuju satu dekade. Jika skema jebol saat catatan masih dalam jendela retensinya, seorang lawan dapat memalsukan dan memundurkan tanggalnya, sehingga seluruh arsip gagal sekaligus. Kami membandingkan Ed25519 dengan ECDSA, BLS, dan keluarga pasca-kuantum NIST ML-DSA, pada throughput dan ukuran.
| Skema | Verifikasi (ops/s) | Ukuran tanda tangan |
|---|---|---|
| ECDSA P-256 | 16 887 | ~72 B |
| ML-DSA-44 (pasca-kuantum) | 10 725 | 2420 B |
| Ed25519 | 10 375 | 64 B |
| BLS12-381 | hanya impl. rujukan | 96 B, mengagregasi |
Dua hasil menjungkirkan asumsi yang kami bawa, dan keduanya kami simpan dalam catatan. Ed25519 bukan yang tercepat diverifikasi: ECDSA P-256 terukur sekitar 1,6x lebih cepat, di atas assembly pustaka yang dioptimalkan. Ed25519 tetap menjadi default pada ukuran tanda tangan dan pada determinisme (RFC 8032), yang menghapus kegagalan pemakaian ulang nonce ECDSA yang membocorkan kunci privat sementara tanda tangan masih terverifikasi. Dan tanda tangan pasca-kuantum tak lambat diverifikasi: ML-DSA-44 sedikit melampaui Ed25519, dengan biayanya pada penandatanganan (sekitar 13x lebih lambat) dan ukuran (sekitar 38x bita). Karena sebuah jejak ditandatangani sekali dan diverifikasi bertahun-tahun, sisi yang mahal adalah sisi yang paling jarang kami lakukan. BLS ditolak atas sebuah persyaratan, bukan sebuah angka: agregasi meruntuhkan banyak tanda tangan menjadi 96 bita, tetapi sebuah agregat terverifikasi semua-atau-tak-satu pun dan memerlukan setiap kunci dan pesan, yang tak sejalan dengan menyingkap satu cabang keputusan tanpa mengungkap sisanya.
Pembingkaian ulang yang penting: tanda tangan tidak rahasia, jadi "panen sekarang, dekripsi nanti" tak berlaku, dan ancaman nyatanya adalah pemalsuan retroaktif dalam jendela retensi. Menambatkan akar ke buku besar publik membuktikan kapan sebuah catatan ada, terlepas dari skema tanda tangan, sehingga kunci yang jebol menelan kemampuan membuktikan siapa yang menyegel catatan tetapi bukan kapan atau apa. Karena itu penambatan berada di jalur kritis dan ML-DSA ditata bertahap di belakangnya, dengan amplop DSSE dijaga gesit-algoritma dan algoritma dicatat per kapsul.
Jejak audit per eksekusi
Setiap eksekusi adalah urutan peristiwa hanya-tambah dan terantai-hash (panggilan LLM, panggilan alat, pengambilan, pemunculan sub-agen, persetujuan manusia, keputusan pagar pengaman), dengan sebuah akar Merkle atas semuanya dan tanda tangan DSSE atas akar. Hanya hash dari masukan dan keluaran yang disimpan, tak pernah muatannya, jadi jejak menjaga privasi secara default. Verifikator tak sekadar mengembalikan sah atau tak sah; ia menamai jaminan yang jebol.
| Operasi (eksekusi 102 peristiwa) | Biaya | Penskalaan |
|---|---|---|
| Mencatat satu peristiwa | ~121 us | datar, di bawah 0,01% satu langkah |
| Menyegel, membangun akar | 0,15 ms | linear pada peristiwa |
| Memverifikasi, menghitung ulang semua daun | 9,2 ms | linear, sekitar 60x penyegelan |
Mencatat adalah kurang dari seperseratus persen sebuah langkah agen biasa, yang didominasi oleh perjalanan bolak-balik model, jadi overhead bukan alasan untuk menyampel dan jejak tetap lengkap alih-alih statistik. Verifikasi jauh lebih berat daripada penyegelan karena ia menghitung ulang setiap daun dari konten sementara penyegelan hanya membangun pohon atas hash yang sudah ada. Asimetri itu benar untuk sebuah jejak audit, tempat mencatat konstan dan verifikasi jarang, dan ia menandai verifikasi ulang massal sebagai tempat inti natif dan paralelisme berbuah berikutnya. Untuk mengonkretkan jaminan, sebuah demo menyerang eksekusi tersegel dengan delapan cara, masing-masing ditolak dengan alasan spesifik:
| Serangan | Ditolak sebagai |
|---|---|
| Menulis ulang keluaran model | ketidakcocokan hash daun |
| Menghapus atau menyisipkan peristiwa | ketidakcocokan jumlah peristiwa |
| Mengurutkan ulang peristiwa | putus rantai |
| Memangkas eksekusi | ketidakcocokan kepala rantai |
| Menurunkan algoritma hash | ketidakcocokan hash daun |
| Menyajikan di bawah kunci yang salah | tanda tangan tak terverifikasi |
Log transparansi antar-eksekusi
Sebuah kapsul per eksekusi yang sah tak dapat membuktikan bahwa himpunan eksekusi lengkap. Seorang operator yang membuang eksekusi yang tak nyaman memegang koleksi kapsul yang masing-masing sempurna dan sebuah riwayat berlubang. Kami menutupnya dengan satu log hanya-tambah berisi akar-akar kapsul yang mendukung bukti inklusi (sebuah eksekusi ada di log) dan bukti konsistensi (log pada ukuran lebih awal adalah awalan persis dari log sekarang). Konsistensi menangkap penyensoran: sebuah log yang dibangun ulang dengan satu eksekusi dibuang secara internal berbentuk baik dan setiap kapsul yang selamat masih terverifikasi, tetapi ia gagal pada pemeriksaan konsistensi terhadap akar yang diterbitkan sebelumnya, dan pemeriksaan yang sama menolak sisipan yang tanggalnya dimundurkan. Ini hanya bekerja terhadap akar yang di-commit sebelum gangguan, jadi akar itu harus tinggal di suatu tempat yang tak dapat direvisi operator, seperti sebuah tambatan publik.
Kami memakai Merkle Mountain Range alih-alih pohon Merkle biasa karena sebuah penambahan hanya menambah simpul dan tak pernah menulis ulang satu pun, yang membiarkan log tinggal di penyimpanan tulis-sekali atau objek dan menjaga bukti inklusi lama tetap sah seiring log tumbuh. Sifat itu nyaris optimal, bukan sekadar nyaman: ePrint 2025/234 membuktikan bahwa setiap komitmen hanya-tambah yang ringkas mesti memicu jumlah pembaruan saksi yang superlinear, dan sebuah varian MMR yang dekat pada dasarnya mencapai batas itu.
| Ukuran log | Pembangunan MMR | Pembangunan ulang biasa |
|---|---|---|
| 500 | 1,3 ms | 158 ms (120x) |
| 1000 | 2,6 ms | 618 ms (237x) |
| 2000 | 5,2 ms | 2491 ms (483x) |
Penambahan tetap datar seiring log tumbuh (sekitar 390k penambahan per detik baik pada 100 maupun 10 000 entri) sementara membangun ulang pohon biasa turun dari 8176 ke 84 akar per detik pada rentang yang sama, tanda tangan kuadratik-lawan-linearitmik. Penyimpanan mengendap pada 2,00 hash tersimpan per entri dan bukti inklusi tumbuh hanya dari 7 ke 17 langkah antara 100 dan 100 000 entri. Di mana kami kalah: bukti konsistensi kami adalah O(log^2 n), membawa satu jalur per puncak log lama alih-alih O(log n) yang dapat dicapai, beberapa kilobita pada 100 000 entri dan pertukaran yang disengaja demi konstruksi yang dapat diperiksa seorang peninjau dengan membaca.
Batas yang tak kami lampaui
Hashing memberi bukti gangguan, bukan kekebalan gangguan. Seorang lawan yang membangun ulang sebuah eksekusi dan menghitung ulang akarnya menghasilkan catatan yang konsisten-sendiri, karena akar Merkle membuktikan peristiwa cocok dengan akar, bukan bahwa akar itu adalah yang diterbitkan. Tanda tangan menangkap itu, dan tambatan publik membuktikan waktunya. Log transparansi bertumpu pada asumsi yang sama dalam skala besar: ia mendeteksi eksekusi yang terhapus hanya relatif terhadap akar yang di-commit sebelum penghapusan. Kami menyatakan batas-batas ini dalam produk dan demonya, dan sebuah tes menegaskan bahwa demo pemalsuan terus menunjukkan serangan yang tak kami hentikan, agar kasus yang jujur tak dapat lenyap diam-diam.
Reproduktibilitas
Setiap angka di sini berasal dari sebuah benchmark yang di-commit yang berjalan ulang dalam satu perintah, bersama tes-tes, suite konformansi antar-bahasa dan antar-implementasi, serta matriks CI yang melatih Python 3.10 hingga 3.14 dengan dan tanpa inti natif. Metodologi, JSON mentah, dan catatan keputusan (termasuk dimensi tempat setiap pilihan kalah) ada di repositori, karena lapisan yang membuat AI dapat diaudit haruslah dapat diaudit pula.