Rand Protocol
مستندات
راهنماها

رمزنگاری

اولیه‌های رمزنگاری و جایی که هر کدام به کار می‌رود، پارامترهای STARK و FRI در محیط عملیاتی، و ساختارهای هش که ممکن است توسعه‌دهنده لازم داشته باشد آن‌ها را بازتولید کند.

از این صفحه برای انتخاب کتابخانهٔ درست هنگام تعامل با زنجیره، برای بررسی یک پارامتر در برابر آنچه نود اعمال می‌کند، و برای بازمحاسبهٔ یک شناسه یا یک تعهد به‌دست خودتان استفاده کنید. همهٔ مقادیر اینجا همان‌هایی است که کد روی chain 20 (fullnode v0.6.8) اجرا می‌کند.

اولیه‌های رمزنگاری و محل استفادهٔ آن‌ها

اولیهپارامترهاکاربرد
Dilithium2کلید عمومی ۱٬۳۱۲ بایتی، امضای ۲٬۴۲۰ بایتی؛ جفت‌کلیدها از یک seed ۳۲ بایتی مشتق می‌شوندرأی‌های اعتبارسنج‌ها و پیشنهاد بلوک؛ mintهای faucet؛ Unbond، Withdraw و Registration یک اعتبارسنج؛ رأی‌های AdmitValidator (chain 20)؛ کنش‌های تجمیع‌کننده؛ اختیار mint کلید Key در یک توکن RPL (TokenMint، SetAuthority)؛ هم‌امضایی‌های پساکوانتومی نگهبانان پل، کلید توقف آن و، در chain 20، اثبات‌های تملک کلیدهای جدید در یک چرخش (در ادامه)
ML-KEM-768کلید کپسوله‌سازی ۱٬۱۸۴ بایتی، متن رمزشدهٔ ۱٬۰۸۸ بایتیمهر و موم کردن کلید هر تراکنش در پاکت یک یادداشت برای نشانی گیرنده؛ مهر و موم کردن پاکت ورودی فراخوانی برای یک حسابرس؛ مهر و موم کردن یک کار اثبات برای یک اثبات‌کنندهٔ جفت‌شده
ChaCha20-Poly1305کلید ۳۲ بایتی، nonce تصادفی ۱۲ بایتی که در ابتدا قرار می‌گیرد، تگ ۱۶ بایتیهر بخش از پاکت: بدنهٔ یادداشت‌ها، کلیدهای تراکنشِ بسته‌بندی‌شده، رونوشت‌های ورودی فراخوانی؛ کارها و پاسخ‌های یک اثبات‌کنندهٔ جفت‌شده
BLAKE3خروجی ۳۲ بایتی، همیشه با یک رشتهٔ دامنه در ابتدانشانی‌ها، شناسه‌های تراکنش، اتصال تراکنش و اتصال فراخوانی، شناسه‌های برنامه، شناسه‌های دارایی توکن، ریشهٔ وضعیت و درخت‌های Merkle آن، هویت p2p، پیام‌های امضا، شناسه‌های دارایی پل، پوشانندهٔ (blinding) یک سپردهٔ پل و پوشانندهٔ یادداشت‌های کارمزد پل
Poseidon2 روی Goldilocksعرض ۸، نرخ ۴، ظرفیت ۴، اسفنج بازنویسی بدون padding؛ عناصر پیام کلمات ۳۲ بیتی‌اند؛ ۸۶ ثابت دور از برش chain-15 به بعد یک جدول لفظی در کد منبع نود هستند (poseidon2_constants.rs)، همان مقادیری که پیش‌تر قرعه‌کشی با seed تولید می‌کردهر چیز درون یک اثبات: کلیدها، تعهدهای یادداشت، nullifierها، درخت تعهد، چکیدهٔ برنامه hc، تعهدهای ورودی H_IN و H_PUB، چکیدهٔ بسته، تعهد احراز اختیار
secp256k1 ECDSA + keccak256امضاهای low-s، نشانی‌های ۲۰ بایتی نگهبان به سبک Ethereum، mu = keccak256(keccak256(body))گواهی‌های نگهبانان پل، تا یک کلید روی قراردادهای EVM، برنامهٔ Solana و Rand کار کند؛ در Rand هر گواهی به حد نصاب Dilithium2 زیر نیز نیاز دارد
bech32m (BIP-350)بخش خوانای انسانی rpl، بار ۳۲ بایتی، ۵۲ نویسهٔ داده + ۶ نویسهٔ checksum = ۶۲قالب متنی rpl1… شناسهٔ دارایی یک توکن RPL
Plonky3 batch STARKGoldilocks p = 2⁶⁴ − 2³² + 1، FRI پنهان‌کننده، blowup 8، arity تاشدگی 8، ۸۰ query، ۲۰ بیت proof-of-workهر اثبات بسته، اثبات احراز اختیار و اثبات فراخوانی؛ یک اثبات بسته و اثبات احراز اختیار آن، هشت کلمهٔ اتصال تراکنش خود را به‌عنوان قطعهٔ ورودی عمومی حمل می‌کنند

