Rand Protocol
ドキュメント
ガイド

暗号技術

使用しているプリミティブとその用途、本番環境の STARK と FRI のパラメータ、そして開発者が再現する必要のあるハッシュ構成について説明します。

このページは、チェーンと連携する際にライブラリを選ぶとき、パラメータをノードが強制する内容と照合するとき、そして id やコミットメントを自分で再計算するときに使ってください。ここに挙げた値はすべて、chain 20(fullnode v0.6.8)上でコードが実際に使っているものです。

プリミティブと用途

プリミティブパラメータ用途
Dilithium2公開鍵 1,312 バイト、署名 2,420 バイト。鍵ペアは 32 バイトのシードから導出バリデータの投票とブロック提案、faucet のミント、Unbond、Withdraw、バリデータの Registration、AdmitValidator の投票(chain 20)、アグリゲータのアクション、RPL トークンの Key ミント権限(TokenMint、SetAuthority)、ブリッジのポスト量子ガーディアン共同署名とその停止鍵、さらに chain 20 ではローテーションにおける新しい鍵の所有証明(後述)
ML-KEM-768カプセル化鍵 1,184 バイト、暗号文 1,088 バイトノートエンベロープのトランザクションごとの鍵を受信者のアドレス宛てに封印すること、呼び出し入力エンベロープを監査人宛てに封印すること、証明ジョブをペアリング済みのプルーバー宛てに封印すること
ChaCha20-Poly130532 バイトの鍵、先頭に付加するランダムな 12 バイトのナンス、16 バイトのタグエンベロープのすべての部分(ノート本体、ラップされたトランザクション鍵、呼び出し入力のトランスクリプト)、ペアリング済みプルーバーのジョブと応答
BLAKE332 バイト出力。常にドメイン文字列を前置アドレス、トランザクション id、トランザクションバインディングと呼び出しバインディング、プログラム id、トークンのアセット id、ステートルートとその Merkle ツリー、p2p アイデンティティ、署名メッセージ、ブリッジのアセット id、ブリッジ入金のブラインディング、ブリッジ手数料ノートのブラインディング
Poseidon2 over Goldilocks幅 8、レート 4、キャパシティ 4、パディングなしの上書きスポンジ。メッセージ要素は 32 ビットワード。86 個のラウンド定数は chain-15 のカット以降ノードのソース(poseidon2_constants.rs)にリテラルのテーブルとして置かれており、値はそれ以前にシードから生成していたものと同じ証明の内部で使うすべて:鍵、ノートコミットメント、ヌリファイア、コミットメントツリー、プログラムダイジェスト hc、入力コミットメント H_IN と H_PUB、バンドルダイジェスト、認可コミットメント
secp256k1 ECDSA + keccak256low-s 署名、Ethereum 形式の 20 バイトのガーディアンアドレス、mu = keccak256(keccak256(body))ブリッジのガーディアン証明。これにより同じ鍵が EVM コントラクト、Solana プログラム、Rand で使えます。Rand ではすべての証明にさらに下記の Dilithium2 クォーラムが必要です
bech32m(BIP-350)human-readable part は rpl、ペイロード 32 バイト、データ文字 52 + チェックサム文字 6 = 62RPL トークンのアセット id のテキスト形式 rpl1…
Plonky3 batch STARKGoldilocks p = 2⁶⁴ − 2³² + 1、hiding FRI、blowup 8、folding arity 8、80 クエリ、proof-of-work 20 ビットすべてのバンドル証明、認可証明、呼び出し証明。バンドル証明とその認可証明は、そのトランザクションの 8 個のバインディングワードをパブリック入力セグメントとして持ちます

ホワイトペーパーの目標パラメータは、実装が実際に使う値と異なる箇所があります(たとえば、論文の 384 ビットのトランスクリプトハッシュに対し、zkVM は Poseidon2 のトランスクリプトを使います)。これらのページが記述するのはコードの内容です。

ブリッジにおけるポスト量子共同署名

