考察(その3)です。CTransactionSignatureSerializerの構造をみていきます。

bitcoin-SignatureHash

本日は、このCTransactionSignatureSerializerの構造を解読していきましょう。

ビットコインを解読する際は、Serializeというメソッドが重要です。ここから解読していくのです。

template<typename S>
void Serialize(S &s) const

この部分ですね。Sはストリームのメソッドが実装されたクラスが渡されます。ビットコインにおけるストリームのメソッドが実装されたクラスで有名なものは「CDataStream」と「CHashWriter」です。このようなストリームを持つクラスのインスタンスに、このCTransactionSignatureSerializerのインスタンスをストリーム演算子(<<と>>ですね)で渡すと、このSerializeとUnserializeが呼ばれる仕組みになっています。

このCTransactionSignatureSerializerはECDSAの「秘密鍵」に渡すハッシュを生成しますので、ハッシュを生成するストリームである「CHashWriter」に、このインスタンスを渡して、CHashWriterからハッシュを得て、そのハッシュをECDSAの「メッセージハッシュ」として署名する。そんな流れになっています。

つまり、ECDSAの署名の内容はCTransactionSignatureSerializerの一存で決まる仕組み(1または3から始まるアドレス)です。なぜなら、ECDSAの署名(なお、他の公開鍵暗号方式も同じ仕組み)は「秘密鍵」と「メッセージハッシュ」で決まるからです。秘密鍵も重要ですが、それと同じ位、この「メッセージハッシュ」も大切な要素です。この内容で公開鍵による検証の有効無効が定まるからです。

そこでSerializeの内容をみていきます。トランザクションの内容をくまなく辿って、各メンバまたは各Serializeを呼び出していますね。このトランザクションを構成するクラス(CTxInやCTxOut)などにもSerializeが実装されており、連鎖的に呼び出せるようになっています。

これで、CTransactionの各メンバ、CTxIn、CTxOutの内容次第でCTransactionSignatureSerializerが出力するシリアライズの内容が変化することがわかりました。ここで、CHashWriterとは何か。これは、そのシリアライズされたバイナリをハッシュターゲットにします。よって、CTransactionSignatureSerializerが出力するシリアライズの内容でトランザクションを作成するための署名用メッセージハッシュが定まる仕組みになっているのがわかりました。

それで、このCTransactionSignatureSerializerとCTransactionを何度も読み返すと、非常に低い発生確率ですが起こりえる確率で一つ抜け穴があります。

ああ、本考察はできる限り簡素に書こうと考えていたのが、本日は気合を入れました(^^;。休憩です。

タイトルとURLをコピーしました