Crypto OS
Technical Crypto OS第1段階 · ブロックチェーン開発者のメンタルモデル

T2 · 暗号学の基礎

なぜ署名の文字列が「私だ」と証明できるのか?

この章を 3D で体験する →
練習する能力
BuilderProtocol Literacy
実践
ローカルで鍵ペアを作り、メッセージに署名して公開鍵で検証する。1 バイトだけ変え、検証が失敗することを確認する。
AI Lab
AI にマークル証明の検証関数を書かせ、自分で偽の証明を作って拒否されることを確認する。

現実の問題

DApp のログインにはパスワードがありません。

ウォレットを接続し、署名するとログインできます。バックエンドが受け取るのは、アドレスと 132 文字の十六進数だけです。それで所有者からの要求だと判断します。

従来なら登録、パスワードの要約、照合、セッションが必要ですが、ここではありません。初めての利用者でも、サーバーは秘密を保存しません。

しかも署名は公開されています。HTTP、アクセスログ、途中の通信、自分のコンソールへ現れる可能性があります。

見られても、なぜ他者はなりすませないのでしょうか。

誰でもコピーできる文字列が、なぜ本人を証明できるのでしょうか。

思考実験

知らない街で、初対面の人へ、このメモを自分が書いたと証明します。

共通の秘密はなく、自分の秘密を教えられず、メモは誰でも見てコピーできるという三条件です。

第一案:合言葉を末尾に書く。

見た相手は同じメモを作れます。検証者が偽造者にもなります。実装より構造の問題です。

第二案:合言葉から計算し、元へ戻せない文字列を書く。

逆算しなくても、そのまま別のメモへコピーできます。証明が内容に結び付いていないため、何度でも使えます。

第三案:合言葉と内容を合わせて計算する。

別のメモには合いませんが、検証するには合言葉が必要で、第一案に戻ります。

検証できることと、偽造できないことが両立しません。

普通の一方向の関数だけでは解決できません。別のものが必要です。

証明を作る数字と検査する数字の対で、検査用から生成用を導けないものです。

検査用を公開すると誰でも検証でき、生成用を渡さなければ誰も偽造できません。

132 文字は秘密ではなく、秘密で計算した一回の結果です。そのメッセージだけに有効なので、見ても別のものを作れません。

あなたが決める

要求がアドレス A の所有者から来たと、どう確認しますか。

結果を観察する

四案を同じ軸で比べます。

方法検証に秘密が必要か内容と結び付くか再使用できるか漏えいの結果
秘密を送る必要いいえ自由にできる全資産を失う
秘密の要約不要いいえ自由にできるなりすまし
秘密と内容の要約必要はいできない双方が偽造できる
公開検証可能な証明不要はい内容による対象メッセージだけ

最後の曖昧さは重要です。再使用の可否は暗号学より、メッセージに何を書くかで決まります。

署名自体は永続します。「ログイン」だけなら、いつでも別サイトや別チェーンで使えます。一回、一か所に限定するには、乱数、ドメイン、チェーン番号、期限を署名する内容へ含めます。

自分で設計する責務です。

モデルを作る

三つの基本要素と、一つの組合せです。

第一:一方向の要約。任意長を固定長へ変え、同じ入力は同じ結果、少しの変更は大きな変化となり、逆算は計算上困難です。

短い安定した名前、改ざん検知、大量のデータを一値にまとめる用途があります。

第二:鍵の対。秘密鍵は乱数、公開鍵は一方向の導出、アドレスはさらに要約です。

  1. 乱数 = 秘密鍵
  2. 楕円曲線の演算 → 公開鍵
  3. 要約と切出し → アドレス
すべて一方向です。秘密鍵を失っても、アドレスから戻せず、誰も回復できません。

第三:署名と検証。鍵と要約から、Ethereum では r、s、v の合計 65 バイトを作ります。検証はメッセージと署名から、署名者の公開鍵を復元してアドレスへ変えます。

公開鍵で復号するのではなく、署名から公開鍵を回復します。先に相手を知らなくても検証で分かるため、取引の送信アドレスも計算できます。

本人確認の全過程は次です。

  1. サーバーが乱数とドメインを含むメッセージを出す
  2. ウォレットが要約へ署名する
  3. 内容と署名を返す
  4. サーバーがアドレスを復元する
  5. 照合し、乱数を無効にする
最後を省くと、署名を何度でも再使用できます。

組合せ:大量のデータを一値にまとめ、個々の所属も証明する。