ブリッジのガーディアン証明は 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 クォーラムが署名する値です。M に含まれる Rand の chain id により、ガーディアン鍵が再利用されたとしても、testnet の共同署名が別の Rand チェーンで検証を通ることはありません。M がバインドするのは chain id のみで、これは chain 20 でも同じです。binding_domain がジェネシスハッシュの背後へ移さなかった唯一の署名対象メッセージであり、それに署名するガーディアンのデーモンが別のリポジトリにあるためです。同じ chain id と同じガーディアンセットを持つチェーンのコピーは、その入金の共同署名を受け入れてしまいます。ガーディアンセットのインデックスは M に含まれないため、共同署名は ECDSA セットのローテーションをまたいで有効です。アクションの pq_signatures フィールドは PqSignature { index: u8, signature } のリストで、安価な検査を先に、高価な検査を後にして検証されます。quorum(n) ≤ len ≤ n(PqNoQuorum)、インデックスが厳密に増加していること(PqIndexOrder)、すべてのインデックスが n 未満であること(PqIndexOutOfRange)、すべての署名がちょうど 2,420 バイトであること(PqBadSignatureLength)、最後に、すべての署名が pq_guardians[index] の下で検証を通ること(PqBadSignature)です。PQ の署名者が ECDSA の署名者と同じである必要はなく、それぞれのクォーラムは別々に数えられます。このフィールドはトランザクションバインディングの内側にあるため、コピーから取り除いたり差し替えたりすることはできません。

PQ セットはジェネシスの bridge.pq_guardians です。chain 20 では chain 15 から 19 と同じく 1,312 バイトの鍵 8 個で、ジェネシスの ECDSA セット(ガーディアンセット 1)とインデックスが対応しています(chain 14 は 6 個で、セット 0 に対応していました)。ECDSA のガーディアンセットのローテーションがこれを動かすことはありません。chain 14 ではチェーンの存続期間中固定でしたが、chain 15 以降はジェネシスにブリッジの rules_v2 グループが含まれ、その下では PQ クォーラムが PQ セット全体(RotatePqGuardians)または停止鍵(RotatePauseKey)を置き換えられます。いずれもブリッジの rotation_nonce の下で行われます。chain 20 のジェネシスは bridge.rotation を追加します。ローテーションは V2 アクションでなければならず、各新しい鍵自身が同じメッセージに対して行う Dilithium2 署名(所有証明)を伴います。また、現在の停止鍵がキャンセルしない限り、確定から 1 日後に有効になります(Bridge)。rand_getBridgeState は鍵を返し、デコードされた bridge_attest は署名したインデックスである pq_signers を列挙します。同じ PQ クォーラムが、ブリッジのガバナンスメッセージも承認します。各メッセージは、chain id とナンスを含む固定のビッグエンディアンのレイアウトです。chain 20(ジェネシスの binding_domain: 1)では、各ドメインのバージョン桁が 2 になり、32 バイトのジェネシスハッシュがドメインと chain id の間に入ります。chain 14 から 19 は -1 の形式を使います。

メッセージドメイン(chain 14–19 / chain 20)署名者
M_pauserand-bridge-pause-1 / -2ジェネシスの唯一の停止鍵(Dilithium2)。停止はできるが、停止解除はできない
M_unpauserand-bridge-pq-unpause-1 / -2PQ ガーディアンのクォーラム
M_listrand-bridge-pq-list-1 / -2PQ ガーディアンのクォーラム(ListBacking)
M_registerrand-bridge-pq-register-1 / -2PQ ガーディアンのクォーラム(RegisterBridgedToken)
M_rotate_pqrand-bridge-pq-rotate-pq-1 / -2現在の PQ セットのクォーラム(RotatePqGuardians、rules_v2 のチェーン)。chain 20 では所有証明として各新しい鍵も署名
M_rotate_pauserand-bridge-pq-rotate-pause-1 / -2現在の PQ セットのクォーラム(RotatePauseKey、rules_v2 のチェーン)。chain 20 では新しい鍵も署名
M_cancelrand-bridge-cancel-rotation-1 / -2、末尾に kind バイト現在の停止鍵(CancelRotation、bridge.rotation を持つチェーン:chain 20)

本番環境の STARK

zkVM は制約セット 8 にあります。9 個の必須テーブル(program、cpu、memory、alu、range、nibble、poseidon2、input、public)に加え、ゲストが対応するシステムコールを呼び出した場合にのみ証明が持つ keccak テーブルと sha256 テーブルがあり、17 本のバスで接続され、1 つのバッチ STARK として証明されます。制約セット 7 以降、宣言されたすべてのテーブルは少なくとも 2⁷ 行を持ち、すべてのテーブルの LogUp 終端は 17 番目のバス BLIND を通じてブラインドされます。証明のパブリックインターフェースは 35 個のフィールド要素(pv::NUM)です。エントリ pc、ティア、8 個の出力ワード、プログラムダイジェスト hc(8 ワード)、ソルト付きのプライベート入力コミットメント H_IN(8)、ソルトなしのパブリックセグメントダイジェスト H_PUB(8)、そして制約セット 8 以降は宣言されたガス上限 GAS_LIMIT です。

