暗号技術の使い方
各部品のページは、その部品が何を保証するかを述べる。このページは、それをどう実現しているかを述べる。どの群と生成元を使い、どのトランスクリプト・ラベルを付け、検証器がどの等式を検査し、wire 上を何バイトが流れるか、という水準で書く。ここに書いたことはすべて 2026-09-07 にコードから読み取り、ファイル名を挙げてある。コードと古い設計文書が食い違う箇所ではコードの側を報告し、食い違いは末尾に一覧にした。
出典: zkpi/rust/zkfmi-zk (pedersen.rs, sigma.rs, range.rs, bitrange.rs, oneofmany.rs, or_dleq.rs, adaptor.rs, shamir.rs。2026-09-07 までは defmi の main にあった) · defmi/rust/defmi (ledger.rs, notes.rs, note_membership.rs, netting.rs, credit.rs, reconcile.rs, viewing.rs, vetting.rs, assets.rs, pvp.rs) · zkpi, qomm-proofs · zkpi, qomm, oclob, dekyx, zkfmi-crypto · 版は Cargo.lock で固定したもの
群、生成元、ハッシュ
すべての commitment、証明、古典署名は ristretto255 の中にある。Curve25519 上の素数位数群で、4.1.3 に固定した curve25519-dalek を通して扱う。この下限はワークスペースのマニフェストに明記してある。4.1.3 には、コンパイラがスカラー減算に持ち込んだタイミング漏れ(RUSTSEC-2024-0344)の修正が入っている。dalek 系は 2019 年に、Bulletproofs crate と併せて Quarkslab の監査を受けた。生の曲線ではなく Ristretto を選んだ理由はコードに記録してある。以前の版は点へハッシュする際に余因子を消しておらず、よく知られたライブラリが受け入れる符号化のうち 39% は素数位数ではなかった。Ristretto には、間違えようのある余因子がそもそもない。
二つの Pedersen 生成元は、このスタックが自分で選んだものではない。Bulletproofs crate から取っており、g = B(Ristretto の基点)と h = hash-to-group(SHA3-512, B) である。これは意図的である。範囲証明はその crate が選ぶ生成元の下で commit され、決済はその commitment を、台帳が自分で作った commitment と比較する。二つの生成元の組が違っていれば、どの等式も型検査は通るが、両者の間の束縛はすべて空虚になる。範囲証明と決して出会わない用途のためには、SHA-512 で導出した独立な第二の生成元の組がある。
資産ごとの生成元、すなわち asset tag は、固定ラベルと資産識別子を hash-to-group したものである。
A_a = hash_to_group(SHA-512, "qomm:defmi:asset:" || be32(asset_id))
資産 a の残高は A_a の下で commit する。g の代わりに置くもので、h は変えない。したがって h についてだけ語る証明は、値の生成元を替えても有効なままである。同じ hash-to-group の型で、次の三つも作る。審査名簿のおとりの席(ラベル qomm:defmi:vetting:decoy:v1。運営者を含めて誰もおとりの開封値を持たないようにするため)、or-DLEQ 証明の scope 生成元、そして note(価値を一件ずつ表す記録)の証明で、資格のない ring(本物とおとりを混ぜた集合)メンバーの代わりに置く点(DEFMI:NOTE:INELIGIBLE:v2)である。
チャレンジを手作りのハッシュで作ることはない。すべてのシグマ・プロトコルは Merlin トランスクリプト(Keccak-f[1600] 上の STROBE)の上で動く。点はラベルの下に圧縮形で追記し、チャレンジは 64 バイトをスカラーに還元したものである。したがってハッシュ族は三つ現れ、それぞれ役割が一つずつ決まっている。Merlin は証明のチャレンジ、SHA-512 は hash-to-group と鍵導出、SHA-256 はダイジェストと wire 上の識別子である。
| 構成 | トランスクリプトの枠組み | チャレンジ |
|---|---|---|
| 開封証明 | dom = "qomm/opening"、次に C、T | c |
| 0 固定の開封証明(値が 0 であることを固定した開封証明) | 開封の枠組みの前に relation = "zero-opening:v2" | c |
| 生成元をまたぐ等価 | dom = "qomm/xgen"、次に g1 g2 c1 c2 t1 t2 | c |
| 積 | dom = "qomm/product"、次に Ca Cb Cc Tf Tp | c |
| ビット(OR 証明) | dom = "qomm/bit"、次に C T0 T1 | c |
| Groth–Kohlweiss one-of-many | dom = "qomm/gk"、次に集合 C の全体と cl ca cb gk、それぞれ長さ接頭辞付き | x |
| or-DLEQ(クレデンシャルの scope) | qomm:or-dleq:v1、次に registry scope context N P A B | c |
| adaptor Schnorr | qomm:zk:adaptor:v1、次に R X m | c |
| ビット分解の範囲証明 | qomm:bitrange:v1 + コンテキスト、副コンテキストとして :bit:i、:link、|above、|below | 構成要素ごと |
| 照合 | qomm:defmi:reconcile、次に attestation 本文(登録簿、口座、資産、基準日、合計)の SHA-256 | c |
| 審査名簿への所属(vetting) | qomm:defmi:vetting:v1、次にコンテキスト、コホート、グループ、エポック、すべての封筒、handle | x |
| note の ring(Triptych) | DEFMI:NOTE:MEMBERSHIP:v2 + 出力の commitment と note の束縛をハッシュしたコンテキスト | ライブラリ側 |
この表のうち二行には、そうした形にした理由がある。one-of-many のトランスクリプトに証明だけでなく集合も含めるのは、そうしないと攻撃者が二つのメンバーの間で量を動かしつつ、和を変えずに済ませられるからである。審査証明のトランスクリプトにすべての封筒を含めるのは、エポックだけを書く形では、名簿がエポックを上げずに一項目を書き換えられるからである。
commitment と保存則
commitment は加法記法で C = g·v + h·r と書く。あるいは H·q + h·r と書く。後者は、blinding(隠すための乱数)を掛けた asset tag H = A_a + h·γ の下での形である。口座台帳上の保存則は、証明も開封もなしに、状態全体にわたる一つの等式で検査する。
Σ accounts + Σ escrowed(pending PvP legs) == minted
escrow(決済待ちの預かり)は明示的に数える。これを外すと、prepare された脚はすべて価値の消滅に見え、commit はすべて価値の生成に見える。振替ごとに、台帳は準同型性を直接検査し、その後に範囲証明を一つ求める。
balance − amount_commitment == remainder_commitment // arithmetic, no proof
remainder_commitment ∈ [0, 2^bits) // Bulletproof
この一組が「負にならず、生成もされない」の全部である。asset tag の下で唯一細かい点になるのは、blinding の帳簿付けである。支払側の残りの blinding は r_payer − r_amount − γ·balance になる。H^(v−q) h^t が balance / amount に一致しなければならず、そこに γ·v の分がかかるからである。ネッティングのレールも同じ形で、残高の代わりにポジションを置く。
六つのシグマ・プロトコル
zk crate はシグマ・プロトコルを自前で実装している。この用途にある既存の crate は、本番用ではないと自ら述べているか、監査を受けていないかのどちらかだからである。各プロトコルは三手の証明を Merlin 上で非対話にしたもので、形はどれも同じである。第一手の点を commit し、追記し、チャレンジを取り、z = k + c·witness で応答する。圧縮した点とスカラーはそれぞれ 32 バイトである。
| 証明 | 関係 | wire | 用途 |
|---|---|---|---|
| 開封 | (v, r) を知っており、それが C = g·v + h·r を満たす | 点 1 + スカラー 2、96 B | 構成部品。ビット分解による比較基準での連結 |
| 0 固定の開封 | C = h·r。値を 0 に強制し、それ以外は拒否する | 96 B | note 支出の収支(入力 − 出力)、線形関係 |
| 生成元をまたぐ等価 | 同じ v が C₁ = G₁·v + h·r₁ と C₂ = G₂·v + h·r₂ の両方に入っている | 点 2 + スカラー 3、160 B | 指図の金額 ↔ 証券脚。現金の参照値 ↔ 資金脚 |
| 積 | C_c が a·b に commit していること。C_a、C_b は与えられる。C_a·b = g·ab + h·r_a·b を経由して、C_c − C_a·b が h の純粋な倍数になることを示す | 点 2 + スカラー 3、160 B | 資金脚 = 数量 × 価格。ウォーターフォールの順序 |
| 線形 | Σ coeff_i·v_i = constant。Σ coeff_i·C_i − g·constant の 0 固定の開封に畳み込む | 96 B | attestation 付きサイクル、与信の算術 |
| ビット | C が 0 か 1 に開く。Chaum–Pedersen の OR 証明で、二つのチャレンジの和がトランスクリプトのチャレンジになる | 点 2 + スカラー 3、160 B | ビット分解による比較基準の各ビット |
DvP の決済では、このうち三つをまとめて検査する。証券脚が指図の commit された数量を動かすことを示す、生成元をまたぐ証明が一つ。price × amount が commit された現金の参照値に等しいことを示す積の証明が一つ。資金脚がその参照値を動かすことを示す、生成元をまたぐ証明が一つ。三つは一つのバッチに積み、単位元に対する一回のマルチスカラー乗算で決着させる。そのバッチの隣には、健全性の規則が二つコードに書かれている。第一に、バッチの重みは検証器が引く。トランスクリプトからは決して取らない。トランスクリプト由来の重みは証明者も計算できるので、集約した一つの関係を解けてしまうからである。第二に、バッチ化しない検証器は、積の証明の二つの半分を別々に検査しなければならない。和にまとめた検査は、かつて 2 × 3 = 8 という証明を受け入れた。それを偽造するテストが crate に残してある。
範囲証明。本番は Bulletproofs、比較基準はビット分解
本番経路上の範囲証明はすべて Bulletproof(bulletproofs 5.0.0)である。幅は 8、16、32、64 ビットで、2 の冪の個数に集約し、足りない分は値 0 で埋める。幅を超える値は crate が拒否しないので、証明の前に拒否する。単一の 64 ビット証明は 672 バイトで、七つの要素に、2·log₂(n·m) 個の点と二つのスカラーからなる内積論証を加えたものである。検証はマルチスカラー乗算一回で済む。決済パッケージの大きさが幅でほとんど変わらない(64 ビットで 3,424 B)のも、「決済」時間が 7.02 ms なのもそのためである。
ビット分解による構成は、切り替え可能なバックエンドとしてではなく、計測済みの比較基準として残してある。各ビットをリトルエンディアンの順に、新しい blinding の下で commit し、各ビットをそれ専用の副トランスクリプトの下でビット証明によって証明する。そして重み付き和を元の commitment に連結し直す。C − Σ 2^j·C_j は h の純粋な倍数でなければならない。費用はビットあたり 192 バイト(ビットの commitment に 32、その証明に 160)に連結を加えたもので、パッケージの残りを数えると wire 上で 896 B/bit、検証に 0.80 ms/bit である。本番で呼び出すのは、図の「線形バックエンド」の行を作る計測ハーネスだけである。
ただし、その閾値形は本番経路上にある。定足数が、どのメンバーも保持していない値について範囲を証明するとき、ビットごとの OR 証明はシェアからは作れない。そこで閾値範囲証明はビットの commitment と連結を残し、OR を体の等式 b·b = b に置き換えて、これを共同で証明する。閾値 DvP パッケージが二つの予約の残量に使うのはこれであり、zkPI が二つの閾値範囲証明として運ぶのもこれである。有界区間は、幅 ⌈log₂(high − low)⌉ の範囲証明二つで表す。検証器は内側の幅も検査する。これが防ぐ攻撃はコードに書かれている。区間 [−4000, 4000] と値 4001 に対して、value − low は 8001 で、13 ビットの範囲に収まる。一方 high − value は −1、すなわち ℓ − 1 であり、253 ビットの範囲なら収まってしまう。
one-of-many。tag と審査証明には Groth–Kohlweiss、note には Triptych
Groth–Kohlweiss 証明は、集合の中の一つの commitment が 0 に開くことを、どれかを言わずに示す。実装は基数 2 に固定してある。集合の大きさは 2 の冪でなければならず、m = log₂ N とする。証明者は自分の添字のビット(cl_j)、ランダムなマスク(ca_j)、その積(cb_j)に commit し、m 個の多項式係数の点 G_k = Σ_i p_i[k]·C_i + h·ρ_k を公開し、チャレンジに f_j、za_j、zb_j と一つの集約値 zd で答える。証明サイズはちょうど 32·(7m + 1) バイトなので、大きさ 16 の集合で 928 B、集合を倍にするごとに 224 B 増える。検証時間は倍にするごとに 2× ではなく約 1.4× で伸びる。バッチ化したマルチスカラー乗算の効果が現れている。予測はこれを外し、その結果、既定の審査証明の群を 16 から 128 に動かした。
用途は二か所である。一つは口座の発行時で、blinding した tag H が登録済みの資産生成元の一つであることを、商 H − A_i(登録された添字でちょうど h·γ に等しい)の上で示す。資産レジストリは 2 の冪の大きさに詰めてある。資産が上場されるたびに集合が増える形では、上場の事実が漏れるからである。この証明の費用は決済ごとではなく、口座ごとに一度である。もう一つは、下で述べる審査証明である。
note の ring は、もう Groth–Kohlweiss ではない。note レールのバージョン 2 は Tari の Triptych を改作している。Triptych は並列の one-of-many 証明で、同じ ring の添字を、使い捨ての所有者鍵と値の commitment の両方に束縛し、連結不能な linking tag を生む。パラメータは基数 2、指数 max(2, log₂ ring)、ring の上限 4,096、証明の上限 1,800 バイトで、正規符号化は復号時に再検査する。ライブラリはコミットで固定し、ライブラリ自身の注意書きをアダプタでも繰り返している。元の実装は実験的であり、これは監査を主張するものではない。
note、serial、nullifier
アドレスは対 (A, B) = (g·a, g·b) で、閲覧鍵 a と支出鍵 b からなる。二つはウォレットの側で分けてあるので、閲覧鍵は note を見つけられるが支出はできない。拒否するためのメソッドがあるわけではなく、スカラーが単に手元にないだけである。支払側は一時的な e を引き、E = g·e を公開し、note の使い捨ての点 g·H(A·e) + B を作る。受取側は共有スカラーを閲覧鍵から、serial を支出鍵から再計算する。
shared = H_512("qomm:defmi:note:v1:" || "shared" || E·a)
S = shared + b
masks = H_512(… "mask:value" …), H_512(… "mask:blinding" …)
値と blinding は、この二つのスカラーでマスクして運ぶ。したがって走査は note あたり Diffie–Hellman 一回とハッシュ二回で済む(0.05 ms)。note は g·S の点と値の commitment A_a·v + h·r を別々に公開する。一つの点に畳んでしまうと、決済が証明を突き合わせる相手がなくなるからである。note の識別子は DEFMI:NOTE:BODY:v2 の下での本体全体の SHA-256 である。和ではなくハッシュにしたのは、悪意ある受取人がその分解を変えられないようにするためである。
支出時に公開するのは Triptych の linking tag U·S⁻¹ である。U はライブラリの第三の生成元である。g·S もスカラーも決して公開しない。これは 2025 年 9 月の note 証明レビューでの欠陥 N2 だった。検索できる使い捨て鍵を公開していれば、支出が支払いと結び付いてしまうからである。支出の証明が運ぶのは次のものである。tag、入力値への再 blinding した疑似 commitment、Triptych の ring 証明、出力の commitment と note の束縛、出力全体にわたる集約 Bulletproof 一つ、そして 0 固定の開封証明、すなわち pseudo − Σ outputs が h の純粋な倍数であることの証明である(欠陥 N3 は、ここが一般の開封証明だったことである。0 に固定した変種は今では、0 でない値の応答をすべて拒否する)。二重支出の検査は、圧縮した tag を集合に挿入するだけである。使用済みの note はプールに残す。取り除けば、どれが使われたかを言ってしまうからである。プールの状態ルートは追記のたびに更新する SHA-256 で、追記ごとと支出ごとに一度ずつ延長する。以前はプールを歩き直していたが、それが一回の決済のうち 61 ms を占め、暗号処理は約 8 ms だったと計測されたので変更した。
おとりの選び方には実装が二つある。ring_for はプール全体から一様に引き、固定シードでシャッフルして、本物の note が常に先頭に来ないようにする。ring_recent は最新の note から引く。決済は直前に受け取った note で支払うものであり、一様に選んだおとりはたいてい最新ではないからである。計測した攻撃がその差を示している。ring 16、他の通信として決済 16 件があるとき、名目 0.062 に対して 0.359 である。今日ハーネスとテストに配線されているのは一様な規則だけである。新しさの規則はベンチマークの中にあり、台帳自身の状態注記もそう述べている。
PvP のための adaptor signature
状態を共有しない二つの台帳の上にある二つの脚は、ristretto255 上の Schnorr adaptor signature で結ぶ。
pre-sign R = g·r, c = H(R + Y, X, m), s' = r + c·x → (R, s')
verify g·s' == R + c·X
adapt s = s' + y → (R + Y, s)
extract y = s − s'
設計の理由はモジュールに書かれている。ハッシュロックは前像を漏らす。前像は両方の台帳に平文で現れるので、両方を読む者は二つの脚を結び付けられる。adaptor が漏らすのはスカラーであり、それも事前署名の保持者にだけである。どちらの台帳に載るのも通常の Schnorr 署名で、nonce の点が Y だけ違う。Y そのものは決して現れない。プロトコルでは、提案側と応答側がそれぞれ escrow した脚を用意し、事前署名を交換する。最初の claim(受け取り)が署名を公開し、二番目の当事者はそこから y を取り出して他方の脚を claim する。escrow は解放鍵を prepare の時点で記録し、期限後の commit を拒否する。unwind に署名は要らない。期限がすべての権限である。脚の名前は台帳の生涯にわたって使い切りである。安全条件は、二つの期限と、気づいて反応するまでの時間との間の不等式である。反応は 0.06 ms なので、露出の窓を決めるのは二つの台帳の finality であり、このコードの中の何かではない。
登録簿との照合、96 バイト
commitment は準同型なので、口座の残高 commitment の和は、和への commitment である。
Σ C_i = A_a·(Σ v_i) + h·(Σ r_i)
residual = Σ C_i − A_a·N // N is the register's figure
登録簿が正しければ残差は h の純粋な倍数である。それを示す 96 バイトの証明は、合計が一致することだけを言い、それ以外は何も言わない。登録簿の数字、口座、資産、基準日はチャレンジにハッシュされるので、証明を別の attestation(署名付きの申告)に対して再生することはできない。attestation 自体は登録簿の管理者が ed25519 で署名する。集約した blinding を誰かが持つ必要はない。3-of-7 の定足数が応答を組み立てられる。不一致の場所を特定するには開示という代価がかかり、これは設計どおりである。二分探索は 2·log₂ n + 1 個の副証明を作り、公開した範囲をすべて報告する。
(v, r) について residual = g·v + h·r が成り立つと知っていることだけである。開封値を持つ者は、どんな N に対してもそのような証明を作れる。このページを準備しながら書いたテストは、残高の合計が 6,000 のところに、合計 6,500 の照合を受け入れさせた。二つ目のテストは、300 への commitment を 8 ビットの範囲証明に通した。同じ形をしていたビット分解の連結を再証明したものである。同じ型は他にもあった。zkPI と閾値 DvP パッケージが運ぶ閾値範囲証明の連結、quote proof(見積の証明)の「勝者が公開値に開く」段、規則監査の等価の段である。5 か所すべてが、note 支出が既に使っていた 0 固定の開封証明を使うようになった。閾値の組み立てではどのノードの nonce も値の成分を持たないので、組み立てた応答の値の部分は、命題が成り立つときにちょうど 0 になる。二つの偽造は、zkpi にある所有 crate で回帰テストになっている。詳細は決済リポジトリの所見注記にある。scope 付き閲覧
scope の区切りは鍵ではなくアドレスにある。ウォレットは 32 バイトのシードを二つ持ち、scope(銘柄、四半期、委任)ごとに次を導出する。
view_s = H_512("qomm:defmi:view:v1" : "view" : seed_v : scope) // the auditor gets this
spend_s = H_512("qomm:defmi:view:v1" : "spend" : seed_s : scope) // it does not
address = (g·view_s, g·spend_s)
閲覧の付与は、付与先、アドレス、閲覧鍵、有効期間を名指しし、ed25519 で署名する。付与を検査するときは、署名と、鍵が名指しされたアドレスを開くこと、そして日付を確かめる。監査人はその鍵で note を走査する。使い捨ての点と値の commitment の両方が再構成できてはじめて、その note はウォレットのものと認める。監査人は値と blinding を受け取るが、serial は受け取らない。そして上の照合を scope 全体にわたって走らせることができる。限界は三つあり、隠さずに明記してある。第一に、付与は取り消せない。取り消すとはアドレスを交代することである。第二に、閲覧鍵が見るのは入ってくる価値だけである。serial がアドレスに属するのは S − H(E·a) = b のときにちょうど限られ、このハッシュのために、それはシグマ・プロトコルで証明できる範囲の外にある。第三に、scope の区切りは、支払側が現在のアドレスを使うことに依存する。したがって出金は署名付きの開示である。検証ではなく帰属である。コードは、同じ scope について閲覧鍵と serial を組み合わせることを拒否する。その組み合わせはウォレットそのものだからである。
審査証明(vetting)。一つの handle、一つの席、128 の群
審査名簿は封印された封筒 C_i = a_i·G + r_i·h を保持する。handle(参加者を表す仮名の公開点)A が審査を通ったことを示すには、保持者は二つを証明する。一つは、ある C_i − A が 0 への commitment であることの one-of-many 証明である。そのグループは handle の生涯にわたって固定してあるので、ring の交差で絞り込むことはできない。もう一つは、A = a·G が基点だけの冪であることの Schnorr 証明である。この後半が要である。one-of-many 証明だけでは C_ℓ − A が h の倍数であることしか言えず、A + δ·h はどんな δ についてもそれを満たす。A を基点に固定することで、法人ごとの上限にとって「一つの審査に一つの handle」が意味を持つ。おとりの席は誰も開けない点へハッシュしてあるので、名簿の審査済みメンバー数は正直である。席はランダムに割り当てるので、位置が加入の順序を表さない。グループの型は crate の外では構成できないので、検証器は名簿のダイジェストを、チェーンが公開したものと比べなければならない。群 128 の検証は 3.80 ms、1,676 バイトである。16 では所属証明は 1,004 バイトで、うち 928 が ring、64 が制御の証明、12 がグループとエポックである。数千の中に隠れるには、回路の中で検査する Merkle 木が要る。それはこのスタックの土台とは別の証明系である。
ネッティング、日中限度、ウォーターフォール
net のレールは証明を一切使わずに累積する。差分一つ、支払側一つ、受取側一つで、position_payer −= Δ、position_payee += Δ とする。意図的に借方・貸方の組にはしていない。保存則を、忘れられ得る検査ではなく、構成によって成り立たせるためである。gross のレールでは注文ごとにカバーの証明が必要である。net のレールではそれを拒否する。締めの時点で、各 handle は充足を一度証明する。
headroom = position + limit // both commitments
Bulletproof(headroom ∈ [0, 2^bits)) under transcript "qomm:cycle:close" || rail || handle
検証器は命題 position_commitment + cap_commitment を教えられるのではなく、自分で再構成する。他のどの点についての証明も拒否する。上限は commitment として入り、その blinding はポジションの blinding に加える。したがって証明は position + cap についてのものであり、ポジションが 0 のどちら側にあったかは決して明かさない。符号付きのポジションを隠すのに本来必要になるオフセットの技法は、どこにも要らない。余裕(headroom)の算術は 128 ビット整数で行う。リリースビルドでは桁あふれが黙って起きるからである。あふれた余裕は、充足していないポジションを充足していると証明してしまう。
限度の付与では collateral·(10,000 − haircut_bp) − cap·10,000 ≥ 0 を、拡大した余剰に対する範囲証明として証明する。したがって整数除算を証明する必要はどこにもない。幅は拡大率の分の 14 ビットだけ増え、その費用は注文ごとではなく付与時に一度払う。デフォルト・ウォーターフォールは積の証明の連鎖である。draw_k × remaining_{k−1} = 0 を、積の commitment を単位元に固定して示す。後のトランシェは、前のトランシェが尽きたときにだけ引き出せる。attestation 付きサイクルは取引ごとの検証を省く。代わりに、サイクル識別子を長さ接頭辞として付けたダイジェストに対する、定足数の ed25519 署名を要求する。ある静かなサイクルの attestation が、次の静かなサイクルを一度決済してしまったことがあるからである。計測した結果は DeFMI のページにある。取引 64 件、参加者 8 で、gross-gross 400 ms、net-net 247.5 ms、attestation 付き 20.6 ms である。
zkPI。wire が運ぶものと定足数が署名するもの
指図のバージョン 2 の wire 形式はエンコーダから生成する。したがってリポジトリの wire 文書にある配置が、コードからずれることはない。全体がビッグエンディアンである。
| フィールド | バイト | 種類 |
|---|---|---|
magic QOMMZKPI、バージョン 2 | 8 + 2 | タグ |
| 金額、価格、資産の commitment | 3 × 32 | Pedersen、圧縮 Ristretto |
| 支払側 handle、受取側 handle | 2 × 32 | 公開点 g·s_V |
| 期限、nonce | 8 + 32 | Unix 秒。nullifier の入力 |
| quote proof のダイジェスト | 32 | 完全な公開 quote proof の SHA-256 |
| 定足数署名 | 64 | ristretto255 上の FROST |
| 金額の範囲証明、価格の範囲証明 | 4 + n, 4 + m | 閾値ビット分解証明、長さ接頭辞付き |
閾値範囲証明は 2 + bits × (32 + 5 × 32) + 3 × 32 バイトである。内訳は、幅、ビットごとに commitment 一つと五要素の積の証明一つ、そして 96 バイトの連結である。積ベクタの上限である数量 16 ビット、価格 32 ビットでは、それぞれ 3,170 バイトと 6,242 バイトになり、指図全体は 306 + 4 + 3,170 + 4 + 6,242 = 9,726 バイトになる。この数字は上限に依存する。既定の上限は 32/32 で、QOMM の積回路は 64 ビットの金額で動くので、それぞれ合計は異なる。バージョン 1(詰め込んだ見積鍵と Bulletproofs 二本、1,572 バイト)は移行用の形式である。未知のバージョンは推測せず拒否する。誤って解釈した commitment も、なお有効な点として通ってしまうからである。
nullifier は運ばれるのではなく、導出する。nullifier(二重使用を検出するための識別子)は、SHA-512("QOMM:ZKPI:NUL:v1" || nonce || payer_handle || payee_handle) の先頭 32 バイトである。期限は市場で両側から抑える。設定可能な上限(既定 86,400 s)より先ではなく、既に過ぎてもいないことを確かめる。
FROST 署名(frost-ristretto255 3.0、Zcash Foundation の閾値 Schnorr、2023 年に NCC Group が部分的に監査)は、公開フィールドの SHA-512 ダイジェストに対する 3-of-7 署名である。
SHA-512( "QOMM:ZKPI:v2" || len(domain) || domain
|| amount_c || price_c || asset_c || payer_handle || payee_handle
|| deadline || nonce
|| "QOMM:QUOTE-PROOF-DIGEST:v1" || quote_proof_digest )
範囲の証拠は、意図的に署名対象のダイジェストの外にある。市場は範囲を別に検証し、その後に署名を検証する。レールをまたぐ再生を止めるのは domain である。鍵は、認証付きコーディネータ上で走る三ラウンドの FROST DKG(分散鍵生成)から来る。コーディネータが中継するのは、署名付きの身元、公開のブロードキャスト、受信者向けに暗号化した第二ラウンドのパッケージだけである。したがって群の秘密を保持する者は誰もいない。trusted dealer のコンストラクタは存在するが、配備用ではなく fixture(テスト用の固定部品)と札が付いている。署名は標準の二ラウンドで、使い捨ての nonce commitment の後に部分署名を出し、64 バイトに集約する。群の鍵だけを受け取る検証器は、同じ点に集約する別の定足数と区別できない。そのため市場は完全な公開鍵パッケージを保持する。業務システムが使う型付き zkPI は、第二の FROST 署名を加える。その対象は、操作、scope、方向、市場と台帳の識別子、三つの handle、予約識別子と連番、RFQ の nullifier、委任と受領証のダイジェスト、直前の状態ルートである。両方の署名が検証を通らなければならない。
handle は、参加者ごとに 32 バイトのシード一つ、市場ごとにスカラー一つで作る。s_V = H_512("QOMM:ZKPI:HANDLE:v1" || seed || len(venue) || venue)、H_V = g·s_V である。乗法的な代案 g·(a·h(V)) は却下し、その却下はテストになっている。二つの handle が一つの法人に属するときにちょうど H_A·h(B) = H_B·h(A) が成り立つので、公開情報だけで連結できてしまう。計測では、観察者が市場をまたぐ交換の二つの脚を確実に結び付けられた。ドメインをまたぐ DvP は一つの指図を、異なるダイジェストで二つの台帳に射影する。したがって二つの公開記録は取引識別子を共有しない。本文が要求するのは、二つの異なる台帳配備、送り元とも送り先とも異なる escrow、arm < claim < refund の順の期限である。
検証器の終了コードは、0 が受入、1 が拒否、2 が問い合わせ不能である。定足数の鍵と時計がなければ配置だけを検査し、そのことを言葉で明示する。整形式だが未署名の指図に「ok」と印字する道具は、無いより悪いからである。受け入れたテストベクタは、復号して再符号化すると同じバイト列に戻らなければならない。これは「解釈できた」より強い主張である。
閾値証明。シグマの応答は affine なのでシェアを結合できる
定足数が、どのメンバーも保持していない値についての証明を作れる理由は、一行の代数である。シグマの応答 z = k + c·w は witness(証明者が知っている秘密)について affine(一次)である。したがって各ノードは自分の Shamir シェアから z_i = k_i + c·w_i を計算でき、その断片を群のスカラー体の中で Lagrange 結合すれば z になる。これが成り立つのは、シェアが群のスカラー体に住むときだけである。それが下で述べるMPC の体を commitment の群の位数に合わせた構成(matched field)である。ビットごとの範囲証明は OR 構成を使えない。ビットの値から分岐を選ぶ操作は affine ではないからである。閾値形は代わりに b·b = b を積の関係として証明する。その応答は affine である。
プロトコルは commit、reveal、チャレンジ、応答の順で、commitment を先に封印する。各ノードは reveal の前に、自分の nonce の点の SHA-256 封印を QOMM:THRESHOLD-RANGE:ROUND1:v1 の下で公開する。したがって適応的なノードが正直な nonce を打ち消すことはできない。reveal は封印と正確に一致し、定足数も正確に一致し、コンテキストのダイジェストも一致しなければならない。各ノードが持つのは、自分の値のシェア、blinding のシェア、ビットごとの三つ組、そして公開の VSS(検証可能秘密分散)係数 commitment だけである。各ノードは使う前に、自分のシェアを公開の VSS の主張と照らして検査する。公開の主張は指数の中でだけ再構成し、その関数はスカラーのシェアも範囲の値も受け付けない。検証は通常の公開検証器で行い、シェアも定足数もセットアップも入力に取らない。市場はさらに、数学的には有効な単独証明者の Bulletproof を、出所の方針として拒否できる。単独の証明者は、平文の再構成点になっていたはずだからである。
MPC。群の位数の上の malicious Shamir
市場は MP-SPDZ の malicious-shamir-party.x を 7 者、閾値 2 で走らせる。バイナリが無ければ、平文の照合器に落ちるのではなく、一切走ることを拒む。仮想機械に渡す素数は
ℓ = 7237005577332262213973186563042994240857116359379907606001950938285454250989
= 2^252 + 27742317777372353535851937790883648493
であり、これはちょうど ristretto255 の位数である。これが MPC の体を commitment の群の位数に合わせた構成(matched field)である。仮定ではなく、強制している。証明の組立器は回路の素数を群の位数と照らして検査し、合わなければ「回路はある幅の体で書かれ、commitment は 253 ビットの体に住んでいる」という文言で拒否する。回路の変更は一行で、Σ LAGRANGE[p]·input_p を Σ input_p の代わりに置く。公開値と秘密値の積は局所計算なので、ラウンド数も入力数も変わらない。代価は通信量がちょうど 2.00× になることで、要素が 16 バイトから 32 バイトに増える分だけであり、他には何もない。壁時計時間は 1.06 から 1.07× である。計測記録には、自身の誤りも残してある。最初の版はラウンド 2.02×、通信量 14.3× と報告した。その差の全部はコンパイル・フラグ一つによるもので、フレームワークはその警告を毎回の実行で印字していた。
blinding は MPC の中で引く。生成された回路は、価格の blinding とすべてのビットの blinding に sint.get_random() を呼ぶ。したがってどの当事者も r を知らない。勝者は、各メイカーの決済価格に「最良キーと等しいか」のフラグを掛けることで、見ないまま(obliviously)選ぶ。各ノードの永続化ファイルは、自分の Shamir 評価値だけを受け取る。各ノードは次に Com(share_i, blinding_i) を公開し、公開 commitment C = g·price + h·r は指数の中で Lagrange 補間によって再構成する。後段の発行者が平文の見積から何かを作り直すことはない。閾値範囲から指図を組み立てるコンストラクタは、API 上、開封値を受け付けない。これが、発行者プロセスが隠れた再構成点になることを防ぐ。
quote proof は Baum–Damgård–Orlandi の公開監査可能 MPC を実体化したものである。入力提供者は Pedersen commitment を公開し、オンライン段階は線形演算なので、監査人は commitment の上でそれを再実行できる。メイカーごとに次を証明する。
depth_i = slope_i × qty product proof
skew_i = invcoef_i × inv_i product proof
ask_i = level_i + depth_i + skew_i linear, free
bid_i = level_i − spread_i − depth_i + skew_i
fits_i = maxqty_i − qty ≥ 0 range proof
fresh_i = expiry_i − now ≥ 0 range proof
ok_i is a bit and gates the cost
key_i = cost_i × M + i linear, free
そして集合全体について、勝者の commitment が公開値に開くこと、key_i − v ≥ 0 がすべての i について成り立つことを証明する。最小性と所属を合わせれば、ちょうど「v は最小値である」になる。したがって誤った勝者は証明できない。六つの偽造制御(最小でない勝者、期限切れのメイカー、約定できない依頼、無効化された勝者、入れ替えた最小性証明、偽の勝者に対する最小性)が、拒否として記録されている。登録済みの値付け規則の blinding を持たない witness は拒否する。したがって最小値は、証明者が捏造した commitment ではなく、登録済みの commitment の上で取られる。各メイカーの二つの資格範囲は一つの集約 Bulletproof を共有し、最小性の範囲も同様である。host-a で 7 ノードの計測では、メイカー 4 で証明 62 ms、検証 19 ms、メイカー 16 で 246 ms と 71 ms である。3 者の定足数による共同組立は 4.8 ms で、どのノードも witness を持たず、通常の検証器がその結果を受け入れる。
計算したものを commit したものに束縛する。ノードは、配られたシェアを配る側の commitment と照らして検査できる。だが、その後 MPC に入れる値がそのシェアであることは、何によっても強制されない。健全な参加者ごとの入力検査が、この穴を閉じる。回路はシェアを読みながら保存し、全入力が入ったところで一つのランダムな ρ を開き、Σ ρ^k·share_k を commitment の同じ結合と照らして検査する。健全性は Schwartz–Zippel により m/p で、253 ビットの体に 166 個の値で約 2⁻²⁴⁵ である。旧来の狭い体で 6 ビット係数を七回繰り返した 2⁻⁴² を、これで置き換えた。費用はラウンド 1 回の追加と、通信量 0.39% の増加である。配る側は比較ではなく同一性で束縛する。値に commit する参加者が、それをシェアに分ける参加者でもあり、参加者ファイルを書く一回のパスの中でこれを行う。commit していないものを配った側は、何かが計算される前に、最初の不一致の位置で捕まる。
嘘をついた者を名指しする。次数 t の秘密の Shamir シェアは Reed–Solomon 符号語 RS[n, t+1] である。したがって Berlekamp–Welch は ⌊(n − t − 1)/2⌋ 個までの誤ったシェアを訂正し、誤り位置多項式を返す。その根が、嘘をついた参加者の評価点である。n = 7、t = 2 では、新しいシェア分散で容量 2、次数 2t の積では 1 である。n ≥ 4t + 1 はここから来ており、頑健な構成が 9 ノードである理由もこれである。計測では、容量までは 300 回中 300 回で犯人を正確に名指しし、容量を超えると 300 回中 0 回だった。シェアの通信量は 40% 増、追加ラウンドはない。フレームワーク自体は検出しかしない。その整合性の失敗は参加者の情報を運ばず、1 バイトを反転させた四回の実行は、二つの異なる犯人に対して同じ文字列を返した。検出した障害は、Ed25519 署名の受領証(QOMM:AUDIT:v1、ノードごとスロットごとに一つ)と、固定の表を持つ bond の台帳に流す。表は、食い違う二重の発言(equivocation)1,000,000、分岐した状態と省かれたメイカー 500,000、古い状態と不正な署名 250,000、受領証の欠落 50,000 で、相対単位である。説明責任のページに五段からなる説明責任の段階がある。配備中のエンジンは第 1 段である。
差分プライバシー。公開する件数には、MPC の中でサンプリングしたノイズを載せる。秘密シェアされた 64 個のランダムビットで一様な 64 ビットの u を作り、切り詰めた両側幾何分布の量子化した CDF と比較する。越えた閾値の数から、分布の台(取り得る値の範囲)の大きさを引いたものがノイズである。この機構は純粋 DP ではなく (ε, δ) である。台が有限で、裾を折り返しているため、隣接する入力の台が感度の分だけずれるからである。δ は閉形式ではなく、e^ε でのホッケースティック・ダイバージェンスとして計算する。閉形式は過小に見積もるからである。ε = 0.5、台 8 で、計測した公開は δ ≈ 2.1 × 10⁻⁴、28 ラウンド、7 者にわたって 63.9 MB で、ノイズがラウンドの 93% を占める。純粋 DP を主張する前には、正確な非有界サンプラーがなお必要である。より安価な可分な構成は知られているが、実装していない。
転送。入力のシェアは固定長 495 バイトのフレーム(QOMMWIRE v4、体の要素 14 個)で運び、実行体 ℓ の中で引く。以前の版は 2²⁵⁵ − 19 の上でシェアを分けていた。テストでは正しく再構成できたが、フレームワークが自身のスカラー体で還元すると別の値になった。ノードや勝者への封筒は次の構成である。受取人の鍵への X25519 で、封筒ごとに新しい一時鍵を使う。共有秘密に対する HMAC-SHA-256 の extract-and-expand で、一時鍵と見積のダイジェストを info に入れる。ヘッダを関連データとする ChaCha20-Poly1305 で封じる。ノード間のサービス通信は相互認証 TLS である。これは P0 の結合器であり、ハンドシェイク・プロトコルではない。何がこれを置き換えるかは耐量子のページが扱う。
OCLOB。シェアは参加者の手元で作り、到着は 5 台が証明する
法人参加者は、どのコーディネータも注文を見る前に、六つのフィールド(売買の向き、指値、数量、有効期間、期限、GTC フラグ)の次数 2 の Shamir シェアを作る。秘匿性のある Pedersen VSS commitment を付けるので、各ノードは小さな価格や数量を知ることなく、不整合なシェアを拒否できる。また commitment は、裸の g·price のように総当たりで破ることができない。各シェアは一つのノード宛てに封じる。固定 8,192 バイトの平文、新しい X25519 一時鍵、導出した封筒鍵、封筒ヘッダを関連データとする ChaCha20-Poly1305 を使い、相互 TLS の上で直接届ける。コーディネータは注文の内容を受け取らない。
受付の順序は、照合の前に到着証明書で固定する。7 ノード中 5 台が、次の同一の文に Ed25519 で署名する。
SHA-256( "OCLOB:ORDER-VOTE:v1" || len(market) || market || sequence
|| order_commitment || previous_certificate || expires_at )
一つの連番で異なる文に二度投票したノードは、食い違う二重の発言(equivocation)をしたことになる。証明書には、同一の文のダイジェストを持つ少なくとも 5 台の異なるノードと、厳密な署名検証が要る。ログは各証明書が先行する証明書を名指しすることを要求する。したがって連鎖は正規であり、繰り返された commitment は再生である。方針の定数は凍結してある。7 ノード、腐敗し得るのは 2、再構成の定足数 3、順序付けの定足数 5 である。検証器は他のどの形も拒否し、腐敗の上限の二倍を超えない順序付け定足数も拒否する。照合は、ℓ 上の同じ malicious Shamir MPC の中で価格・時間優先により行う。約定ごとに 7 ノードは、616 本の秘密シェアされた証明用ワイヤから、数量と価格の範囲、数量 × 価格、そして現金、証券、メイカー予約の残量が非負であることを共同で証明する。
注文の決済権限は、注文ごとの鍵で封じた固定 65,536 バイトの封筒である。その鍵は 3-of-7 で Feldman シェアされている。参加者が署名し VSS で検証済みのノードの解放のうち、任意の三つから再構成する。スカラーを補間してから公開 commitment と照らして検査する。二つのシェアでは常に失敗する。開く側は平文バッファをゼロ化し、復元した注文をマニフェストと照らして再検査する。ノードは、有効な MPC 結果を永続化した後、決済専用の相互 TLS 接続の上でだけ自分のシェアを解放する。解放が許されるのは、その結果が注文の約定、または残量付きの到着を示したときだけである。照合前に使える単一の復号鍵は存在しない。P0 項目として残るのは旧来のブラウザデモである。そのコーディネータは、シェアに分ける前の平文の注文をまだ見る。ネイティブ経路は見ない。
DeKYX。Ed25519 署名付きの commitment、Schnorr の提示、scope nullifier
クレデンシャルは BBS+ でも CL でもない。発行者の Ed25519 署名であり、署名対象は SHA-256 ダイジェスト(DEKYX:CREDENTIAL:v1)である。ダイジェストには、Pedersen で commit した主体の秘密、属性の Merkle ルート、scope とポリシーのダイジェスト、エポックと有効期間が入る。主体の commitment は g·s + H_b·r で、H_b = hash-to-group("DEKYX:SUBJECT-BLINDING-GENERATOR:v1") である。保持者が s を生成し、発行時に開封値の Okamoto 証明で所持を証明する。発行者が見るのは commitment と証明だけで、どちらのスカラーも見ない。属性は Merkle の葉なので、選択的開示とは、ポリシーが要求する葉とその経路を明かすことである。
提示は、一つのチャレンジの下での二基点 Schnorr AND 証明である。
g·z_s + H_b·z_r == A_c + c·commitment
H_scope·z_s == A_n + c·nullifier where H_scope = hash-to-group("DEKYX:SCOPE-NULLIFIER-GENERATOR:v1" || scope)
c = H_512("DEKYX:ANONYMOUS-PRESENTATION:v1" || credential || context || nullifier || A_c || A_n || disclosed leaves and paths)
これにより次の三つを証明する。署名された commitment の開封値を知っていること。公開された nullifier が H_scope·s であり、その秘密が同じものであること。そしてチャレンジを通して、開示した葉が署名されたルートの下にあること。コンテキスト(scope、提示先、操作、依頼のダイジェスト、nonce、期限)はチャレンジに入っている。したがって、ある操作のトランスクリプトを別の操作に流用することはできない。消費済みの(nullifier、コンテキスト)の組の台帳は、認証付きの記憶装置に置かなければならない。ロールバックされると再生が再び可能になるからである。nullifier N_scope = H_scope·s は決定的である。一つの scope の中では連結でき、scope をまたぐと基点が異なるので連結できない。安定した subject line は、発行者、scope、ポリシー、nullifier の SHA-256 である。発行者の鍵交代を越えて残るので、業務システムは主体が誰かを知らずに、主体ごとに一つの line や一つの限度を強制できる。
失効リストは DEKYX:STATUS-LIST:v1 の下で Ed25519 署名する。整列済みで厳密に増加し、発行者鍵のエポックに束縛され、その有効期間の中でだけ有効である。リストが無いか古ければ閉じる側に失敗し、古いリストが新しいリストを置き換えることはできない。鍵交代は厳密に大きいエポックを登録し、以前のエポックには猶予の期限を設ける。明記された限界は DeKYX のページにあり、ここでも繰り返す。この方式は scope の中では仮名であるが、発行者に対して連結不能ではない。署名された commitment は一つのクレデンシャルの中で変わらないので、発行の記録と相関させ得るからである。発行者に対する連結不能性には、レビューを受けた BBS+ や CL のアダプタのような、再ランダム化できるクレデンシャルが要る。
耐量子ハイブリッド
基盤 crate は ed25519-dalek 2.2.0、ml-dsa 0.1.1、ml-kem 0.3.2、x25519-dalek 2.0.1 を正確に固定し、提供元のコミットと tarball のハッシュを記録している。二つの格子系 crate は独立の監査を受けていない、という提供元の声明も繰り返している。
署名、Ed25519 + ML-DSA-65。ハイブリッド署名は単純な連結 ed25519(64) || ml_dsa_65(3309) で 3,373 バイト、公開鍵は 32 + 1952 バイトである。復号は正確な長さだけを受け付ける。両成分はハイブリッド・スイートの中で生成し、両方が検証を通らなければならない。格子側の誤りが古典のみの受入に変わることは決してない。共有コンテキストは "ZKFMI:SIGNATURE:v1" || purpose(u16) || suite(4) である。ML-DSA はこれを FIPS 204 のコンテキストとして受け取り、ランダム化して署名する。Ed25519 にはコンテキスト入力がないので、別のドメイン "ZKFMI:ED25519-CONTEXT:v1" || len(context) || context || len(message) || message に署名し、厳密に検証する。スイート識別子は wire 上の安定した判別子で、宣言順から推測することは決してない。ハイブリッドは 0x202 である。
鍵交換、X25519 + ML-KEM-768。結合器は次のとおりである。
HKDF-SHA256( salt = "ZKFMI:HYBRID-KEM:v1",
ikm = ss_x25519(32) || ss_mlkem(32) || ct_x25519(32) || ct_mlkem(1088) || suite(4),
info = "ZKFMI:HYBRID-KEM:SESSION:v1", L = 32 )
公開鍵は 1,216 バイト、暗号文は 1,120 バイトで、暗号文の古典側の半分は送信者の一時 X25519 鍵である。寄与のない X25519 の結果は両側で拒否し、秘密はゼロ化する。古典のみの代替経路はない。ML-KEM は暗黙の拒否を行うので、改竄された暗号文は誤りではなく別の秘密を生む。これは P0 の結合器である。相手を認証せず、ハンドシェイクではない。
正規化した前像 ZKFMI:CANONICAL:v1 は、署名が何に対するものかを固定する。内容は、プロトコル名とバージョン、ネットワーク、配備と契約の識別子、用途コード、オブジェクト識別子の一覧、連番または nonce、排他的な期限、スイート、32 バイトの本文ハッシュである。すべて長さ接頭辞付きのビッグエンディアンで、Unicode 正規化も整列もしない。本文の符号化はプロトコル自身のもので、前像に入れる前に SHA-256 でハッシュする。鍵の記録は、参加者、用途、スイート、単調増加する鍵バージョン、有効期間と失効の時刻を持つ。鍵交代は双方向に署名する。旧鍵が ZKFMI:KEY-ROTATION:AUTHORIZE:v1 に、新鍵が ACKNOWLEDGE に署名し、それぞれが両方の束縛を覆う。参加者や用途の変更、世代の飛び越し、鍵の再利用、ハイブリッドから古典へのロールバックは拒否する。
ハイブリッドが古典のまま残すものは、スイート表自体に明記してある。FROST の定足数署名、Pedersen commitment、Bulletproofs、古典 TLS の転送は post_quantum = false を持つ。このフラグはアルゴリズムを分類するもので、実装を保証するものではない。シグマ層をそのまま格子へ差し替えられない理由について、市場側自身の分析は三つの障害を挙げる。第一に大きさである。シグマの一段あたり 4,960 バイトに対して、格子では数キロバイトから数十キロバイトになる。第二に棄却サンプリングである。abort(中断)の判定は結合した応答に対して行うので、棄却は、それが防ぐはずの漏れの後に届く。第三は構造的なもので、短さが Shamir を越えて残らないことである。Lagrange 結合した応答は、短いものに大きな係数を掛けて還元したものだからである。計算自体は既に情報理論的に秘匿されている。量子攻撃者が破るのは commitment の束縛である。署名と KEM のハイブリッドの統合状況は耐量子のページにある。
何が古典で、何が監査済みで、何を主張しないか
- すべての commitment、範囲証明、one-of-many 証明、adaptor signature、定足数署名は、ristretto255 の離散対数に依っている。Pedersen commitment の束縛は計算量的にしか成り立たない。そしてメイカーの値付け規則の commitment は、規則の生涯にわたって置かれたままである。ポジション・ペーパーはこれを、ここで耐量子の方向を採る最も強い論拠として挙げている。量子計算機は要らず、時間だけで足りるからである。
- 耐量子のページのハイブリッドは、署名と鍵交換を覆う。離散対数を破る攻撃者に対して Pedersen commitment を束縛にするものではなく、既存の関係は古典のままだが、別の PQC 証明経路を研究実装している。
- 監査済みの部品は、curve25519-dalek と bulletproofs(Quarkslab 2019)、frost-ristretto255(NCC Group 2023、部分的、v0.6.0)である。未監査なのは、シグマ・プロトコル、Groth–Kohlweiss の実装、Triptych アダプタとその元のライブラリ、note レール、ネッティングと与信の証明、閾値構成、そしてすべてのホストである。二回の内部レビューは先行研究と安全性のページに記録してあるが、監査ではない。
- ここにあるものは、何も MPC を証明しない。検証者は提出されたものを検証する。シェアから証明への引き渡しは束縛されているが、証明されてはいない。束縛のページがその費用を計測している。
古い文書とコードが食い違うところ
2026-09-07 にコードから読み取った。このサイトの部品ページは揃えてある。リポジトリの設計文書は、記した箇所で古い記述をまだ持っている。
| 文書の記述 | コードの動作 | 場所 |
|---|---|---|
| note の ring は、ring のうち一つがこの serial を持つことの Groth–Kohlweiss 証明である | バージョン 2 は連結不能な linking tag を持つ Triptych を使う。Groth–Kohlweiss は asset tag の所属と審査証明に残る | DEFMI.md §5 対 defmi/src/note_membership.rs |
note は一つの点 C = g^S · A_a^v · h^r である | 使い捨ての点と値の commitment は別々に公開する。note の識別子は本体の SHA-256 である | DEFMI.md §5、notes.rs のヘッダ 対 notes.rs の構造体 |
| nullifier は serial から導出し、支出時に公開する | 支出は Triptych の linking tag U·S⁻¹ を公開し、g·S は決して公開しない | note_membership.rs、レビュー所見 N2 |
| 決済の証明は残高範囲のビット分解である | 本番の範囲証明はすべて Bulletproof である。ビット分解は計測済みの比較基準と、閾値形に残る | DEFMI.md §2 対 ledger.rs、notes.rs、netting.rs |
| 新しさを合わせたおとりが ring の隙間を閉じる | 実装と計測は済んでいるが、呼ぶのはベンチマークだけである。本番経路は、DEFMI.md §9 が述べるとおり一様なおとりを使う | notes.rs、benches/rings.rs |
| 照合の証明は、commit された残高の和が登録簿の数字に一致することを示す | 検証器は残差の一般の開封証明を検査しており、偽造した合計が受け入れられた。同日に修正した。上の所見を見よ | reconcile.rs、bitrange.rs、threshold_range.rs、quote_proof.rs、rule_audit.rs |
技術スライドから実装へ
37項目の暗号技術カタログで用途・数式・証明者・制約を確認し、予約から決済・回収までで状態遷移をたどれます。暫定結果とchallengeは、両デモの検証方式とnative決済の境界を説明します。