پارامترهای هدف در whitepaper در چند جا با آنچه پیاده‌سازی اجرا می‌کند تفاوت دارند (برای مثال چکیدهٔ رونوشت ۳۸۴ بیتی در مقاله در برابر رونوشت Poseidon2 در zkVM). این صفحات کد را توصیف می‌کنند.

هم‌امضایی‌های پساکوانتومی روی پل

گواهی‌های نگهبانان پل از نوع secp256k1 ECDSA هستند که یک مهاجم کوانتومی می‌تواند جعل کند. از chain 14 به بعد هر BridgeAttest — چه سپرده و چه چرخش مجموعهٔ نگهبانان — باید یک حد نصاب از امضاهای Dilithium2 را هم از همان نگهبانان روی همان چکیده حمل کند:

M = "rand-bridge-pq-cosign-1" || rand_chain_id (u64 BE) || mu        // 63 bytes, deterministic signing

که در آن mu = keccak256(keccak256(body)) همان چیزی است که حد نصاب ECDSA امضا می‌کند. شناسهٔ زنجیرهٔ Rand در M مانع می‌شود هم‌امضای یک testnet روی زنجیرهٔ Rand دیگری تأیید شود، حتی اگر کلیدهای نگهبانان دوباره استفاده شده باشند. M فقط شناسهٔ زنجیره را به هم می‌بندد، در chain 20 نیز: این تنها پیام امضاشده‌ای است که binding_domain آن را پشت هش genesis نبرد، چون دیمن‌های نگهبانی که آن را امضا می‌کنند در مخزن دیگری قرار دارند. نسخهٔ کپی یک زنجیره با همان شناسهٔ زنجیره و همان مجموعهٔ نگهبانان، هم‌امضاهای سپرده‌های آن را می‌پذیرد؛ اندیس مجموعهٔ نگهبانان در M نیست، پس یک هم‌امضا از چرخش مجموعهٔ ECDSA جان به‌در می‌برد. فیلد pq_signatures در کنش فهرستی از PqSignature { index: u8, signature } است که ارزان‌ها پیش از گران‌ها بررسی می‌شوند: quorum(n) ≤ len ≤ n (PqNoQuorum)، اندیس‌ها اکیداً صعودی (PqIndexOrder)، هر اندیس کمتر از n (PqIndexOutOfRange)، هر امضا دقیقاً ۲٬۴۲۰ بایت (PqBadSignatureLength)، و در پایان هر امضا زیر pq_guardians[index] تأیید می‌شود (PqBadSignature). امضاکنندگان PQ لازم نیست همان امضاکنندگان ECDSA باشند؛ هر حد نصاب جداگانه شمرده می‌شود. این فیلد درون اتصال تراکنش است، پس نمی‌توان آن را از یک نسخهٔ کپی حذف یا عوض کرد.