パラメータ本番値備考
FRI クエリ数80制約セット 3 と 4 の 27 クエリへの調整は、2026-09-12 の監査後に元へ戻されました。証明可能なセキュリティが約 42 ビットにとどまったためです
blowup8(log_blowup = 3)すべてのテーブルの最大制約次数は、上限 8 の下に固定されています
folding arity8
proof-of-work ビット数20
soundness3·80 + 20 = 260 ビット(予想値、ethSTARK)。proximity gaps の下で証明可能なのは約 86 ビット
ゼロ知識性統計的:LDE と FRI バッチ多項式がランダム化されるため、同じ実行から生成した 2 つの証明は異なります制約セット 7 以降、宣言されたすべてのテーブルは少なくとも 2⁷ 行で、証明が開く 82 点より多く、LogUp 終端はブラインドされています
ティア10、12、14、16、18、20証明が明らかにするのはティアであり、サイクル数は明らかにしません。fullnode v0.5.6 以降、ティア 14 を超える呼び出し証明は拒否され(CallTierTooHigh)、バンドル証明はティア 14 に、認可証明はティア 10 に固定されます
証明サイズ上限ジェネシスの max_proof_bytes:chain 17 から 20 は 4 MiB(4,194,304)、chain 13 から 16 は 8 MiB、chain 12 のようにこれを持たないジェネシスでは 2 MiB(MAX_PROOF_BYTES)2 MiB は、デプロイ済みのゲストが生成できるハッシュテーブルを持たないすべての証明より大きく、keccak を含む証明より小さい値です。4 MiB は両方を受け入れます
ガスcpu 1 行あたり 1、Poseidon2 absorb 1 行あたり 3、SHA256 1 行あたり 64、KECCAK 1 行あたり 192cpu テーブルの GAS 列に累積され、最大でも GAS_LIMIT までしか証明されません。検証者は gas_max(t, k, s) = (2ᵗ − 1) + 2ᵗ⁻² + 191·(2ᵏ/32) + 63·(2ˢ/64) を超える上限を拒否します。この値は、ハッシュを使わないティア 10 のヘッダーでは 1,279、ティア 14 のヘッダーでは 20,479 です

コンストレイントセット6での実測サイズ(Apple Silicon、リリースビルド)は次のとおりです。keccak を含まないプロダクション証明は、ティア10で 1,298,729 バイト、ティア12で 1,359,978 バイトでした。keccak を含むティア10の証明は 3,198,430 バイトで、既定の 2 MiB を超え、チェーン13〜15の 8 MiB を下回ります。廃止された 2-in-2-out のバンドルゲストのティア14の証明は、チェーン8で 1,321,773 バイト、チェーン13で 1,418,406〜1,420,423 バイトでした。チェーン14の 4-in-4-out の hidden-asset バンドルゲストは、ハッシュテーブルをどちらも持たないままティア14にとどまり、その証明はチェーン14(2026-09-20)で 1,422,116 バイトと 1,423,170 バイトでした。チェーン15も同じゲストを固定しています(hc_bundle は変更なし)。そこではバンドル証明が public_log_height を 4(8個のバインディングワードの高さ)と宣言し、ノードは検証鍵を構築する前に、それ以外の値をすべて拒否しました。2026-09-19 にチェーン13で作成した、keccak を含む ERC-20 approve 呼び出しの証明(ティア16)は 3,412,405 バイトです。fullnode v0.5.6 以降のすべてのチェーンは、この呼び出しをティア16で拒否します。

