ブロックの署名検証(catapult)


はじめに

Don't trust veryfy!

とはよく言いますが、

そんなこと言われてもどうすりゃいいのさ...

ですよね。ほぼすべての人が自分で確認なんてしないと思います。
ですが、やりましょう。(署名検証だけだけど)

今回はcatapultでやります。

署名検証するブロック

今回署名検証してみるブロックは、下記の通り。署名されるフィールドも合わせて確認してください。

自分で作ったネットワーク上のデータなので、テストネットのデータなどとは全く関係の無いデータです。

言わずもがなですが、 署名が検証される = データが公開鍵に紐づく秘密鍵の持ち主が署名したことが確認できる という意味を持ちます。つまり、ブロックをリレーしているときに、署名されたデータ部分を誰かが改ざんするとバレるということですね。

電子署名は何を使っているか

catapultで使われる電子署名は ed25519 です。この ed25519 は内部でハッシュ関数をつかっているのですが、そのハッシュ関数がcatapultだと SHA3_512 になっています。 NIS1(現行のNEM)だと、 Keccak_512 を使っています。

ちなみに、NIS2に関しては、ここはNIS1のものに合わせられるそうです。あくまでcatapultでは SHA3_512 を使っているよということです。

ed25519のフローはこちら。

図の中に HashFunction があるのが分かると思います。これが違うと署名も変わりますし、検証できるものもできなくなります。

SHA3とKeccakの関係はこちら。
https://qiita.com/mincoshi/items/4b8fd450f13637e6a1f2

検証してみる

言語は何でも良かったのですが、今回はrubyで

require "ed25519_keccak"

class Deterministic_block_nis2
  attr_reader :size, :signature, :pubkey_of_signer, :version, :entity_type, :height, :timestamp, :diff, :prev_block_hash, :tx_hash , :private_key

  def initialize
    @size = "c0000000"
    @signature = "addb1df57ee20e94b43ba09b2789689be51dc80f3f3557cb7973d1fb7107ef32a7f5810d3a0c554d5d8a8dfab0e95e6ef1537ce1aafe62282d8a6186627c260d"
    @pubkey_of_signer = "f59240141852736bc2a23832833eb2114ce037b0066217e09207ddfea0e08478"
    @version = "0390"
    @entity_type = "4381"
    @height = "0200000000000000"
    @timestamp = "141e9dd512000000"
    @diff = "00407a10f35a0000"
    @prev_block_hash = "9050e352bb5bf321522a7067b78c87c3c3cd5c7c7fbc1c96fae82f6d73974452"
    @tx_hash = "0000000000000000000000000000000000000000000000000000000000000000"
  end

  def get_data_buffer
    data_buffer = @version + @entity_type + @height + @timestamp + @diff + @prev_block_hash + @tx_hash
    return data_buffer
  end
end

nis2_block = Deterministic_block_nis2.new

publickey = nis2_block.pubkey_of_signer
message   = nis2_block.get_data_buffer
signature = nis2_block.signature

ed25519 = Ed25519Keccak::SHA3_512.new

is_verify = ed25519.verify( publickey, message , signature, :hex )
puts( "is verify ? : " + is_verify.to_s )

実行すると、結果trueが表示されます。

ライブラリがなかった

rubyを使ったのに深い意味はありません。繰り返しになりますが...

catapultで使われる電子署名は ed25519 です。この ed25519 は内部でハッシュ関数をつかっているのですが、そのハッシュ関数がcatapultだと SHA3_512 になっています。 NIS1(現行のNEM)だと、 Keccak_512 を使っています。

ここで困ったことに、rubyのgemを探してもこれがありません。SHA2_512 ならすぐに見つかったのですが。

で、別の言語使おうかとも思ったのですが、どうせならといろいろ勉強がてら作ってみました。(実装自体は、 RFC8032 内にあるpythonのコードをrubyに書き換えたものです)

暗号って自分で触りたくないですよね。この辺がNEMの辛いところかも知れません。

参考