30 万アドレスの一覧をコントラクトへすべて書くと、費用が大きすぎます。

各データを要約して葉にし、隣の二つを結合して要約し、層を重ねて一つにします。チェーンには一値だけを置きます。

利用者は自分のデータと、葉から根までの兄弟値を渡します。30 万なら約 19 個です。経路を計算して根が一致すれば認めます。

全データを渡さず、一つが集合に属すると証明します。

ブロックの取引、エアドロップの一覧、ブリッジのメッセージでも同じ構造です。

何と呼ぶか

Hashハッシュ / 要約

任意長を固定長へ変える一方向の関数です。同じ入力なら同じ結果、ビットが変われば大きく変わり、逆算できません。

Ethereum は Keccak-256、Bitcoin は SHA-256 です。同じ関数ではなく、混同するとアドレスも一致しません。

Private Key秘密鍵

作り上げるより、無作為に選ぶ数字です。乱数の質が安全を決めます。

本人証明と資産支配を兼ね、従来のパスワードのように再設定できず、紛失は永続します。

Public Key公開鍵

秘密鍵から一方向に導いた値で、公開できます。さらに要約して切り出すとアドレスです。

公開鍵やアドレスの公開は安全です。危険なのは秘密鍵と、それを導ける署名時の乱数などです。

ECDSA楕円曲線デジタル署名アルゴリズム

Ethereum と Bitcoin で使い、曲線は secp256k1 です。Solana の Ed25519 は別方式で、長さと形式も異なります。

一回限りの乱数を使います。一度でも再使用すると、秘密鍵を解けます。実例で事故を扱います。

Signature署名

一つのメッセージの証明です。Ethereum では r と s が各 32 バイト、回復識別子 v が 1 バイトです。

内容が変わらず、署名時に鍵を持っていたことを証明します。意味の理解は証明できません。

Merkle Treeマークル木

集合を二つずつ要約して根へまとめます。データと葉から根への経路だけで、集合全体なしに所属を検証できます。

経路長は対数で、百万件でも約二十ハッシュです。この対数性が価値の理由です。

実践

実践ローカルで鍵を作り、署名、検証、一バイトの変更を試すopenssl(macOS と Linux に付属)0

チェーン、テストネット、実資産は使いません。生成鍵は実験専用で、終了後に削除します。

secp256k1 の秘密鍵と公開鍵を生成します。

openssl ecparam -name secp256k1 -genkey -noout -out priv.pem
openssl ec -in priv.pem -pubout -out pub.pem
cat priv.pem pub.pem

priv.pem から pub.pem を再生成できますが、逆はできません。pub.pem を削除して再生成し、一致を確認します。

メッセージを用意し、署名します。

printf 'transfer 100 to alice' > msg.txt
openssl dgst -sha256 -sign priv.pem -out sig.bin msg.txt
xxd sig.bin | head

sig.bin の長さを見ます。内容ではなく要約へ署名するため、メッセージ長と無関係です。

公開鍵で検証します。

openssl dgst -sha256 -verify pub.pem -signature sig.bin msg.txt

Verified OK が出ます。pub.pem だけを使い、秘密鍵は参加しません。

一バイトを変えて再検証します。

printf 'transfer 100 to blice' > tampered.txt
openssl dgst -sha256 -verify pub.pem -signature sig.bin tampered.txt

一文字でも要約が変わり、失敗します。

署名ファイルの一バイトを変えても失敗します。おおむね正しい状態はなく、通るか通らないかだけです。

実際のチェーンの署名を見ます。

ウォレットのメッセージ署名で、自分の短い文章を署名してコピーします。

0x と 130 文字で 65 バイトです。最初の 64 文字が r、次の 64 が s、最後の 2 が v です。

openssl と曲線は同じでも、Ethereum は Keccak-256、固定 65 バイト、要約前の接頭辞を使います。DER ではありません。数学は同じでも、符号化と前処理が違います。言語間の実装で注意します。

署名内容を読みます。

実際の DApp のログイン署名で、ドメイン、乱数、期限、チェーン番号を全文から確認します。

欠けた軸では再使用できます。

AI Lab

AI LabAI に Merkle 検証を書かせ、偽の証明で試すLevel 2 · AI Copilot

二段階で、第二が中心です。

第一段階:
指定した言語で Merkle 証明の検証関数を書いてください。
入力は leaf、proof 配列、root、出力は true または false です。
ハッシュ、結合順、葉と内部ノードの区別の仮定を説明してください。