コンストレイントセット7のブラインディング列とテーブルのフロアにより、ハッシュを含まない証明は約5%大きくなります。fullnode による 2026-09-28 の実測では、fib はティア10で 1,367,688 バイト、ティア12で 1,424,299 バイト、keccak を含むティア10の証明は 3,283,898 バイト、ティア14の hidden-asset バンドル証明は 1,498,821 バイト(ゲスト v1)と 1,497,156 バイト(ゲスト v2)でした。それ以降、バンドル証明は public_log_height を 7 と宣言します。コンストレイントセット8の増加は 1% 未満です。2026-09-30 にチェーン18で実測した値(Apple Silicon)は次のとおりです。認可証明は 1,364,940〜1,375,371 バイト(ティア10)、バンドル証明は 1,494,151〜1,504,260 バイト(ティア14、ゲスト v3)、呼び出し証明は、ハッシュテーブルなしのティア14で 1,498,589 バイト、SHA-256 テーブルありのティア14で 1,911,152 バイト、Keccak テーブルありのティア12で 3,346,865 バイトです。いずれも、チェーン18〜20の 4 MiB の上限に収まります。

検証にかかる時間は、検証鍵がウォームな状態で約 16 ms、(tier, heights) の鍵を初めて構築するときで約 230 ms です。test FRI プロファイル(16クエリ)はテストスイート用で、安全ではありません。チェーン20のジェネシスは production を固定しています。fullnode v0.6.8 はコンストレイントを一切変更しません。チェーン20は、チェーン17〜19と同じ hc_bundle と hc_auth を固定しています。

再現できるハッシュ構成

ドメイン付きの BLAKE3: blake3(domain || data)。ドメイン文字列は区切りなしで連結します。

バインディングドメイン。 チェーン20のジェネシスは binding_domain: 1 を設定しています(fullnode v0.6.8、audit v6 BIND-1)。このようなチェーンでは、チェーン ID だけをバインドしていたすべての証明バインディングと署名済みアクションメッセージが、ジェネシスハッシュもバインドするようになります。ドメインのバージョン番号が1つ上がり、32バイトのジェネシスハッシュがプリイメージの先頭、チェーン ID の前に置かれます。これにより、あるチェーン向けに作った証明や署名は、チェーン ID と鍵を再利用した別のチェーン(再カットの場合など)でも、他のどのチェーンでも検証を通りません。バインディングワードは証明の公開入力なので、ゲストも検証鍵も変わっていません。表には両方の形式を載せています。チェーン14〜19は前者をバイト単位でそのまま使います。以前からジェネシスにバインドされていて変更がないものは、投票と提案(consensus_domain: 1 以降)、v2 の Registration、AdmitValidator の投票です。移していないものは、ブリッジのミント共同署名(前述)です。チェーン20で送信するにはウォレットが v0.6.8 である必要があり、形式はノードの申告ではなくチェーン ID で決めます。rand_getLimits.binding_domain がそれを報告します。