مجموعهٔ PQ همان bridge.pq_guardians در genesis است — در chain 20 هشت کلید ۱٬۳۱۲ بایتی، مانند chainهای ۱۵ تا ۱۹، هم‌تراز با مجموعهٔ ECDSA در genesis، مجموعهٔ نگهبانان ۱ (chain 14 شش کلید داشت، هم‌تراز با مجموعهٔ ۰). چرخش مجموعهٔ نگهبانان ECDSA هرگز آن را جابه‌جا نمی‌کند. در chain 14 این مجموعه تا پایان عمر زنجیره ثابت بود؛ از chain 15 به بعد genesis گروه rules_v2 پل را حمل می‌کند که در آن یک حد نصاب PQ می‌تواند کل مجموعهٔ PQ (RotatePqGuardians) یا کلید توقف (RotatePauseKey) را جایگزین کند، هرکدام زیر rotation_nonce پل. genesis در chain 20 مقدار bridge.rotation را اضافه می‌کند: یک چرخش باید کنش V2 باشد و امضای Dilithium2 خودِ هر کلید جدید را روی همان پیام حمل کند (اثبات تملک)، و یک روز پس از ثبت اعمال می‌شود مگر آنکه کلید توقف فعلی آن را لغو کند (پل). rand_getBridgeState کلیدها را ارائه می‌دهد و یک bridge_attest رمزگشایی‌شده pq_signers را فهرست می‌کند، یعنی اندیس‌هایی که امضا کرده‌اند. همین حد نصاب PQ پیام‌های حاکمیتی پل را مجاز می‌کند که هرکدام یک چیدمان big-endian ثابت دارند و شناسهٔ زنجیره و یک nonce را حمل می‌کنند. در chain 20 (genesis با binding_domain: 1) رقم نسخهٔ هر دامنه ۲ است و هش genesis ۳۲ بایتی میان دامنه و شناسهٔ زنجیره قرار می‌گیرد؛ chainهای ۱۴ تا ۱۹ از قالب‌های -1 استفاده می‌کنند:

پیامدامنه (chainهای ۱۴–۱۹ / chain 20)امضاکننده
M_pauserand-bridge-pause-1 / -2تنها کلید توقف در genesis (Dilithium2)، که می‌تواند متوقف کند و هرگز نمی‌تواند از توقف خارج کند
M_unpauserand-bridge-pq-unpause-1 / -2یک حد نصاب نگهبانان PQ
M_listrand-bridge-pq-list-1 / -2یک حد نصاب نگهبانان PQ (ListBacking)
M_registerrand-bridge-pq-register-1 / -2یک حد نصاب نگهبانان PQ (RegisterBridgedToken)
M_rotate_pqrand-bridge-pq-rotate-pq-1 / -2یک حد نصاب از مجموعهٔ PQ فعلی (RotatePqGuardians، chainهای rules_v2)؛ در chain 20 هر کلید جدید نیز، به‌عنوان اثبات تملک خود
M_rotate_pauserand-bridge-pq-rotate-pause-1 / -2یک حد نصاب از مجموعهٔ PQ فعلی (RotatePauseKey، chainهای rules_v2)؛ در chain 20 کلید جدید نیز
M_cancelrand-bridge-cancel-rotation-1 / -2، با یک بایت kind در انتهاکلید توقف فعلی (CancelRotation، chainهای دارای bridge.rotation: chain 20)

STARK در محیط production

zkVM در constraint set 8 است: نه جدول اجباری (program، cpu، memory، alu، range، nibble، poseidon2، input، public) به‌علاوهٔ یک جدول keccak و یک جدول sha256 که یک اثبات فقط وقتی حمل می‌کند که guest آن syscall متناظر را فراخوانده باشد، با هفده bus به هم وصل شده‌اند و به‌صورت یک batch STARK اثبات می‌شوند. از constraint set 7 به بعد هر جدول اعلام‌شده دست‌کم 2⁷ سطر دارد و پایانهٔ LogUp هر جدول از طریق bus هفدهم، یعنی BLIND، پوشانده می‌شود. رابط عمومی یک اثبات ۳۵ عنصر میدانی است (pv::NUM): pc ورودی، tier، هشت کلمهٔ خروجی، چکیدهٔ برنامه hc (۸ کلمه)، تعهد ورودی خصوصیِ salt‌دار H_IN (۸)، چکیدهٔ قطعهٔ عمومیِ بدون salt یعنی H_PUB (۸) و، از constraint set 8، سقف gas اعلام‌شده GAS_LIMIT.