第二段階:
今度は攻撃者になり、この実装で、
木にないデータに true を返す入力を作ってください。
不可能なら、防ぐコードの行を示してください。

第二原像攻撃という典型的な欠陥があります。葉と内部ノードを同じ方法で要約すると、内部ノードを葉として短い経路と渡せます。異なる接頭辞や長さで防ぎます。

モデルは欠陥のある版を書き、攻撃は不可能と言うかもしれません。その場合、説明を渡して書き直させます。

訓練するのは実装より、何を問うべきかを知ることです。

例の契約アドレスや根を勝手に作っていたら、チェーンで確認してください。存在しないことが多いものです。

AI の回答後、自分で必ず検証すること

  • 対象チェーンのハッシュを使い、SHA-256 と Keccak-256 を混同していない
  • 二子の結合順が明記されている
  • 葉と内部ノードを区別し、内部ノードを葉として渡せない
  • ライブラリーと関数が公式文書に実在する
  • 十六進数とバイト配列を正しく変換し、0x を数えすぎない
  • 検証成功をデータの正当性と取り違えず、根の信頼性を区別する

実例

乱数の再使用で秘密鍵が解かれる2010 年と 2013 年

同じ鍵と乱数で異なる二メッセージを署名すると、署名から初歩的な代数で鍵を解けます。

2010 年、ゲーム機のコード署名が乱数を定数にし、鍵が計算されて体系が失効しました。2013 年、モバイル OS の乱数の欠陥でウォレットが同じ乱数を使い、資金を失いました。

破られたのはアルゴリズムではなく実装です。乱数は自分で書くべきでない部分です。

ブラインド署名のフィッシング

偽サイトの理解できない十六進数へ、利用者が署名しました。

実際は NFT をゼロ価格で売る注文でした。合法な署名で、同意はしたが、何に同意したかを知らなかったのです。

2022〜2023 年に大きな損失を生みました。構造化して各項目を表示し、ドメインとチェーンを結び付けます。T13 で扱います。

同じ署名を別チェーンで使う

初期の形式にはチェーン番号がなく、テストネットの取引をメインネットでそのまま使えました。

取引は後の規格で防ぎましたが、オフラインのメッセージはアプリの責務です。番号や期限のないログインでは、一年前の署名も使えます。

30 万アドレスのエアドロップを 32 バイトで記録する

全一覧は高価で、毎回の運営の署名なら常時オンラインが必要です。

根だけをチェーンへ置き、公開一覧から利用者が経路を持参すると、運営が停止しても受領できます。

アプリで最も一般的な Merkle の用途で、自分でも実装する機会があります。

変数を一つ変える

もしハッシュの衝突が見つかる

異なるデータが同じ要約なら、証明が二つを指し、コードの照合も置換できます。

一アプリより、要約をデータの代表にする体系が崩れます。チェーンが新しい関数へ慎重な理由です。

もし秘密鍵を乱数でなく、自分の文章にする

ブレインウォレットです。攻撃者は詩、歌詞、辞書を試せばよく、算法を破る必要がありません。

空にされる平均時間は秒単位です。安全は乱数のエントロピーにあります。

もしログイン署名に乱数と期限がない

永続的な通行証となり、ログ、エラー報告、通信記録が漏えい源になります。

チェーン上の承認を全部取り消しても、オフラインの署名には効きません。チェーンへ載っていないためです。

もしSolana に変える

曲線と算法が異なり、アドレスは公開鍵自体なので、直接取得できます。

署名者を明記する Solana と、署名から導く Ethereum の違いを、T6 のアカウントモデルで扱います。

持ち帰る問い

2
なぜブロックチェーンが必要なのか?

署名検証自体にブロックチェーンは不要です。SSH、HTTPS にもあります。チェーンで必要なのは、全員が同じ変更不能な規則で検証することで、会社のサーバーでなくプロトコルへ記します。

9
誰がリスクを負うか?

鍵の紛失は保有者がすべて負担し、救済はありません。マルチシグ、社会的回復、権限の階層化は、そのリスクを再分配します。

16
エージェントにはどんな権限があるか?

Agent へ秘密鍵を渡すと、全権限です。額、相手、期限のある署名承認で限定します。権限を先に考え、署名方法を後に決めます。逆なら一つの誘導で資金を失えます。

章末チェック

要点

秘密鍵は決して送らず、誰でも検証できる証明だけを送る。

この章の実践課題を終えたらチェックしてください進捗をすべて見る

このページの内容