値構成
透明アドレスblake3("rand-address" || dilithium2_public_key)、base58
トランザクション IDblake3("rand-txid-3" || bincode(view))。view は、バンドルの証明バイト列を blake3(proof) に、認可証明を blake3(auth_proof) に置き換えたトランザクションです。auth_commit はそのまま入ります。ドメインはチェーン16までは認可フィールドなしの rand-txid-2 でした
トランザクションバインディングチェーン14〜19では blake3("rand-tx-bind-1" || bincode(chain_id, bundle', action'))、チェーン20では blake3("rand-tx-bind-2" || bincode(genesis_hash, chain_id, bundle', action'))。リトルエンディアンの u32 ワード8個です。' は bundle.proof、bundle.auth_proof、Aggregate の proof を空のベクタに置き換えることを表します。bincode は固定幅のリトルエンディアン整数を使います。すべてのバンドル証明と認可証明は、これらのワードに対して作成され、検証されます
呼び出しバインディングblake3("rand-call-bind-1" || …)。チェーン20ではジェネシスハッシュを先頭に置いた rand-call-bind-2。トランザクションバインディングの構成に、Call(または Invoke)自身の proof も空にしたものです。チェーン20のような hardening_v6 ジェネシスでは、呼び出し証明の公開セグメントは、プログラムのデプロイ時の公開ワードに続いてこの8ワードが並び、Invoke ではさらにその後ろに、遷移がコンテキストワードとして加わります
プログラム IDblake3("rand-program" || base_pc as 4 LE bytes || words as 4 LE bytes each)
p2p アイデンティティblake3("rand-p2p-identity" || seed) から作る ed25519 鍵
ブリッジアセット ID(バッキングごと)blake3("rand-bridge-asset" || token_chain as 2 BE bytes || token_address (32 bytes)) — rand_bridgeAssetId が計算し、rand_getAssets がバッキング行ごとに出力します。これはワイヤ上でソースのコインを識別するもので、トークンを識別するものではありません
RPL トークンアセット ID(ネイティブ)blake3("rand-rpl-asset" || bincode(name, symbol, decimals, authority, initial: Option<InitialMint>, salt))。salt は作成者が選ぶ32バイトです。16進数と rpl1… で表示されます
RPL トークンアセット ID(ブリッジ)blake3("rand-rpl-asset" || bincode(name, symbol, BRIDGE_DECIMALS, salt)) — 1つのブリッジトークンが複数のバッキングにまたがるため、(chain, token) の組にはかけません
ブリッジ入金のブラインディングr = blake3("rand-deposit-r-1" || mu)。BridgeAttest の受理が認める唯一の r です(それ以外は WrongDepositBlinding)
ブリッジ手数料ノートのブラインディング(チェーン20)入金の手数料ノート: r = blake3("rand-bridge-fee-r-1" || mu)。バーンの手数料ノート: r = blake3("rand-bridge-burn-fee-r-1" || txid)。どちらも8個のリトルエンディアンワードとして読みます。これらのノートにエンベロープはなく、すべてのフィールドが公開で、所有者はジェネシスの bridge.fees.recipient です
ブリッジ受取人完全なシールドアドレスにかけた blake3("rand-shielded-recipient" || pk_bytes || kem_ek)
faucet の Mint メッセージblake3("rand-mint-2" || bincode(chain_id, cm, pk, time, r, envelope, amount))。チェーン20では blake3("rand-mint-3" || bincode(genesis_hash, chain_id, cm, pk, time, r, envelope, amount))
TokenMint、SetAuthority メッセージblake3("rand-rpl-mint-1" or "rand-rpl-authority-1", chain_id || asset_id || nonce || body)。ミントの body には blake3(bincode(envelope)) が含まれます。チェーン20では rand-rpl-mint-2 と rand-rpl-authority-2 で、ジェネシスハッシュが先頭に来ます
Registration メッセージstaking.registration_v2 または binding_domain: 1 を持つジェネシス(チェーン20など)では blake3("rand-register-2" || bincode(genesis_hash, chain_id, validator, payout))(v1 の登録はそこでは拒否されます)。それ以外では blake3("rand-register" || bincode(chain_id, payout))
AdmitValidator の投票(チェーン20)blake3("rand-admit-validator-1" || genesis_hash || candidate_address)。投票する各バリデータが署名します
Unbond メッセージblake3("rand-unbond" || bincode(chain_id, validator, amount, nonce))。チェーン20では blake3("rand-unbond-2" || bincode(genesis_hash, chain_id, validator, amount, nonce))
Withdraw メッセージblake3("rand-withdraw" || bincode(chain_id, validator, amount, nonce, time, r, envelope))。チェーン20では rand-withdraw-2 で、ジェネシスハッシュが先頭に来ます
Merkle ノード(ステートツリー)blake3("rand-merkle-node" || left || right)
トークンレジストリのリーフblake3("rand-token-leaf-1" || bincode(TokenInfo))。インデックス順に tokens_root の下に置かれます
ステートルートチェーン20では、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) を包む blake3("rand-state-admitted-1" || inner || admitted_root)。ここで program_state_root = blake3("rand-program-state-1" || cells_root || vaults_root)(RPL-2)、faucet の2つのカウンタと2つのライブ価格はそれぞれ8バイトのビッグエンディアンで、ラッパーは承認済み集合(staking.admission_by_vote)にコミットします。チェーン19のものは、byte_price までの同じフィールドにかけた blake3("rand-state-7" || …) でした(ジェネシスの staking セクションは、チェーン15〜17のように rand-state-5 の下で tokens_root の後ろに3つを追加し、ジェネシスの gas.dynamic セクションは2つの価格を追加してドメインを rand-state-7 に移します)。チェーン14では先頭の6つにかけた rand-state-4、bridge、tokens、aggregation のセクションを持たないチェーンでは先頭の4つにかけた rand-state-2 です(コンセンサス)