پارامترproductionتوضیح
query های FRI80تنظیم مجدد ۲۷ queryِ constraint setهای ۳ و ۴ پس از ممیزی 2026-09-12 برگردانده شد: حدود ۴۲ بیت اثبات‌شده باقی می‌گذاشت
blowup8 (log_blowup = 3)بیشینهٔ درجهٔ محدودیت هر جدول زیر سقف ۸ مهار شده است
arity تاشدگی8
بیت‌های proof-of-work20
سلامت (soundness)3·80 + 20 = 260 بیت به‌صورت حدسی (ethSTARK)؛ حدود ۸۶ بیت اثبات‌شده تحت proximity gaps
دانش‌صفرآماری: LDE و چندجمله‌ای batch در FRI تصادفی‌سازی می‌شوند، پس دو اثبات از یک اجرا با هم تفاوت دارنداز constraint set 7 به بعد هر جدول اعلام‌شده دست‌کم 2⁷ سطر دارد، بیش از ۸۲ نقطه‌ای که یک اثبات باز می‌کند، و پایانه‌های LogUp پوشانده می‌شوند
tier ها10، 12، 14، 16، 18، 20یک اثبات tier را آشکار می‌کند، هرگز تعداد چرخه‌ها را؛ از fullnode v0.5.6 به بعد یک اثبات فراخوانی بالاتر از tier 14 رد می‌شود (CallTierTooHigh)، یک اثبات بسته روی tier 14 و یک اثبات احراز اختیار روی tier 10 ثابت شده است
سقف اثباتمقدار max_proof_bytes در genesis: 4 MiB (4,194,304) در chainهای ۱۷ تا ۲۰؛ 8 MiB در chainهای ۱۳ تا ۱۶؛ 2 MiB (MAX_PROOF_BYTES) در genesis بدون آن، مانند chain 122 MiB بالاتر از هر اثبات بدون جدول هش است که guestهای مستقرشده می‌توانند تولید کنند و پایین‌تر از اثباتی که keccak حمل می‌کند؛ 4 MiB هر دو را می‌پذیرد
gas1 به ازای هر سطر cpu؛ 3 به ازای هر سطر absorb در Poseidon2؛ 64 به ازای هر سطر SHA256؛ 192 به ازای هر سطر KECCAKدر ستون GAS جدول cpu انباشته می‌شود و حداکثر تا GAS_LIMIT اثبات می‌شود؛ تأییدکننده سقفی بالاتر از gas_max(t, k, s) = (2ᵗ − 1) + 2ᵗ⁻² + 191·(2ᵏ/32) + 63·(2ˢ/64) را رد می‌کند، که برای یک سرآیند tier-10 بدون هش 1,279 و برای یک سرآیند tier-14 برابر 20,479 است

اندازه‌های اندازه‌گیری‌شده در مجموعه قیود ۶ (Apple Silicon، ساخت release): یک اثبات تولیدیِ بدون keccak در رده ۱۰ برابر با 1,298,729 بایت و در رده ۱۲ برابر با 1,359,978 بایت بود؛ یک اثبات رده ۱۰ حامل keccak برابر با 3,198,430 بایت بود، یعنی بیش از پیش‌فرض ۲ MiB و کمتر از ۸ MiB زنجیره‌های ۱۳ تا ۱۵. اثبات رده ۱۴ برای guest بستهٔ بازنشستهٔ ۲-ورودی-۲-خروجی روی زنجیرهٔ ۸ برابر با 1,321,773 بایت و روی زنجیرهٔ ۱۳ بین 1,418,406 تا 1,420,423 بایت اندازه‌گیری شد. guest بستهٔ دارایی پنهان ۴-ورودی-۴-خروجیِ زنجیرهٔ ۱۴ در رده ۱۴ و بدون هیچ‌یک از دو جدول هش می‌ماند و اثبات‌هایش روی زنجیرهٔ ۱۴ برابر با 1,422,116 و 1,423,170 بایت اندازه‌گیری شد (2026-09-20)، و زنجیرهٔ ۱۵ همین guest را تثبیت کرد (hc_bundle بدون تغییر)؛ اثبات بسته در آن‌جا public_log_height را برابر ۴ اعلام می‌کرد، یعنی ارتفاع هشت واژهٔ اتصال، و گره پیش از ساختن کلید تأییدکننده هر مقدار دیگری را رد می‌کرد. اثبات فراخوانی approve برای ERC-20 حامل keccak که در 2026-09-19 روی زنجیرهٔ ۱۳ ساخته شد (رده ۱۶) برابر با 3,412,405 بایت است؛ هر زنجیره از fullnode v0.5.6 به بعد این فراخوانی را در رده ۱۶ رد می‌کند.

