इस पृष्ठ को पढ़कर उस मशीन को समझें जो Rand पर हर प्रूफ़ के पीछे है: वह क्या सिद्ध करती है, किसी प्रोग्राम का एक रन ऐसी चीज़ में कैसे बदलता है जिसे वैलिडेटर मिलीसेकंडों में जाँच सके, और गोपनीयता कहाँ से आती है। प्रूफ़ की लागत और वॉलेट उसे कैसे बनाता है, यह जानने के लिए प्रूफ़ देखें। पैरामीटर और हैश संरचनाओं के लिए क्रिप्टोग्राफ़ी देखें। जिस निर्देश-समुच्चय के आधार पर प्रोग्राम लिखा जाता है, उसके लिए RISC-V ISA देखें।
वह एक कथन जो हर प्रूफ़ करता है
चेन जो भी प्रोग्राम चलाती है, उन सबके लिए zkVM एक ही प्रकार का कथन सिद्ध करता है:
एक प्रोग्राम, जिसका डाइजेस्ट
hcहै,base_pcसे आरंभ हुआ,H_INद्वारा कमिट किए गए निजी इनपुट औरH_PUBद्वारा कमिट किए गए सार्वजनिक इनपुट सेगमेंट पर चला,2ᵗ − 1चक्रों के भीतर रुका, अधिकतमGAS_LIMITगैस ख़र्च की और ये आठ आउटपुट शब्द लिखे।
शील्डेड ट्रांसफ़र एक निश्चित प्रोग्राम के बारे में यही कथन है। वह प्रोग्राम hidden-asset bundle guest है, जिसका hc जेनेसिस फ़ाइल में hc_bundle के रूप में निर्धारित है। चेन 17 से हर ट्रांसफ़र के लिए यह कथन दो बार बनाया जाता है: auth guest (जेनेसिस फ़ाइल में hc_auth) के बारे में एक दूसरा, छोटा प्रूफ़ दिखाता है कि प्रेषक के पास स्पेंड की है (प्रूफ़)। गोपनीय कॉल किसी डिप्लॉय किए गए प्रोग्राम के बारे में यही कथन है। इन सबके लिए एक ही मशीन, एक ही वेरिफ़ायर और कंस्ट्रेंट्स का एक ही समुच्चय है। इसलिए प्रोग्राम डिप्लॉय करना एक डेटा ऑपरेशन है (उसके शब्द और hc संग्रहीत करना), क्रिप्टोग्राफ़िक ऑपरेशन नहीं: न हर प्रोग्राम के लिए अलग सर्किट है और न ही कोई ट्रस्टेड सेटअप।
प्रूफ़ प्रणाली Plonky3 से बनी एक STARK है। इसे हैश फ़ंक्शन के अलावा कुछ नहीं चाहिए: न सेटअप समारोह और न ही एलिप्टिक कर्व, इसलिए इसमें Shor के एल्गोरिदम के तोड़ने लायक कुछ नहीं है।
पाइपलाइन
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
ऊपरी पंक्ति प्रेषक की मशीन पर एक बार चलती है: बंडल के लिए लगभग 100 सेकंड में और उसके साथ के ऑथराइज़ेशन प्रूफ़ के लिए लगभग 7 सेकंड में। निचली पंक्ति हर वैलिडेटर पर केवल सार्वजनिक फ़ील्ड और प्रूफ़ के आधार पर चलती है।
1. प्रोग्राम चलाएँ और सब कुछ दर्ज करें
यह मशीन एक 32-बिट RISC-V प्रोसेसर है: RV32IM, जिसमें FENCE, CSR निर्देश और EBREAK शामिल नहीं हैं (RISC-V ISA)। प्रूवर पहले प्रोग्राम को एक एमुलेटर पर चलाता है और हर क्लॉक टिक के लिए एक पंक्ति दर्ज करता है। यह रिकॉर्ड एक्ज़ीक्यूशन ट्रेस है। जिसके पास यह हो, वह रन को चरण-दर-चरण दोहरा सकता है। योजना का शेष भाग इसीलिए है कि वेरिफ़ायर ट्रेस अपने पास रखे बिना आश्वस्त हो सके कि ट्रेस सही है।
प्रोग्राम बाहरी दुनिया से केवल आठ सिस्टम कॉल के माध्यम से संवाद करता है, किसी और माध्यम से नहीं:
| सिस्टम कॉल | क्रमांक | यह क्या करता है |
|---|---|---|
HALT | 0 | रुकना; आठ आउटपुट शब्द अंतिम हो जाते हैं |
WRITE_OUTPUT | 1 | आठ सार्वजनिक आउटपुट शब्दों में से एक सेट करना |
READ_INPUT | 2 | निजी इनपुट का एक शब्द पढ़ना |
POSEIDON2 | 3 | मेमोरी में एक बफ़र को उसी स्थान पर हैश करना |
KECCAK | 4 | एक Keccak-f[1600] परम्यूटेशन |
SHA256 | 5 | एक SHA-256 कम्प्रेशन |
READ_PUBLIC | 6 | सार्वजनिक इनपुट सेगमेंट का एक शब्द पढ़ना |
POSEIDON2_LEN | 7 | POSEIDON2, जिसमें संदेश की लंबाई हैश में बाँधी जाती है (कंस्ट्रेंट सेट 7) |
नोट कमिटमेंट, नलिफ़ायर और Merkle पथ मशीन में अंतर्निहित नहीं हैं। ये सामान्य गेस्ट कोड हैं, जो मेमोरी में डोमेन-टैग वाला संदेश तैयार करके POSEIDON2 को कॉल करता है। यह सिस्टम कॉल पैडिंग नहीं करता, इसलिए [a] और [a, 0] का हैश एक जैसा होता है। उपलब्ध कराए गए गेस्ट इसे केवल निश्चित लंबाई वाले संदेशों पर कॉल करते हैं। जो नया प्रोग्राम बदलती लंबाई वाले डेटा को हैश करता है, वह POSEIDON2_LEN का उपयोग करता है (RISC-V ISA)।
निरस्तीकरण का कोई विकल्प नहीं है
प्रोसेसर में ऐसा कोई निर्देश नहीं है जो रन पूरा करने से इनकार करे, इसलिए किसी जाँच के विफल होने पर प्रोग्राम रुक नहीं सकता। इसके बजाय बंडल गेस्ट विफलता को दर्ज करता है: हर विफल जाँच bad नामक रजिस्टर में 1 को OR करती है, और bad आउटपुट डाइजेस्ट में हैश किया जाने वाला अंतिम शब्द है:
D = H(64; anchor, nf₀..₃, cm₀..₃, fee, burn_a, burn_r, burn_asset, time, c, bad)
c वह ऑथराइज़ेशन कमिटमेंट है जिसे ऑथ प्रूफ़ भी प्रकाशित करता है (चेन 17 से; चेन 14 से 16 तक के डाइजेस्ट में c नहीं था)।
चेन D का प्रीइमेज कभी प्रेषक से नहीं लेती। वह ट्रांज़ैक्शन के सार्वजनिक फ़ील्ड से प्रीइमेज को फिर से बनाती है, स्वयं bad = 0 सेट करती है, हैश करती है और तुलना करती है। धोखेबाज़ ऐसे रन का पूर्णतः वैध प्रूफ़ बना सकता है जिसमें कोई जाँच विफल हुई हो, लेकिन उस रन ने H(…, 1) लिखा, जबकि चेन H(…, 0) खोज रही है। दोनों का मेल कराने के लिए हैश कोलिज़न चाहिए।
2. ट्रेस को नौ तालिकाओं में बाँटें
पूरे प्रोसेसर का वर्णन करने वाली एक ही तालिका अनावश्यक रूप से चौड़ी होती, इसलिए ट्रेस को विशेषीकृत तालिकाओं में बाँटा जाता है, जिन्हें एक बैच के रूप में एक साथ सिद्ध किया जाता है:
| तालिका | टियर t पर पंक्तियाँ | यह क्या दर्ज करती है |
|---|---|---|
program | घोषित, ≥ 2⁷ | प्रोग्राम के निर्देश शब्द, सर्किट में डिकोड किए गए; तय करती है कि CPU क्या फ़ेच कर सकता है |
cpu | 2ᵗ | प्रति चक्र एक पंक्ति, जिनसे पहले वे पंक्तियाँ आती हैं जो प्रोग्राम, निजी इनपुट और सार्वजनिक सेगमेंट को हैश करती हैं; 35 सार्वजनिक मान रखती है |
memory | घोषित, ≥ 2ᵗ⁺² | रजिस्टर और RAM, (स्पेस, पता, समय) के क्रम में |
alu | 2ᵗ⁺¹ | हर अंकगणितीय, तार्किक, शिफ़्ट, तुलना, गुणा और भाग ऑपरेशन, बाइट लिंब पर |
range, nibble | प्रत्येक 256 | निश्चित लुक-अप तालिकाएँ: बाइट, दो की घातें, 4-बिट AND/OR/XOR |
poseidon2 | 2ᵗ⁺² | हैश परम्यूटेशन, प्रति राउंड एक पंक्ति |
input | घोषित, ≥ 2⁷ | कमिट किए गए निजी इनपुट शब्द |
public | घोषित, ≥ 2⁷ | सार्वजनिक सेगमेंट के शब्द (बंडल के लिए, ट्रांज़ैक्शन बाइंडिंग) |
दो और तालिकाएँ, keccak और sha256, केवल उसी प्रूफ़ में मौजूद होती हैं जिसके प्रोग्राम ने उन्हें कॉल किया हो, और मौजूद होने पर प्रत्येक में कम से कम 2⁷ पंक्तियाँ होती हैं; बंडल गेस्ट इनमें से किसी का उपयोग नहीं करता। हर घोषित तालिका पर 2⁷ पंक्तियों की न्यूनतम सीमा कंस्ट्रेंट सेट 7 के साथ आई (खंड 9)।
टियर t का मान 10, 12, 14, 16, 18 या 20 में से एक होता है, और यही तालिकाओं का आकार तय करता है। हर बंडल टियर 14 पर सिद्ध किया जाता है: 16,384 पंक्तियों वाली CPU तालिका, जिनमें से गेस्ट लगभग 12,400 का उपयोग करता है। ऑथ गेस्ट टियर 10 पर 250 चक्र चलता है। शेष पैडिंग है, इसलिए प्रूफ़ यह प्रकट करता है कि प्रोग्राम को किस टियर की आवश्यकता थी, यह कभी नहीं कि उसके भीतर उसने कितने चरण लिए (टियर)।
मेमोरी तालिका ही RAM को जाँचने योग्य बनाती है। चूँकि यह पहले पते और फिर समय के क्रम में होती है, “कोई रीड उस पते पर लिखा गया अंतिम मान लौटाता है” यह शर्त दो आसन्न पंक्तियों के बीच का नियम बन जाती है।
3. तालिकाओं को बसों से जोड़ें
वेरिफ़ायर को कैसे पता चलता है कि CPU ने जिस योग का उपयोग किया, वह वही योग है जिसे ALU ने गणना की? बसों के माध्यम से। जब CPU को जोड़ की आवश्यकता होती है, तो वह एक संदेश (op, a, b, c) भेजता है; ALU अपनी गणना की गई हर पंक्ति के लिए एक संदेश प्राप्त करता है। मशीन में सत्रह बसें हैं:
| बस | किनके बीच |
|---|---|
PROGRAM, PROGRAM_WORD | cpu ← program: निर्देश फ़ेच, और वे शब्द जिन्हें प्रोग्राम डाइजेस्ट समाहित करता है |
MEMORY | cpu ↔ memory: हर रीड और राइट |
ALU | cpu → alu |
RANGE8, POW2, AND4, OR4, XOR4 | निश्चित तालिकाओं के विरुद्ध बाइट रेंज जाँच, शिफ़्ट और बिटवाइज़ ऑपरेशन |
POSEIDON2 | cpu → poseidon2: प्रति परम्यूटेशन एक संदेश |
INPUT_DIGEST, INPUT_READ | cpu ← input: वे शब्द जिन्हें इनपुट डाइजेस्ट समाहित करता है, और प्रोग्राम के रीड |
PUBLIC_DIGEST, PUBLIC_READ | cpu ← public: सार्वजनिक सेगमेंट के लिए वही जोड़ी |
KECCAK, SHA256 | cpu → वैकल्पिक हैश तालिकाएँ |
BLIND | हर तालिका → एक निश्चित चक्र में अगली तालिका: पहली पंक्ति पर प्रत्येक का एक यादृच्छिक मान (कंस्ट्रेंट सेट 7) |
बसों की जाँच लॉगरिदमिक-डेरिवेटिव तर्क (LogUp) से की जाती है। तालिकाओं के कमिट होने के बाद एक यादृच्छिक मान α चुना जाता है, और प्रत्येक तालिका अपने भेजे या प्राप्त किए गए संदेशों पर ±1/(α − m) का संचयी योग रखती है। ये योग ठीक तभी और केवल तभी निरस्त होते हैं जब भेजा गया हर संदेश प्राप्त हुआ हो, यानी दोनों ओर एक ही मल्टीसेट हो। एक भी जाली संदेश ऐसा अवशेष छोड़ता है जिसे यादृच्छिक α अत्यधिक प्रायिकता के साथ उजागर कर देता है। मेमोरी बस इसकी निकट संबंधी विधि, मल्टीसेट परम्यूटेशन जाँच, का उपयोग करती है।
प्रत्येक तालिका अपने संचयी योग का अंतिम मान, यानी अपना टर्मिनल, प्रकाशित करती है, और वेरिफ़ायर जाँचता है कि सभी टर्मिनलों का योग शून्य है। कंस्ट्रेंट सेट 6 तक टर्मिनल अपनी तालिका की सामग्री का एक जाँचने योग्य फ़ंक्शन था। कंस्ट्रेंट सेट 7 से हर तालिका में पाँच अतिरिक्त कॉलम होते हैं, और अपनी पहली पंक्ति पर वह BLIND बस पर एक यादृच्छिक मान भेजती है और अपनी पड़ोसी तालिका का मान प्राप्त करती है। इससे प्रत्येक टर्मिनल चैलेंज फ़ील्ड के एक समान रूप से वितरित अवयव जितना खिसक जाता है, और योग शून्य ही रहता है।
डाइजेस्ट और रीड बसें जानबूझकर अलग-अलग जोड़ियों में हैं। LogUp संतुलन प्रति संदेश होता है, प्रति उपभोक्ता नहीं, इसलिए एक साझा बस होने पर प्रूवर डाइजेस्ट से कोई शब्द हटा सकता था, जबकि उसी शब्द का रीड फिर भी सफल हो जाता।
4. ट्रेस को बाहरी दुनिया से जोड़ें
पैंतीस सार्वजनिक मान ट्रेस से बाहर आते हैं, सभी CPU तालिका में:
| मान | ये क्या हैं |
|---|---|
| 1 | प्रवेश pc |
| 1 | टियर |
| 8 | आउटपुट वर्ड (बंडल के लिए, डाइजेस्ट D) |
| 8 | hc, प्रोग्राम डाइजेस्ट, जिसकी गणना प्रोग्राम टेबल के वर्ड से ट्रेस के भीतर होती है |
| 8 | H_IN, निजी इनपुट डाइजेस्ट, जो इनपुट पर निकाला जाता है और जिसमें सबसे पहले एक नया 128-बिट सॉल्ट जुड़ता है |
| 8 | H_PUB, सार्वजनिक सेगमेंट डाइजेस्ट, बिना सॉल्ट |
| 1 | GAS_LIMIT, गैस की वह अधिकतम सीमा जो प्रूवर घोषित करता है (कंस्ट्रेंट सेट 8) |
चूँकि hc की गणना सर्किट के भीतर होती है, इसलिए किसी दूसरे प्रोग्राम का प्रूफ़ बंडल गेस्ट के प्रूफ़ के रूप में मान्य नहीं हो सकता। वेरिफ़ायर कभी कोई निर्देश-वर्ड नहीं देखता। वह hc की तुलना उस डाइजेस्ट से करता है जिसकी उसे अपेक्षा है। चूँकि H_IN सॉल्टेड है, इसलिए यह निजी इनपुट को उससे बाँध देता है पर उसे प्रकट नहीं करता। उस व्यक्ति के सामने भी नहीं जो उसका अनुमान लगा सकता हो। चूँकि H_PUB बिना सॉल्ट का है, इसलिए वेरिफ़ायर इसकी गणना उन वर्ड से दोबारा कर सकता है जो उसके पास पहले से हैं। बंडल के लिए ये वर्ड ट्रांज़ैक्शन बाइंडिंग हैं, यानी blake3("rand-tx-bind-1" ‖ chain_id ‖ tx)। इसकी गणना ट्रांज़ैक्शन पर होती है, जिसमें प्रूफ़ बाइट्स रिक्त कर दिए जाते हैं। इसलिए यदि किसी प्रूफ़ को ऐसे ट्रांज़ैक्शन पर कॉपी किया जाए जिसका गंतव्य, मेमो, एनवेलप या चेन आईडी भिन्न हो, तो वह सत्यापित नहीं होता। चेन 20 पर (जेनेसिस binding_domain: 1) यह blake3("rand-tx-bind-2" ‖ genesis_hash ‖ chain_id ‖ tx) है। इसलिए चेन आईडी एक ही होने पर भी कोई प्रूफ़ दूसरी चेन पर सत्यापित नहीं होता। ये वर्ड सार्वजनिक इनपुट हैं, इसलिए इस बदलाव से सर्किट में कुछ नहीं बदला। ऑथ प्रूफ़ भी इन्हीं आठ वर्ड पर बनता है। चेन 20 पर कॉल प्रूफ़ भी इसी तरह बँधा होता है। उसके सेगमेंट में पहले प्रोग्राम के डिप्लॉय-समय के सार्वजनिक वर्ड आते हैं और उनके बाद कॉल बाइंडिंग के आठ वर्ड (rand-call-bind-2, जो चेन 20 से पहले rand-call-bind-1 था)। इसलिए किसी दूसरे फ़ी बंडल में कॉपी किया गया कॉल प्रूफ़ सत्यापित नहीं होता।
गैस वह मशीनी माप है जिससे किसी रन का भार मापा जाता है। कंस्ट्रेंट सेट 8 से यह सर्किट का हिस्सा है। CPU टेबल में एक GAS कॉलम होता है जो 1 से शुरू होता है। हर पंक्ति पर इसमें 1 जुड़ता है, Poseidon2 एब्ज़ॉर्ब पंक्ति पर 3, SHA256 पंक्ति पर 64 और KECCAK पंक्ति पर 192। HALT पंक्ति पर सर्किट GAS ≤ GAS_LIMIT सिद्ध करता है। इसके लिए वह अंतर के चार रेंज-चेक किए गए लिंब का उपयोग करता है, जिन्हें कभी खोला नहीं जाता। सीमा सार्वजनिक होती है, पर किसी रन में खर्च हुई गैस सार्वजनिक नहीं होती। वेरिफ़ायर कुंजी बनाने से पहले ही ऐसी किसी भी सीमा को अस्वीकार कर देता है जो प्रूफ़ के अपने हेडर की अधिकतम संभावित आवश्यकता से अधिक हो:
gas_max(t, k, s) = (2ᵗ − 1) + 2ᵗ⁻² + 191·(2ᵏ / 32) + 63·(2ˢ / 64)
यहाँ k और s क्रमशः keccak और sha256 टेबल की घोषित लॉग ऊँचाइयाँ हैं। कोई टेबल अनुपस्थित हो तो उसका पद शून्य होता है। हैश-रहित टियर-10 हेडर की अधिकतम सीमा 1,279 है और टियर-14 हेडर की 20,479। चेन किसी कॉल का शुल्क उसकी घोषित सीमा के आधार पर तय करती है (शुल्क)।
5. नियमों को बहुपद सर्वसमिकाओं में बदलें
हर कॉलम Goldilocks फ़ील्ड की संख्याओं की एक सूची होता है। ये संख्याएँ p = 2⁶⁴ − 2³² + 1 मॉड्यूलो पूर्णांक हैं। n संख्याओं की सूची और n से कम घात वाला बहुपद एक ही चीज़ हैं। जब इन संख्याओं को फ़ील्ड के उपसमूह {1, ω, ω², …} पर रखा जाता है, तो वह बहुपद इन सभी से होकर गुज़रता है। Goldilocks में 2³² तक के दो की हर घात वाले आकार के ऐसे उपसमूह मौजूद हैं, इसलिए यह रूपांतरण फ़ास्ट फ़ूरिए ट्रांसफ़ॉर्म से हो जाता है।
तब मशीन का हर नियम कॉलम बहुपदों के बीच एक समीकरण बन जाता है। उदाहरण के लिए, “निर्देश जंप न करे तो प्रोग्राम काउंटर चार आगे बढ़ता है” योजनात्मक रूप से यह बन जाता है:
is_jump(x)·(pc(ωx) − target(x)) + (1 − is_jump(x))·(pc(ωx) − pc(x) − 4) = 0
यह उपसमूह के हर x के लिए लागू होता है, और pc(ωx) का अर्थ है “अगली पंक्ति”। किसी टेबल के ऐसे सभी नियमों का पूरा समुच्चय उसका AIR (बीजीय मध्यवर्ती निरूपण) कहलाता है। CPU और ALU के नियम घात 8 तक पहुँचते हैं, जबकि बाकी 2 से 4 तक रहते हैं।
जो बहुपद उपसमूह के हर बिंदु पर शून्य हो, वह Z(x) = xⁿ − 1 से विभाज्य होता है। प्रूवर यादृच्छिक भारों के साथ सभी नियमों को एक बहुपद C(x) में जोड़ता है और उसे Z(x) से भाग देता है। यदि हर नियम हर पंक्ति पर सही है, तो भागफल सचमुच निम्न-घात बहुपद होता है। यदि एक भी नियम एक भी पंक्ति पर विफल हो, तो भागफल ऐसा नहीं होता। इस तरह प्रश्न “क्या 16,000 चक्रों वाले रन का हर चरण सही था?” बदलकर “क्या यह फ़ंक्शन किसी निम्न-घात बहुपद के निकट है?” बन गया है। इस प्रश्न का उत्तर यादृच्छिक रूप से चुने गए कुछ मान देखकर दिया जा सकता है।
6. प्रश्न जानने से पहले कमिट करें
प्रूवर को वेरिफ़ायर के यादृच्छिक प्रश्न देखने से पहले अपने बहुपद तय करने होते हैं। अन्यथा वह अपने उत्तर उन प्रश्नों के अनुरूप ढाल सकता है। वह हर कॉलम का मूल्यांकन टेबल से आठ गुना बड़े डोमेन पर करता है (ब्लो-अप 8, कोड दर 1/8) और इन मूल्यांकनों पर एक Merkle रूट प्रकाशित करता है। यह अतिरेक एक Reed–Solomon कोड है। निम्न-घात बहुपद उसके मानों के किसी भी आठवें हिस्से से पूरी तरह तय हो जाता है। इसलिए जो धोखेबाज़ ट्रेस की एक भी पंक्ति बदले, उसे संगति बनाए रखने के लिए विस्तारित कोडवर्ड का अधिकांश भाग बदलना पड़ता है, और यादृच्छिक स्पॉट-चेक उस क्षति पर पड़ ही जाते हैं।
Merkle ट्री Goldilocks पर Poseidon2 का उपयोग करते हैं। इसकी चौड़ाई 8 है, S-box x⁷ है, और इसमें 4 पूर्ण राउंड, 22 आंशिक राउंड और फिर 4 पूर्ण राउंड होते हैं। इसके डाइजेस्ट चार फ़ील्ड तत्वों के होते हैं (लगभग 256 बिट)। हर लीफ़ को नई यादृच्छिकता के चार तत्वों के साथ हैश किया जाता है, इसलिए कोई भी रूट अपने नीचे के मानों के बारे में कुछ प्रकट नहीं करता। मशीन के भीतर नोट कमिटमेंट और नलिफ़ायर हैश भी यही परम्यूटेशन है। इसके 86 राउंड स्थिरांक नोड के सोर्स (poseidon2_constants.rs) में एक शाब्दिक तालिका के रूप में लिखे हैं, इसलिए कोई भी लाइब्रेरी अपग्रेड उन्हें बदल नहीं सकता।
7. FRI से स्पॉट-चेक करें
अब वेरिफ़ायर के पास Merkle रूट हैं। वह सबसे पहले भागफल को ट्रेस से जोड़ता है। इसके लिए वह टेबल के डोमेन के बाहर एक यादृच्छिक बिंदु z चुनता है और उस बिंदु पर हर कॉलम का मान और भागफल का मान माँगता है। फिर वह C(z) = Q(z)·Z(z) को सीधे जाँचता है। अब बस यह पुष्टि करनी बाकी है कि कमिट किए गए फ़ंक्शन सचमुच निम्न-घात बहुपद हैं, और यही FRI जाँचता है।
FRI फ़ोल्डिंग से काम करता है। पहले बहुपद को सम और विषम भागों में बाँटा जाता है: f(x) = fₑ(x²) + x·fₒ(x²)। वेरिफ़ायर से मिले यादृच्छिक β के लिए f′(y) = fₑ(y) + β·fₒ(y) की घात आधी होती है और उसका डोमेन भी आधे आकार का होता है। प्रूवर f′ पर कमिट करता है, नया β प्राप्त करता है और फिर से फ़ोल्ड करता है (Rand हर राउंड में अधिकतम आठ गुना फ़ोल्ड करता है)। यह तब तक चलता है जब तक एक स्थिरांक न बचे, जिसे प्रूवर खुले रूप में भेज देता है। फिर एक क्वेरी पहली परत में एक यादृच्छिक स्थान चुनती है और उसका नीचे तक अनुसरण करती है। हर परत पर वह जाँचती है कि ऊपर खोले गए मान फ़ोल्ड होकर नीचे वाले मान में बदलते हैं। जो फ़ंक्शन निम्न-घात से दूर था, वह ये सारे वादे संगत नहीं रख सकता।
Rand 80 क्वेरी चलाता है। सिद्ध प्रॉक्सिमिटी-गैप्स प्रमेय के अनुसार हर क्वेरी पर धोखेबाज़ के सफल होने की संभावना अधिकतम 9/16 रहती है, इसलिए 80 क्वेरी से (9/16)⁸⁰ ≈ 2⁻⁶⁶·⁴ मिलता है। तैनात STARK जिस ethSTARK अनुमान पर निर्भर करते हैं, उसके अनुसार हर क्वेरी पर यह संभावना 1/8 है, जो कहीं कम है।
8. संवाद हटाएँ
ऊपर सब कुछ एक संवाद के रूप में बताया गया, पर ट्रांज़ैक्शन को ऐसा एकल संदेश होना चाहिए जिसे कोई भी वैलिडेटर अकेले जाँच सके। Fiat–Shamir रूपांतरण वेरिफ़ायर को हटा देता है। प्रूवर हर “यादृच्छिक” चुनौती की गणना अब तक कमिट की गई हर चीज़ के हैश के रूप में करता है। इसके लिए Poseidon2 डुप्लेक्स स्पंज का उपयोग होता है। किसी एक कमिटमेंट को बदलने से उसके बाद की हर चुनौती बदल जाती है, इसलिए प्रूवर चुनौतियों के अनुरूप कमिटमेंट नहीं चुन सकता।
इससे जो कमियाँ रह जाती हैं, उन्हें दो और उपाय दूर करते हैं:
- विस्तार फ़ील्ड।
2⁶⁴तत्वों वाला फ़ील्ड चुनौतियाँ चुनने के लिए बहुत छोटा है। धोखेबाज़ को बस इतना चाहिए कि कोई चुनौती बहुपद के कुछ गिने-चुने ख़राब मानों में से किसी एक पर पड़ जाए। इसमें उसकी सफलता की संभावना लगभगN/2⁶⁴होती है, चाहे कितनी भी क्वेरी चलाई जाएँ। इसलिए ट्रेस तो Goldilocks में ही रहता है, पर हर चुनौती उसके द्विघात विस्तार से चुनी जाती है, जिसमें लगभग2¹²⁸तत्व हैं। - ग्राइंडिंग। क्वेरी स्थान निकाले जाने से पहले प्रूवर को एक ऐसा नॉन्स खोजना होता है जिसका ट्रांसक्रिप्ट के साथ हैश 20 शून्य बिट से शुरू हो। इसमें लगभग दस लाख हैश लगते हैं। ईमानदार प्रूवर यह लागत एक बार चुकाता है। धोखेबाज़ तब तक क्वेरी स्थान दोबारा निकालता रहता है जब तक वे उसकी जालसाज़ी से न चूकें, इसलिए उसे यह लागत हर प्रयास पर चुकानी पड़ती है। Rand में कहीं भी प्रूफ़ ऑफ़ वर्क है तो सिर्फ़ यहीं, और इसका कंसेंसस से कोई संबंध नहीं है।
कुल मिलाकर क्वेरी से मिले 66.4 बिट और ग्राइंडिंग से मिले 20 बिट जुड़कर 86 बिट सिद्ध सुरक्षा देते हैं। अनुमान के अनुसार यह लगभग 100 बिट है, जहाँ विस्तार फ़ील्ड वाला पद सीमा तय करता है।
9. ज़ीरो नॉलेज कहाँ से आता है
STARK अपने आप में ज़ीरो-नॉलेज नहीं होता। क्वेरी स्थानों पर खोले गए मान ट्रेस बहुपदों के ही मान होते हैं, और सावधानी न बरती जाए तो वे जानकारी लीक करते हैं। Rand का कॉन्फ़िगरेशन चार परतें जोड़ता है:
- हर कमिट किया गया बहुपद यादृच्छिक बनाया जाता है (Plonky3 का हाइडिंग FRI चार यादृच्छिक कोडवर्ड मिलाता है)। इसलिए खोले गए 80 मानों को, वितरण के स्तर पर, ऐसा कोई भी व्यक्ति दोबारा बना सकता है जिसने ट्रेस कभी नहीं देखा;
- हर Merkle लीफ़ सॉल्टेड होता है, इसलिए रूट और ऑथेंटिकेशन पाथ कुछ प्रकट नहीं करते;
- प्रूवर की यादृच्छिकता हर प्रूफ़ के लिए ऑपरेटिंग सिस्टम से नए सिरे से ली जाती है, इसलिए एक ही भुगतान के दो प्रूफ़ आपस में असंबंधित दिखते हैं;
- हर घोषित टेबल में कम से कम
2⁷पंक्तियाँ होती हैं और हर LogUp टर्मिनल ब्लाइंड किया जाता है (कंस्ट्रेंट सेट 7)। प्रूफ़ हर टेबल को 80 क्वेरी बिंदुओं और डोमेन के बाहर के दो बिंदुओं पर खोलता है। हाइडिंग कमिटमेंट उतनी ही यादृच्छिक पंक्तियाँ मिलाता है जितनी टेबल में पंक्तियाँ हैं, इसलिए टेबल तभी छिपी रहती है जब उसमें कम से कम 82 पंक्तियाँ हों। ऐसी दो की सबसे छोटी घात 128 है।
लेयर 4 एक सुधार है। 2026-09-27 की समीक्षा ने उत्पादन प्रमाणों से 31 या उससे कम इनपुट शब्दों वाली कॉलों के निजी इनपुट पुनः प्राप्त कर लिए, किसी प्रोग्राम की छोटी प्रोग्राम तालिका से उसकी फ़ेच गणनाएँ पढ़ लीं, और किसी बंडल के अनब्लाइंडेड टर्मिनलों के आधार पर उसके वास्तविक इनपुट स्लॉट को डमी स्लॉट से अलग पहचान लिया। ये वे प्रमाण हैं जो चेन 15 और उससे पहले बनाए गए थे। चेन 16 (बाधा-समुच्चय 7, ब्रांच-रहित बंडल गेस्ट के साथ) ने तीनों को बंद कर दिया, और चेन 18 से 20 तक ये सुधार बने हुए हैं।
गारंटी रैंडम-ओरेकल मॉडल में सांख्यिकीय शून्य-ज्ञान की है। कोई प्रमाण क्या नहीं छिपाता, यह सटीक रूप से निर्धारित है: उसका टियर, उसकी घोषित तालिका ऊँचाइयाँ, और उसके सार्वजनिक मान, जिनमें गैस सीमा भी शामिल है। keccak या sha256 की घोषित ऊँचाई 0 होने का अर्थ है कि रन ने उस हैश का कभी उपयोग नहीं किया, इसलिए किसी कॉल प्रमाण का हेडर यह दिखाता है कि कॉल ने हैशिंग की या नहीं और, न्यूनतम सीमा से ऊपर, दो के गुणक की सटीकता तक कितनी बार की। बंडल के लिए सार्वजनिक मान और फ़ील्ड ये हैं: एंकर, चार नलिफ़ायर, चार प्रतिबद्धताएँ, शुल्क, बर्न, बर्न एसेट, समय, प्राधिकरण प्रतिबद्धता और लेनदेन बाइंडिंग। कोई ट्रांसफ़र जिस एसेट को स्थानांतरित करता है वह एक निजी इनपुट है, इसलिए चेन पर zUSD भुगतान और RAND भुगतान एक जैसे दिखते हैं। hc नियतात्मक है, इसलिए कोई भी यह बता सकता है कि प्रमाण बंडल गेस्ट से संबंधित है (मूल्य स्थानांतरित करने वाला हर प्रमाण ऐसा ही होता है) या, कॉल के मामले में, उसने कौन-सा डिप्लॉय किया गया प्रोग्राम चलाया।
10. वैलिडेटर क्या जाँचता है
Machine::verify_public(hc, words, proof) सबसे सस्ती जाँच से शुरू करके क्रमशः चलता है:
- प्रमाण के घोषित टियर और तालिका ऊँचाइयों की सीमा जाँची जाती है (
check_declared_heights), इससे पहले कि उनके आधार पर किसी भी चीज़ का आकार तय हो, ताकि त्रुटिपूर्ण हेडर की लागत कुछ तुलनाएँ भर हो, कई सेकंड का कुंजी निर्माण नहीं; बंडल को टियर 14 घोषित करना होगा और किसी भी हैश तालिका के बिना, और auth प्रमाण को टियर 10; - 35 सार्वजनिक मान हैं, प्रत्येक एक कैनोनिकल फ़ील्ड तत्व, जिनमें
pv[HC] = hc,pv[TIER]प्रमाण के टियर के बराबर, हर आउटपुट शब्द2³²से कम, औरGAS_LIMITहेडर केgas_maxसे अधिक नहीं; - बैच STARK एक सत्यापनकर्ता कुंजी के विरुद्ध सत्यापित होता है, जो प्रति प्रोग्राम नहीं बल्कि प्रति आकार
(tier, program, input, keccak, sha256, public heights)कैश की जाती है; H_PUBwordsके डाइजेस्ट के बराबर है, जो बंडल के लिए वह लेनदेन बाइंडिंग है जिसकी गणना नोड ने स्वयं की।
इनमें से किसी भी जाँच से पहले नोड हर प्रस्तुत या गॉसिप किए गए प्रमाण की कैनोनिकल एन्कोडिंग की जाँच करता है: उसका FRI फ़ोल्डिंग शेड्यूल वही होना चाहिए जो एक ईमानदार प्रमाणकर्ता हेडर में घोषित डिग्रियों के लिए बनाता है। fullnode v0.6.8 (audit v6, ZKV-4) से यह जाँच सबसे पहले 25 बिट से ऊपर की किसी भी घोषित डिग्री को अस्वीकार करती है (MAX_HONEST_DEGREE_BITS, यानी मेमोरी तालिका की 2²⁴ की अधिकतम सीमा और शून्य-ज्ञान के लिए दोगुनापन, जो किसी स्वीकृत प्रमाण में अधिकतम होता है)। इस सीमा से पहले, बहुत बड़ी डिग्री घोषित करने वाला हेडर नोड को अपने इवेंट लूप पर एक विशाल फ़ोल्डिंग शेड्यूल फिर से निकालने पर मजबूर करता था, और उसे तब तक रोके रखता था जब तक भेजने वाला चाहे; सत्यापनकर्ता उस प्रमाण को वैसे भी अस्वीकार कर देता, इसलिए यह सीमा केवल अस्वीकार करने की लागत बदलती है। जाँच के भीतर पैनिक होने पर अब नोड रुकता नहीं, बल्कि केवल वह एक लेनदेन अस्वीकार होता है।
इसके बाद लेजर bad = 0 के साथ बंडल डाइजेस्ट D की पुनर्गणना करता है और उसकी तुलना प्रमाण के आठ आउटपुट शब्दों से करता है। चेन 20 पर यह यह भी अनिवार्य करता है कि बंडल प्रमाण का GAS_LIMIT ठीक जेनेसिस के bundle_gas_limit, यानी 20,479, के बराबर हो, और auth प्रमाण का 1,279 हो, ताकि हर ट्रांसफ़र एक जैसे मान घोषित करे। वार्म कुंजी के साथ पूरी जाँच में लगभग 16 ms लगते हैं।
पैरामीटर, और उन्हें क्यों चुना गया
नीचे दी गई हर संख्या सर्वसम्मति का हिस्सा है: सत्यापनकर्ता उसकी जाँच करता है, किसी अन्य मान से बना प्रमाण सत्यापित नहीं होता, और इनमें से किसी को बदलना एक नया बाधा-समुच्चय और हार्ड फ़ोर्क है (बाधा-समुच्चय)। FRI प्रोफ़ाइल जेनेसिस फ़ाइल द्वारा तय होती है (चेन 20 पर fri_profile: production), प्रमाण द्वारा कभी नहीं।
| पैरामीटर | मान | यही मान क्यों |
|---|---|---|
| बेस फ़ील्ड | Goldilocks, p = 2⁶⁴ − 2³² + 1 | एक 64-बिट अभाज्य संख्या, जिसका अंकगणित कुछ ही मशीन निर्देशों में हो जाता है और जिसमें 2³² तक दो की हर घात के आकार के गुणात्मक उपसमूह हैं, इसलिए किसी कॉलम को बहुपद में बदलना एक फ़ास्ट फ़ूरिए ट्रांसफ़ॉर्म है। ट्रेस यहीं रहता है क्योंकि यही सस्ता फ़ील्ड है। |
| चैलेंज फ़ील्ड | द्विघात विस्तार F_p² (≈ 2¹²⁸) | स्वयं Goldilocks से लिए गए चैलेंज लगभग N/2⁶⁴ का एक साउंडनेस-तल छोड़ देते, जिसे क्वेरी की कोई भी संख्या नीचे नहीं ला सकती। विस्तार इस पद को 2²⁵ पंक्तियों तक के ट्रेस के लिए अधिकतम 2⁻¹⁰⁰ तक ले जाता है। बड़े फ़ील्ड की क़ीमत केवल चैलेंज चुकाते हैं; ट्रेस नहीं। यदि कभी 128 बिट आवश्यक हों, तो घन विस्तार (≈ 2¹⁹²) घोषित मार्जिन है। |
| ब्लो-अप | 8 (रेट ρ = 1/8, log_blowup = 3) | एक साथ दो कारण। CPU और ALU टेबलों के नियम डिग्री 8 के हैं, और ज़ीरो-नॉलेज फ़्लैग के साथ भागफल की डिग्री 9 हो जाती है, जो 8 का ब्लो-अप अधिकतम वहन कर सकता है; उच्चतर डिग्री का कोई नियम ब्लो-अप 16 को अनिवार्य कर देता। साथ ही, धोखेबाज़ को पकड़ने की प्रत्येक क्वेरी की क्षमता रेट पर निर्भर करती है: प्रति क्वेरी सिद्ध रूप से (1 + ρ)/2 = 9/16, अनुमानित रूप से ρ = 1/8। बड़ा ब्लो-अप कम क्वेरी से काम चला देता, पर इसकी क़ीमत आनुपातिक रूप से बड़ा लो-डिग्री एक्सटेंशन होती, जिसकी गणना प्रूवर को करनी पड़ती और जिसे मेमोरी में रखना पड़ता। |
| FRI क्वेरी | 80 | वह संख्या जो सिद्ध साउंडनेस को लगभग 86 बिट पर रखती है। इसे एक बार 27 तक घटाया गया था (कंस्ट्रेंट सेट 3 और 4), जिससे 100-बिट का अनुमानित लक्ष्य (3·27 + 20 = 101) तो पूरा हुआ, पर सिद्ध बिट केवल लगभग 42 रह गए; 2026-09-12 के zk ऑडिट (फ़ाइंडिंग ZM1) ने 80 बहाल किया। किसी प्रूफ़ के आकार का अधिकांश भाग क्वेरी ही होती हैं, इसीलिए एक बंडल प्रूफ़ ≈ 1.50 MB का है। सिद्ध 100 बिट के लिए 97 क्वेरी लगेंगी। |
| ग्राइंडिंग | 20 बिट, क्वेरी चरण में | क्वेरी स्थितियाँ निकाले जाने से पहले प्रूवर को ऐसा नॉन्स खोजना होता है जिसका हैश 20 शून्य बिट से शुरू हो: लगभग दस लाख हैश, जिनकी क़ीमत ईमानदार प्रूवर एक बार चुकाता है और स्थितियाँ दोबारा निकालने वाला धोखेबाज़ हर पुनःप्रयास पर। यह सस्ते में 20 बिट जोड़ता है; अधिक ग्राइंडिंग (34 बिट से भी सिद्ध 100 बिट मिल जाते) हर ईमानदार प्रूफ़ को धीमा कर देती है। कमिट चरण में कोई ग्राइंडिंग नहीं है। |
| फ़ोल्डिंग एरिटी | प्रति राउंड अधिकतम 8 (max_log_arity = 3) | दो के बजाय आठ से फ़ोल्ड करने पर FRI परतें एक-तिहाई रह जाती हैं, इसलिए प्रत्येक क्वेरी कम Merkle पथ खोलती है और प्रूफ़ छोटा होता है, बदले में प्रति परत थोड़ा अधिक काम होता है। |
| अंतिम बहुपद | एक स्थिरांक (log_final_poly_len = 0) | FRI पूरी तरह नीचे तक फ़ोल्ड करता है और एक मान खुले रूप में भेजता है, जो वेरिफ़ायर के लिए सबसे सरल अंतिम जाँच है। |
| हैश (सर्किट में, Merkle, ट्रांसक्रिप्ट) | Poseidon2, चौड़ाई 8, S-box x⁷, 4 + 22 + 4 राउंड, रेट 4, कैपेसिटी 4 | फ़ील्ड अंकगणित जितना सस्ता होने के लिए बनाया गया हैश, ताकि प्रूफ़ के भीतर हैशिंग (कमिटमेंट, न्यूलिफ़ायर, Merkle पथ, प्रोग्राम डाइजेस्ट) की लागत पंक्तियों में हो, हज़ारों बिट-संक्रियाओं में नहीं। S-box घातांक का p − 1 = 2³²·3·5·17·257·65537 के साथ कोई साझा गुणनखंड नहीं होना चाहिए, और 7 सबसे छोटा मान है जो इस शर्त पर खरा उतरता है। रेट 4 पर चौड़ाई 8 चार एलिमेंट का डाइजेस्ट देती है, लगभग 256 बिट। 86 राउंड स्थिरांक नोड में एक शाब्दिक तालिका के रूप में हैं (poseidon2_constants.rs)। |
| डाइजेस्ट चौड़ाई | 4 फ़ील्ड एलिमेंट (≈ 256 बिट) | प्रीइमेज भूमिकाओं (न्यूलिफ़ायर, कमिटमेंट: Grover के विरुद्ध 128 बिट) के लिए पर्याप्त। ट्रांसक्रिप्ट में 128-बिट क्वांटम कोलिज़न प्रतिरोध के लिए यह पर्याप्त नहीं है (2²⁵⁶/³ ≈ 2⁸⁵); व्हाइटपेपर का डिज़ाइन 384-बिट ट्रांसक्रिप्ट हैश की माँग करता है, और चल रही चेन ने इसे अभी नहीं अपनाया है। |
| हाइडिंग | FRI में 4 यादृच्छिक कोडवर्ड; प्रति Merkle लीफ़ 4 सॉल्ट एलिमेंट; प्रति प्रूफ़ नई OS यादृच्छिकता | वह न्यूनतम जो खोली गई 80 स्थितियों और Merkle पथों को केवल सार्वजनिक मानों से सिम्युलेट करने योग्य बनाता है, जिससे प्रूफ़ सांख्यिकीय रूप से ज़ीरो-नॉलेज होता है। एक ही भुगतान के दो बार बनाए गए प्रूफ़ एक-दूसरे से असंबंधित दिखते हैं। |
| टेबल का न्यूनतम आकार | हर घोषित टेबल के लिए 2⁷ पंक्तियाँ (कंस्ट्रेंट सेट 7) | एक प्रूफ़ प्रत्येक टेबल के 80 क्वेरी बिंदु और 2 डोमेन-बाहरी बिंदु खोलता है, कुल 82, और h पंक्तियों वाली टेबल h यादृच्छिक पंक्तियों से ब्लाइंड की जाती है। 64 पंक्तियाँ बहुत कम हैं और 128 दो की अगली घात है। 126 से अधिक क्वेरी संख्या के लिए 2⁸ चाहिए होगा। |
| टर्मिनल ब्लाइंड | प्रति टेबल F_p² का एक मान, BLIND बस पर (कंस्ट्रेंट सेट 7) | LogUp टर्मिनल की गणना कच्चे ट्रेस से होती है, इसलिए ब्लाइंड के बिना यह अपनी टेबल का बिना सॉल्ट वाला कमिटमेंट होता। ब्लाइंड एक्सटेंशन-फ़ील्ड एलिमेंट है क्योंकि एक अकेला बेस-फ़ील्ड निर्देशांक शिफ़्ट को एक पतले समुच्चय तक सीमित कर देता, जिसके विरुद्ध किसी संभावित विटनेस को परखा जा सकता। |
| गैस भार | प्रति पंक्ति 1; Poseidon2 एब्ज़ॉर्ब पंक्ति 3; SHA256 पंक्ति 64; KECCAK पंक्ति 192 (कंस्ट्रेंट सेट 8) | प्रत्येक भार उन पंक्तियों को गिनता है जिन्हें वह पंक्ति अन्य टेबलों में खींचती है: एक एब्ज़ॉर्ब पंक्ति एक 32-पंक्ति परम्यूटेशन, एक SHA256 पंक्ति 466 कॉलम की 64 पंक्तियाँ, और एक KECCAK पंक्ति 2,612 कॉलम की 32 पंक्तियाँ तथा 100 मेमोरी पंक्तियाँ। |
| अधिकतम कंस्ट्रेंट डिग्री | 8 | ऊपर दिए ब्लो-अप से निर्धारित; प्रत्येक टेबल की डिग्री एक टेस्ट द्वारा तय की गई है ताकि कोई नया नियम चुपचाप इससे आगे न निकल सके। |
| टियर | 10, 12, 14, 16, 18, 20 | टेबलों का आकार छह निश्चित चरणों में तय होता है, हर चरण पिछले का चार गुना, और प्रूफ़ केवल अपना टियर प्रकट करता है: रन की लंबाई की एक मोटी, पैडेड श्रेणी, न कि उसकी साइकिल संख्या। हर बंडल टियर 14 का है और हर ऑथ प्रूफ़ टियर 10 का; fullnode v0.5.6 से कॉल टियर 14 तक सीमित हैं। |
| अधिकतम ट्रेस | 2²⁴ पंक्तियाँ (ज़ीरो-नॉलेज बिट के साथ 2²⁵) | वह आकार जिसके लिए एक्सटेंशन-फ़ील्ड पद सिद्ध है; इससे लंबा ट्रेस अस्वीकार कर दिया जाता है, न कि ऐसे साउंडनेस दावे के तहत प्रूव किया जाता है जो लागू ही नहीं होता। |
| सार्वजनिक मान | 35 फ़ील्ड एलिमेंट | प्रवेश pc, टियर, आठ आउटपुट वर्ड, तीन आठ-वर्ड डाइजेस्ट hc, H_IN, H_PUB, और घोषित गैस सीमा: वह सबसे छोटा कथन जो प्रोग्राम, निजी इनपुट, सार्वजनिक इनपुट और काम की एक सीमा को निर्दिष्ट करता है। कंस्ट्रेंट सेट 7 तक यह 34 था। |
| प्रूफ़ आकार सीमा | डिफ़ॉल्ट 2 MiB; चेन 20 पर 4 MiB (max_proof_bytes) | 2 MiB उन सभी प्रूफ़ से ऊपर है जो तैनात गेस्ट हैश टेबल के बिना बनाते हैं, और keccak वाले प्रूफ़ (≈ 3.3 MB) से नीचे; चेन 20 का जेनेसिस दोनों को स्वीकार करने के लिए 4,194,304 निर्धारित करता है, जैसा चेन 17 से 19 ने किया था। चेन 13 से 16 ने 8 MiB निर्धारित किया था। प्रूफ़ डिकोड होने से पहले ही सीमा जाँची जाती है। |
इन संख्याओं का कुल निष्कर्ष: 86 बिट की सिद्ध साउंडनेस, ethSTARK अनुमान के तहत लगभग 100 बिट (जहाँ सीमा क्वेरी नहीं, बल्कि एक्सटेंशन फ़ील्ड तय करता है), और क्वांटम प्रतिद्वंद्वी के विरुद्ध लगभग 85 बिट, जो 256-बिट ट्रांसक्रिप्ट हैश से निर्धारित होते हैं। व्हाइटपेपर जान-बूझकर दोनों साउंडनेस आँकड़ों को साथ-साथ रखता है: हर तैनात FRI-STARK अपने अंतिम बिटों के लिए इसी अनुमान पर निर्भर है, और किसी तैनाती का आकार तय करने वाले पाठक को पता होना चाहिए कि कौन-सी धारणा कौन-से बिट वहन करती है।
प्रूफ़ के बारे में प्रूफ़
लगभग 1.50 MB का बंडल प्रूफ़ भारी है, 1.37 MB का ऑथ प्रूफ़ उसके साथ चलता है, और हर नोड इन सभी को संग्रहीत करता है। जो उपाय बनाया गया है वह रिकर्शन है: एक ऐसा प्रूफ़ जिसका कथन है “मैंने इन प्रूफ़ का सत्यापन किया”। fullnode इसके लिए एक दूसरी, छोटी मशीन रखता है, रिकर्शन VM, जिसका मूल वर्ड एक Goldilocks एलिमेंट है और जिसके निर्देश स्वयं वेरिफ़ायर की संक्रियाएँ हैं (फ़ील्ड अंकगणित, Poseidon2, Merkle और FRI चरण)। इसका एग्रीगेट प्रोग्राम N बंडल प्रूफ़ के पूर्ण सत्यापन को दोहराता है और उनके सार्वजनिक मानों पर एक डाइजेस्ट प्रकाशित करता है, जो चेन, एग्रीगेटर और एक नॉन्स से बँधा होता है। इसके भीतर एक बंडल प्रूफ़ के सत्यापन की लागत कंस्ट्रेंट सेट 6 के तहत 1,968,619 पंक्तियाँ और कंस्ट्रेंट सेट 7 के तहत 2,044,506 पंक्तियाँ थी; सेट 8 के तहत इसे दोबारा नहीं मापा गया है। यह लागू किया जा चुका है, पर अब तक की हर चेन पर, चेन 20 सहित, जेनेसिस द्वारा बंद है। एग्रीगेट प्रोग्राम केवल बंडल प्रूफ़ का सत्यापन करता है, इसलिए विभाजित-ऑथराइज़ेशन वाली चेन पर ऑथ प्रूफ़ बना रहेगा। इसके प्रोडक्शन प्रूफ़ को नियोजित से अधिक मेमोरी भी चाहिए: कंस्ट्रेंट सेट 7 के तहत मापने पर 133 GB और उससे अधिक (आगामी: ब्लॉक एग्रीगेशन)।
यह योजना क्या दावा नहीं करती
- क्वांटम मार्जिन लगभग 85 बिट है, 128 नहीं।
n-बिट हैश पर क्वांटम कोलिज़न खोज की लागत लगभग2ⁿ/³होती है। व्हाइटपेपर का डिज़ाइन 384-बिट ट्रांसक्रिप्ट हैश निर्धारित करता है; चालू चेन 256-बिट Poseidon2 डाइजेस्ट का उपयोग करती है। इसे चौड़ा करने के लिए नया कंस्ट्रेंट सेट और हार्ड फ़ॉर्क चाहिए। - 100 बिट एक अनुमान (कंजेक्चर) है; 86 बिट सिद्ध है। सिद्ध आँकड़े को 100 तक बढ़ाने के लिए 97 क्वेरी चाहिए होंगी, यानी प्रति प्रूफ़ लगभग पाँचवाँ हिस्सा अधिक क्वेरी डेटा।
- Poseidon2 स्थिरांक एक सीडेड ड्रॉ से लिए गए हैं, कोई प्रकाशित इंस्टैंशिएशन नहीं हैं। इस पर कोई हमला ज्ञात नहीं है; मानक सेट अपनाने से चेन का हर हैश बदल जाएगा।
- कुछ कथन प्रूफ़ के भीतर नहीं, उसके साथ अलग से जाँचे जाते हैं।
TIERसार्वजनिक मान की तुलना वेरिफ़ायर प्रूफ़ के आकार से करता है, पर सर्किट उसे बाध्य नहीं करता (ऑडिट ZL1); और बंडल गेस्ट का टेंट अनुशासन मशीन द्वारा सत्यापित नहीं है, बल्कि संरचनात्मक तर्क, कमज़ोर किए गए गेस्ट वाले हार्नेस और म्यूटेशन फ़ज़िंग पर आधारित है। - प्रूफ़ का हेडर छिपा नहीं होता। टियर और दोनों हैश-टेबल की ऊँचाइयाँ खुले में होती हैं, इसलिए कॉल प्रूफ़ से पता चलता है कि कॉल ने
KECCAKका उपयोग किया याSHA256का। दोनों टेबल को पैड करने वाला एक प्रूवर विकल्प मौजूद है, पर कोई वॉलेट उसे सेट नहीं करता: इससे टियर-10 प्रूफ़ लगभग 1.3 MB से बढ़कर लगभग 3.6 MB हो जाता है। POSEIDON2सिसकॉल परिवर्तनशील-लंबाई इनपुट पर इंजेक्टिव नहीं है। इसे यथावत रखा गया है क्योंकि हर कमिटमेंट, न्यूलिफ़ायर, रूट और प्रोग्राम डाइजेस्ट इसी पर निर्भर है। अभी तक कोई भी जारी किया गया गेस्टPOSEIDON2_LENका उपयोग नहीं करता।- प्रूविंग धीमी है और इसे प्रेषक करता है, या वह प्रूवर जिसके साथ प्रेषक जुड़ता है: एक बंडल के लिए लैपटॉप CPU पर लगभग 100 s और 5.7 GB। GPU कर्नेल पहली बार 2026-09-28 को एक GPU (NVIDIA H100) पर चले और CPU संदर्भ से मेल खाए; वॉलेट अब भी CPU पर ही प्रूफ़ बनाता है।
आगे कहाँ पढ़ें
- व्हाइटपेपर का खंड “The Zero-Knowledge Scheme: How a Rand Proof Works” (
randprotocol.tex) इन्हीं सात घटकों को साउंडनेस प्रमेयों के साथ क्रम से समझाता है। - इम्प्लीमेंटेशन पेपर (
randprotocol_implementation.tex) इंस्ट्रक्शन सेट और सिसकॉल, बंडल गेस्ट, स्पंज और डाइजेस्ट, हर टेबल और बस, मशीन कॉन्फ़िगरेशन और रिकर्शन VM को निर्दिष्ट करता है। - कोड: fullnode में
crates/randprotocol-zkvm/src/—emulator.rs,tables/,machine.rs,gas.rs,guests.rs,hash.rs,poseidon2_constants.rs।