ドメインタグ付きの Poseidon2: H(domain, msg) = sponge_hash([domain, msg...])。タグが最初に吸収されるワードで、各ワードは Goldilocks の要素です。4要素のダイジェストは8個の 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)) — 28ワード
OVK, KEM_SEED5, 6送信用閲覧鍵と ML-KEM シード。カウンターモードのワイドハッシュ [domain, nk, counter] を通して導出します
NODE7ツリーノード H(7, left || right)。空のリーフはすべてゼロです
HC8プログラムダイジェスト。タグ、base_pc、len を最初の置換のキャパシティレーンに置き、その後ワードを1ブロックにつき4ワードずつ吸収します
OUT9送金ゲストの出力ダイジェスト
IN10H_IN: キャパシティヘッダー [10, n_in, 0]、続いて4ワードのソルト、その後に入力が続きます
BUNDLE11廃止された 2入力2出力バンドルの、47個の公開ワードに対するダイジェスト。このゲストを固定しているチェーンはもうありません
hidden bundle64非公開アセットバンドルの、チェーン14から16における81ワードに対するダイジェスト。内訳はアンカー、4つのヌリファイア、4つのコミットメント、fee、burn_a、burn_r(各2ワード)、burn_asset、time、そして最後にテイントワードです。チェーン17から20(バンドルゲスト v3)では89ワードとなり、認可コミットメント c の8ワードがテイントワードの直前に入ります。非公開アセット A は含まれません。このタグはノードローカルであり、ベンダリングされたタグ1から15とは重ならない位置にあります
AUTH65認可コミットメント c = H(65, nk || salt)。16ワードで、バンドルごとに新しい256ビットのソルトを用います。バンドル証明がそのダイジェスト内で公開し、認可証明が8つの出力ワードとして公開し、バンドルが auth_commit として保持します(チェーン17から20)。64と同様にノードローカルです
PUB15H_PUB: ヘッダー [15, n_pub, 0]、ソルトなし。プログラムの場合、チェーン20ではワードはデプロイ時に固定され(最大32,768個)、各呼び出しのセグメントはそれらのワードに呼び出しバインディングの8ワードを続けたものになり、呼び出しはそのセグメントのダイジェストに対して検証されます。バンドル証明と認可証明の場合、セグメントはトランザクションの8個のバインディングワードです。max_program_public_words を持たないジェネシスは、空のセグメントのみを受け入れます

hc、H_IN、H_PUB は、単純なメッセージプレフィックス付きのスポンジではありません。ヘッダーはキャパシティに入るため、cpu テーブルのダイジェスト行は1回の置換でちょうど4ワードを吸収します。手作業ではなく、ベンダリングされたクレート(randprotocol_zkvm::hash::{input_digest, public_digest}、isa::Program::digest)で再現してください。

単純なスポンジはパディングを行わないため、最初のブロック内では [a] と [a, 0] は同じハッシュになります。上記のすべての構成は、固定長のメッセージをそれぞれ固有のタグでハッシュします。長さが変わりうるデータのために、制約セット7で長さ束縛付きスポンジ(hash::sponge_hash_len、POSEIDON2_LEN syscall)が加わりました。このスポンジは状態 [0, 0, 0, 0, n, 0, 0, 0](n はワード数)から始まり、少なくとも1回は置換を行います。同じワード列に対する別のハッシュであり、チェーン上のノート、ヌリファイア、ルート、ダイジェストのいずれもこれを使っていません。

覚えておくべき性質が2つあります。hc は束縛性はあるものの秘匿性はなく(ソルトがないため、推測したプログラムを確認でき、同一プログラムの2つのデプロイを関連付けられます)、H_IN は束縛性に加えて秘匿性もあります(証明ごとに新しい128ビットのソルトを用います)。そのため H_IN を公開しても、ソルトの保持者がそれを開示するまで、入力については何も明らかになりません。

鍵の導出

鍵導出元
Dilithium2 鍵ペア(ノード)32バイトのシードから決定的に導出
libp2p ed25519(ノード)blake3("rand-p2p-identity" || seed)
閲覧鍵、pk、ovk、ML-KEM 鍵ペア(ウォレット)上の表のとおり、支払い鍵から Poseidon2 で導出。ML-KEM ペアは MlKem768::from_seed(kem_seed) です

論文ページの論文には、セキュリティ上の議論が載っています。ポスト量子の選択、FRI の健全性の見積もりと80クエリを維持する理由、そしてトレース長の上限です。

fullnode のコミット c0878c3f(チェーン 21)に対して 2026-10-12 に最終確認しました。 コードとこのページが食い違う場合は、コードが正です。お知らせください。