ستون‌های پوشاندن و کف‌های جدولِ مجموعه قیود ۷ حدود ۵٪ به اثبات بدون هش می‌افزایند: بر پایهٔ اندازه‌گیری fullnode در 2026-09-28، fib در رده ۱۰ برابر با 1,367,688 بایت و در رده ۱۲ برابر با 1,424,299 بایت است، یک اثبات رده ۱۰ حامل keccak برابر با 3,283,898 و یک اثبات بستهٔ دارایی پنهان در رده ۱۴ برابر با 1,498,821 (guest نسخهٔ ۱) و 1,497,156 (guest نسخهٔ ۲). از آن زمان، اثبات بسته public_log_height را برابر ۷ اعلام می‌کند. مجموعه قیود ۸ کمتر از ۱٪ می‌افزاید. اندازه‌گیری‌شده روی زنجیرهٔ ۱۸ در 2026-09-30 (Apple Silicon): اثبات‌های احراز هویت از 1,364,940 تا 1,375,371 بایت (رده ۱۰)، اثبات‌های بسته از 1,494,151 تا 1,504,260 بایت (رده ۱۴، guest نسخهٔ ۳) و اثبات‌های فراخوانی برابر با 1,498,589 بایت در رده ۱۴ بدون جدول هش، 1,911,152 در رده ۱۴ با جدول SHA-256 و 3,346,865 در رده ۱۲ با جدول Keccak. همه در سقف ۴ MiB زنجیره‌های ۱۸ تا ۲۰ جا می‌شوند.

تأیید با کلید تأییدکنندهٔ گرم حدود ۱۶ میلی‌ثانیه و در نخستین باری که کلیدی برای (tier, heights) ساخته می‌شود حدود ۲۳۰ میلی‌ثانیه طول می‌کشد. پروفایل FRI به نام test (۱۶ پرس‌وجو) برای مجموعهٔ آزمون وجود دارد و ناامن است؛ genesis زنجیرهٔ ۲۰ پروفایل production را تثبیت می‌کند. Fullnode v0.6.8 هیچ قیدی را تغییر نمی‌دهد: زنجیرهٔ ۲۰ همان hc_bundle و hc_auth زنجیره‌های ۱۷ تا ۱۹ را تثبیت می‌کند.

ساختارهای هشی که می‌توانید بازتولید کنید

BLAKE3 با یک دامنه: blake3(domain || data)، رشتهٔ دامنه بدون هیچ جداکننده.

دامنهٔ اتصال. genesis زنجیرهٔ ۲۰ مقدار binding_domain: 1 را تنظیم می‌کند (fullnode v0.6.8، ممیزی v6 BIND-1). در چنین زنجیره‌ای هر اتصال اثبات و هر پیام کنش امضاشده‌ای که پیش‌تر فقط شناسهٔ زنجیره را در بر می‌گرفت، اکنون هش پیدایش را هم در بر می‌گیرد: شمارهٔ نسخهٔ دامنه یکی بالا می‌رود و هش پیدایشِ ۳۲ بایتی پیش از شناسهٔ زنجیره در پیش‌تصویر قرار می‌گیرد. آن‌گاه اثبات یا امضایی که برای یک زنجیره ساخته شده در هیچ زنجیرهٔ دیگری تأیید نمی‌شود، حتی اگر شناسهٔ زنجیره و کلیدها را دوباره به کار ببرد، چنان‌که در یک بازسازی (re-cut) پیش می‌آید. واژه‌های اتصال ورودی عمومیِ اثبات‌ها هستند، پس هیچ guest یا کلید تأییدکننده‌ای تغییر نکرد. جدول هر دو شکل را می‌دهد؛ زنجیره‌های ۱۴ تا ۱۹ از شکل نخست استفاده می‌کنند، بایت به بایت. پیش‌تر به هش پیدایش متصل بودند و بدون تغییر مانده‌اند: رأی‌ها و پیشنهادها (از consensus_domain: 1)، Registration نسخهٔ ۲ و رأی AdmitValidator. جابه‌جا نشده: هم‌امضای mint پل (بالاتر). کیف‌پول برای ارسال روی زنجیرهٔ ۲۰ به v0.6.8 نیاز دارد و شکل را با شناسهٔ زنجیره تعیین می‌کند، نه با آنچه یک گره ادعا می‌کند؛ rand_getLimits.binding_domain آن را گزارش می‌دهد.

