LoginSignup
4
0

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-12-08

前回のNIS1(今のNEM)版。

さくっと行きます。

署名されるデータ

NIS1は前回のcatapultとルールが少し違い、データの前にデータ長が付くようになっています。例えば、32byte の公開鍵の前に 0x20000000 がプレフィックスとして付きます。

また、それがプログラム上で オブジェクト と呼ばれるものであれば、オブジェクトデータ長 + データ長 + データ のようになる(別のフィールドが間に入ることもある)ので若干ややこしいところがあります。

この辺りのルールは昔、トランザクションのパターンですが別の場所に書いてあるのでそちらを見てみてください。

今回署名されるNIS1のブロックはこちら。

20181208-draw1.png

ブロック内に一つだけTransferTransactionが入ったブロックです。

NIS1の面白いところが、ブロックに入るトランザクションの全データをそのまま署名にかけるところだ。

catapultもそうだが、ブロックに格納されるトランザクションの証明は、それらを集約したハッシュ値を使うことが多い。しかし、NIS1では直接トランザクションに署名をかけにいく。

「SPVなんか許さねぇよ?」という強い意志を感じます。(恐らく違う)

電子署名は何を使うのか

電子署名はcatapultと同じく、 ed25519 です。但し、前回も書きましたが、内部で使用されるハッシュ関数が Keccak_512 であるという点でcatapultと異なります。(catapultでは SHA3_512

署名検証してみる

require "ed25519_keccak"

class Deterministic_Transfer_Transaction
  def initialize
    @tx_data_size = "BC000000";
    @entity_type = "01010000"
    @version = "02000098"
    @timestamp = "6E000200"
    @pubkey_of_signer_size = "20000000"
    @pubkey_of_signer = "F9BD190DD0C364261F5C8A74870CC7F7374E631352293C62ECC437657E5DE2CD"
    @signature_size = "40000000"
    @signature = "AC00BFBA8CF3B236567398DE63C3339BEE9975E94B000835445A0A19825DA262B9CDE6D6370D950F4C2DC278F304DF2EA8947852CC17B6B5791EF2D99AB62D06"
    @fee = "4054890000000000"
    @deadline = "7E0E0200"
    @recipient_address_size = "28000000"
    @recipient_address = "4E414E454D4F41424C4147523732415A3252563356345A48444358573235585137334F374F425435"
    @amount = "40420F0000000000"
    @message_data_size = "00000000"
    @mosaic_count = "00000000"
  end

  def get_data_buffer
    data_buffer = @tx_data_size \
                + @entity_type \
                + @version \
                + @timestamp \
                + @pubkey_of_signer_size \
                + @pubkey_of_signer \
                + @signature_size \
                + @signature \
                + @fee \
                + @deadline \
                + @recipient_address_size \
                + @recipient_address \
                + @amount \
                + @message_data_size \
                + @mosaic_count
    return data_buffer
  end
end

class Deterministic_block_nis1
  attr_reader :signature,:pubkey_of_signer

  def initialize()
    @entity_type = "01000000"
    @version = "01000098"
    @timestamp = "96000200"
    @pubkey_of_signer_size = "20000000"
    @pubkey_of_signer = "F6F8E0F08CCE7401D59FF4C20114899104C2FE5E8D471BCB41A7536CEB7ADA8D"
    @prev_block_hash_datasize = "24000000"
    @prev_block_hash_size     = "20000000"
    @prev_block_hash = "659BD1647228D19276673EF1676C21F91455BE0799E0716CA0B7058367498946"
    @height = "A701000000000000"
    @tx_count = "01000000"

    @signature = "61FDA17A1B612CE61F43858C881B7BE3377C26DFCE64DB66CA25D2023807344294AFC451ABCEFFDA96823C07CD3708331BA7621DFC92684D5676863D5EEB2706"
  end

  def get_data_buffer()
    tx = Deterministic_Transfer_Transaction.new

    data_buffer = @entity_type \
                + @version \
                + @timestamp \
                + @pubkey_of_signer_size \
                + @pubkey_of_signer \
                + @prev_block_hash_datasize \
                + @prev_block_hash_size \
                + @prev_block_hash \
                + @height \
                + @tx_count

      data_buffer = data_buffer + tx.get_data_buffer
    return data_buffer
  end
end

nis1_block = Deterministic_block_nis1.new

signature = nis1_block.signature
message = nis1_block.get_data_buffer
pubkey_of_signer = nis1_block.pubkey_of_signer

ed25519 = Ed25519Keccak::Keccak512.new

is_verify = ed25519.verify( pubkey_of_signer , message , signature, :hex )

puts( "is verify ? : " + is_verify.to_s )

実行すれば、true の結果を確認することができるはずです。

さいごに

Don't trust verify!!!!!!!!

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0