مقدارساختار
آدرس شفافblake3("rand-address" || dilithium2_public_key)، base58
شناسهٔ تراکنشblake3("rand-txid-3" || bincode(view))، که در آن view همان تراکنش است با بایت‌های اثبات بسته که با blake3(proof) و اثبات احراز هویتش که با blake3(auth_proof) جایگزین شده‌اند؛ auth_commit همان‌گونه که هست وارد می‌شود. تا زنجیرهٔ ۱۶ دامنه rand-txid-2 بود، بدون فیلدهای احراز هویت
اتصال تراکنشblake3("rand-tx-bind-1" || bincode(chain_id, bundle', action')) روی زنجیره‌های ۱۴ تا ۱۹؛ blake3("rand-tx-bind-2" || bincode(genesis_hash, chain_id, bundle', action')) روی زنجیرهٔ ۲۰. هشت واژهٔ u32 به‌صورت little-endian، که در آن ' یعنی bundle.proof، bundle.auth_proof و proof یک Aggregate با بردار تهی جایگزین شده‌اند؛ bincode با اعداد صحیح little-endian با عرض ثابت. هر اثبات بسته و اثبات احراز هویت بر این واژه‌ها ساخته و در برابر آن‌ها تأیید می‌شود
اتصال فراخوانیblake3("rand-call-bind-1" || …)، یا rand-call-bind-2 با هش پیدایش در ابتدا روی زنجیرهٔ ۲۰: ساختار اتصال تراکنش با proof خودِ Call (یا Invoke) که آن هم تهی شده است. روی genesis با hardening_v6، مانند زنجیرهٔ ۲۰، بخش عمومی اثبات فراخوانی عبارت است از واژه‌های عمومیِ زمان استقرار برنامه و پس از آن این هشت واژه، و در Invoke گذارِ آن به‌عنوان واژه‌های زمینه پس از این‌ها افزوده می‌شود
شناسهٔ برنامهblake3("rand-program" || base_pc as 4 LE bytes || words as 4 LE bytes each)
هویت p2pکلید ed25519 از blake3("rand-p2p-identity" || seed)
شناسهٔ دارایی پل (برای هر پشتوانه)blake3("rand-bridge-asset" || token_chain as 2 BE bytes || token_address (32 bytes)) — rand_bridgeAssetId آن را محاسبه می‌کند و rand_getAssets آن را برای هر ردیف پشتوانه چاپ می‌کند؛ این شناسه یک سکهٔ مبدأ را روی شبکه مشخص می‌کند، نه توکن را
شناسهٔ دارایی توکن RPL، بومیblake3("rand-rpl-asset" || bincode(name, symbol, decimals, authority, initial: Option<InitialMint>, salt))، که salt ۳۲ بایتی است و سازنده آن را برمی‌گزیند؛ به‌صورت hex و به‌صورت rpl1… نمایش داده می‌شود
شناسهٔ دارایی توکن RPL، پل‌شدهblake3("rand-rpl-asset" || bincode(name, symbol, BRIDGE_DECIMALS, salt)) — نه روی یک جفت (chain, token)، زیرا یک توکن پل‌شده چند پشتوانه را در بر می‌گیرد
پوشانندهٔ سپردهٔ پلr = blake3("rand-deposit-r-1" || mu)، تنها rای که پذیرش برای یک BridgeAttest می‌پذیرد (در غیر این صورت WrongDepositBlinding)
پوشانندهٔ یادداشت‌های کارمزد پل (زنجیرهٔ ۲۰)یادداشت کارمزد یک سپرده: r = blake3("rand-bridge-fee-r-1" || mu)؛ و یک سوزاندن: r = blake3("rand-bridge-burn-fee-r-1" || txid)؛ هر دو به‌صورت هشت واژهٔ little-endian خوانده می‌شوند. این یادداشت‌ها پاکت ندارند: همهٔ فیلدها عمومی‌اند و مالک همان bridge.fees.recipient در genesis است
گیرندهٔ پلblake3("rand-shielded-recipient" || pk_bytes || kem_ek) روی نشانی shielded کامل
پیام Mint شیر آب (faucet)blake3("rand-mint-2" || bincode(chain_id, cm, pk, time, r, envelope, amount))؛ روی زنجیرهٔ ۲۰ blake3("rand-mint-3" || bincode(genesis_hash, chain_id, cm, pk, time, r, envelope, amount))
پیام‌های TokenMint، SetAuthorityblake3("rand-rpl-mint-1" or "rand-rpl-authority-1", chain_id || asset_id || nonce || body)؛ بدنهٔ mint شامل blake3(bincode(envelope)) است. روی زنجیرهٔ ۲۰ rand-rpl-mint-2 و rand-rpl-authority-2، با هش پیدایش در ابتدا
پیام Registrationblake3("rand-register-2" || bincode(genesis_hash, chain_id, validator, payout)) روی genesis با staking.registration_v2 یا binding_domain: 1، مانند زنجیرهٔ ۲۰ (ثبت‌نام نسخهٔ ۱ در آن‌جا رد می‌شود)؛ در غیر این صورت blake3("rand-register" || bincode(chain_id, payout))
رأی AdmitValidator (زنجیرهٔ ۲۰)blake3("rand-admit-validator-1" || genesis_hash || candidate_address)، که هر validator رأی‌دهنده آن را امضا می‌کند
پیام Unbondblake3("rand-unbond" || bincode(chain_id, validator, amount, nonce))؛ روی زنجیرهٔ ۲۰ blake3("rand-unbond-2" || bincode(genesis_hash, chain_id, validator, amount, nonce))
پیام Withdrawblake3("rand-withdraw" || bincode(chain_id, validator, amount, nonce, time, r, envelope))؛ روی زنجیرهٔ ۲۰ rand-withdraw-2، با هش پیدایش در ابتدا
گره Merkle (درخت‌های وضعیت)blake3("rand-merkle-node" || left || right)
برگ ثبت توکنblake3("rand-token-leaf-1" || bincode(TokenInfo))، به ترتیب اندیس، زیر tokens_root
ریشهٔ وضعیتروی زنجیرهٔ ۲۰، blake3("rand-state-admitted-1" || inner || admitted_root) پیرامون inner = blake3("rand-state-8" || tree_root || nullifier_root || validators_root || programs_root || bridge_root || tokens_root || faucet_epoch || faucet_minted_in_epoch || bond_queue_root || gas_price || byte_price || program_state_root)، که در آن program_state_root = blake3("rand-program-state-1" || cells_root || vaults_root) (RPL-2) است، دو شمارندهٔ faucet و دو قیمت زنده هر یک ۸ بایت big-endian هستند، و پوشش بیرونی مجموعهٔ پذیرفته‌شده را متعهد می‌شود (staking.admission_by_vote). ریشهٔ زنجیرهٔ ۱۹ blake3("rand-state-7" || …) بود روی همان فیلدها تا byte_price (بخش staking در genesis آن سه را پس از tokens_root زیر rand-state-5 می‌افزاید، مانند زنجیره‌های ۱۵ تا ۱۷؛ بخش gas.dynamic در genesis آن دو قیمت را می‌افزاید و دامنه را به rand-state-7 می‌برد)؛ rand-state-4 روی شش فیلد نخست در زنجیرهٔ ۱۴؛ rand-state-2 روی چهار فیلد نخست در زنجیری که بخش bridge، tokens یا aggregation ندارد (اجماع)

Poseidon2 با یک برچسب دامنه: H(domain, msg) = sponge_hash([domain, msg...])، که برچسب نخستین واژهٔ جذب‌شده است، هر واژه یک عنصر Goldilocks است و چکیدهٔ ۴ عنصری به هشت واژهٔ u32 تقسیم می‌شود (نیمهٔ پایین و سپس نیمهٔ بالای هر عنصر). برچسب‌های دامنه:

برچسبمقدارساختار
NK1کلید مشاهده nk = H(1, sk)
PK2مقدار عمومی نوت pk = H(2, nk)
NF3نالیفایر H(3, nk || cm)
CM4تعهد نوت H(4, pk(8) || from(8) || amount_lo || amount_hi || asset || time || r(8)) — ۲۸ واژه
OVK, KEM_SEED5, 6کلید مشاهده خروجی و بذر ML-KEM، از طریق یک هش پهن در حالت شمارنده [domain, nk, counter]
NODE7گره درخت H(7, left || right)؛ برگ خالی تماماً صفر است
HC8چکیده برنامه؛ برچسب، base_pc و len در خطوط ظرفیت نخستین جایگشت قرار می‌گیرند و سپس واژه‌ها چهارتا‌چهارتا در هر بلوک جذب می‌شوند
OUT9چکیده خروجی guest انتقال
IN10H_IN: سرآیند ظرفیت [10, n_in, 0]، سپس یک سالت ۴ واژه‌ای، سپس ورودی‌ها
BUNDLE11چکیده بسته ۲ورودی-۲خروجی بازنشسته روی ۴۷ واژه عمومی؛ دیگر هیچ زنجیره‌ای آن guest را مقید نمی‌کند
hidden bundle64چکیده بسته دارایی پنهان روی ۸۱ واژه در زنجیره‌های ۱۴ تا ۱۶: لنگر، چهار نالیفایر، چهار تعهد، fee، burn_a، burn_r (هر یک دو واژه)، burn_asset، time و در پایان واژه آلودگی. در زنجیره‌های ۱۷ تا ۲۰ (guest بسته نسخه ۳) ۸۹ واژه است: هشت واژه تعهد مجوز c بلافاصله پیش از واژه آلودگی قرار دارند. دارایی خصوصی A در آن نیست. این برچسب محلیِ گره است و از برچسب‌های ۱ تا ۱۵ نسخه همراه‌شده فاصله دارد
AUTH65تعهد مجوز c = H(65, nk || salt)، ۱۶ واژه، با یک سالت ۲۵۶ بیتی تازه برای هر بسته؛ توسط اثبات بسته درون چکیده‌اش و توسط اثبات مجوز به‌صورت هشت واژه خروجی‌اش منتشر می‌شود و بسته آن را با نام auth_commit حمل می‌کند (زنجیره‌های ۱۷ تا ۲۰). محلیِ گره، مانند 64
PUB15H_PUB: سرآیند [15, n_pub, 0]، بدون سالت؛ برای یک برنامه، در زنجیره ۲۰ واژه‌ها هنگام استقرار ثابت می‌شوند (حداکثر 32,768)، قطعه هر فراخوانی همان واژه‌ها به‌علاوه هشت واژه اتصال فراخوانی است و فراخوانی با چکیده آن قطعه بررسی می‌شود؛ برای اثبات بسته و اثبات مجوز، قطعه همان هشت واژه اتصال تراکنش است؛ genesis بدون max_program_public_words فقط قطعه تهی را می‌پذیرد

hc، H_IN و H_PUB اسفنج‌های ساده با پیشوند پیام نیستند: سرآیند به ظرفیت می‌رود تا سطرهای چکیده در جدول cpu در هر جایگشت دقیقاً چهار واژه جذب کنند. آن‌ها را با کریت همراه‌شده بازتولید کنید (randprotocol_zkvm::hash::{input_digest, public_digest}، isa::Program::digest) و دستی انجام ندهید.

اسفنج ساده پدینگ ندارد، بنابراین درون بلوک نخست [a] و [a, 0] هش یکسانی دارند. هر ساختار بالا پیامی با طول ثابت را زیر برچسب خودش هش می‌کند. برای داده‌ای که طولش می‌تواند تغییر کند، مجموعه قیود ۷ یک اسفنج مقید به طول افزود (hash::sponge_hash_len، فراخوان سیستمی POSEIDON2_LEN): این اسفنج از حالت [0, 0, 0, 0, n, 0, 0, 0] شروع می‌کند، که n تعداد واژه‌هاست، و دست‌کم یک‌بار جایگشت می‌دهد. هشی متفاوت از همان واژه‌هاست و هیچ نوت، نالیفایر، ریشه یا چکیده‌ای در زنجیره از آن استفاده نمی‌کند.

دو ویژگی که باید به یاد داشت: hc الزام‌آور است اما پوشاننده نیست (سالت ندارد، پس برنامه‌ای حدس‌زده‌شده را می‌توان تأیید کرد و دو استقرار از یک برنامه قابل پیوند به هم‌اند)، و H_IN هم الزام‌آور است و هم پوشاننده (یک سالت ۱۲۸ بیتی تازه برای هر اثبات)، بنابراین انتشار H_IN تا وقتی دارنده سالت آن را باز نکند، چیزی درباره ورودی‌ها آشکار نمی‌کند.

اشتقاق کلیدها

کلیداز
جفت‌کلید Dilithium2 (گره)قطعی، از بذر ۳۲ بایتی
libp2p ed25519 (گره)blake3("rand-p2p-identity" || seed)
کلید مشاهده، pk، ovk، جفت‌کلید ML-KEM (کیف پول)اشتقاق‌های Poseidon2 از کلید خرج، همان‌طور که در جدول بالا آمد؛ جفت ML-KEM برابر MlKem768::from_seed(kem_seed) است

مقالات موجود در صفحه مقالات استدلال‌های امنیتی را در بر دارند: انتخاب‌های پساکوانتومی، حسابداری درستی FRI و دلیل نگه داشتن ۸۰ پرس‌وجو، و کران طول ردیابی.

آخرین بار با کامیت c0878c3f از fullnode (زنجیرهٔ 21) در تاریخ 2026-10-12 بررسی شد. هرجا کد و این صفحه با هم اختلاف دارند، حق با کد است؛ به ما اطلاع دهید.