FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

SiFiveのFreedom E300 Platformを単体でカスタマイズできるようにする (1. 全体構造からブートROMへのリクエストまでの仕組み)

RISC-Vの実装であるRocket-Chipは、RISC-Vの最新使用に追従しているため最初に見るべきデザインとしてはよくできているが、

  • Chiselで記述されており(初心者には)可読性が低い。
  • 外部のSoCプラットフォームについて情報がない

ことから、なかなかオリジナルのSoCをくみ上げるためのデザインとしてポーティングしにくい。

とはいえ、TileLinkは単なるバスのはずだし、クロックとリセットさえ突っ込めばとりあえずフェッチリクエストが上がってくるはずだ。 そのあたりを解析して、Rocket-Chipを利用したオリジナルSoCプラットフォーム構築のための情報収集を行っていこう。

Freedom SoCはRocket-Coreを含むRISC-VのSoCプラットフォームだが、主にコアとなるTile部分と、外部のペリフェラル部分から構成されている。

f:id:msyksphinz:20180209234009p:plain

Freedom E300 システムのソースファイル全体像

Freedom E300システムは、Rocket-Chipと、外部のSoC部に分かれて構成されている。

freedom
src/main/
└── scala
    ├── everywhere
    │   └── e300artydevkit
    └── unleashed
        └── u500vc707devkit
rocket-chip/src/
└── main
    └── scala
        ├── amba
        │   ├── ahb
        │   ├── apb
        │   └── axi4
        ├── config
        ├── coreplex
        ├── devices
        │   ├── debug
        │   └── tilelink
        ├── diplomacy
        ├── groundtest
        ├── interrupts
        ├── jtag
        ├── regmapper
        ├── rocket
        ├── system
        ├── tile
        ├── tilelink
        ├── unittest
        └── util

Freedom E300 Platform のメモリマップ

Freedom E300 Platform は、以下のメモリマップを持っている。 このなかで、最初の0x0000_0000から0x0FFF_FFFFまでは、E3 Coreplex Manualを参照すること、と書いてある通り、こちらに掲載しているのはあくまでもSoCのメモリマップだ。 さらにSoC内部のCoreplex IPについては、E3 Coreplex Manualを参照する必要がある。

f:id:msyksphinz:20180209230017p:plain

f:id:msyksphinz:20180209230427p:plain

といっても、実際にはリセット後にBootROMに命令フェッチが入っており、そちらからジャンプする仕組みなっている。 BootROMには、以下のプログラムがコンパイルされて格納されている。

  .section .text.init
  .option norvc
  .globl _start
_start:
  csrr a0, mhartid
  la a1, dtb
  li t0, XIP_TARGET_ADDR
  jr t0

  .section .rodata
dtb:
  .incbin DEVICE_TREE

XIP_TARGET_ADDRは、以下のコンパイルコマンドで決定されている。

$(elf): xip.S $(dtb)
    $(CC) $(CFLAGS) -DXIP_TARGET_ADDR=0x20400000 -DDEVICE_TREE='"$(dtb)"' $(LFLAGS) -o $@ $<

TARGET_ADDRを見てわかるとおり、まずは0x2040_0000に配置されているQSPIへ命令をフェッチするようになっている。 つまりBootROMのターゲットアドレスを書き換えれば、所望の場所からプログラムをロードしてフェッチできそうな気がしている。

最初にブートするMaskROMは、System.scalaでmaskROMとして定義されている。

  • freedom/src/main/scala/everywhere/e300artydevkit/System.scala
class E300ArtyDevKitSystemModule[+L <: E300ArtyDevKitSystem](_outer: L)
  extends RocketCoreplexModule(_outer)
    with HasPeripheryDebugModuleImp
    with HasPeripheryUARTModuleImp
...
  • freedom/rocket-chip/src/main/scala/devices/tilelink/MaskROM.scala
trait HasPeripheryMaskROMSlave extends HasPeripheryBus {
  val maskROMParams = p(PeripheryMaskROMKey)
  val maskROMs = maskROMParams map { params =>
    val maskROM = LazyModule(new TLMaskROM(params))
    maskROM.node := pbus.toFixedWidthSingleBeatSlave(maskROM.beatBytes)
    maskROM
  }
}

RTLシミュレーション

一応E300 Freedom SoCのVerilogファイルだけ抜き出して適当にテストベンチをつなげ、ClockとResetをつなげてシミュレーションをしてみると、 とりあえずMaskROMへのフェッチが発生しているところまでは確認できる。

BootROMから、QSPIの領域(0x2040_0000)へジャンプしているため、そこからQSPIへのアクセスに移っているようだ。これをDRAMの領域に差し替えて、外部のRAMから命令をフェッチできるようにしてみよう。

f:id:msyksphinz:20180209235015p:plain

関連記事

「Mastering Bitcoin」を読む (第8章 マイニングとコンセンサス 2.)

「Mastering Bitcoin」を読んでいる。いよいよマイニングだ。 Bitcoinのマイニングは、どのような仕組みで、どのような計算をしているのかについて解説している。 最終的にマイニングしたブロックをブロックチェーンに接続し、それをどのようにしてビットコインネットワークに接続するためのコンセンサスを取るための仕組みだ。

ビットコインとブロックチェーン:暗号通貨を支える技術

ビットコインとブロックチェーン:暗号通貨を支える技術

関連記事

これは著者が読んだ内容をまとめているだけなので、誤訳、理解不足により誤っている可能性があります!鵜呑みにしないようにお願いします。 文章の途中に挿入している画像は、 https://www.bitcoinbook.info/translations/ja/book.pdf に含まれている画像を使用させていただいています。

第6章、第7章は一応読んだが、第8章のほうが面白そうなので先にまとめる。

第8章 マイニングとコンセンサス (2)

ブロックのチェーンの組み立てと洗濯

ブロックチェーンフォーク

  • ブロックのマイニングを全世界的同時並行的に行っている場合、複数のマイニングノードが異なるブロックの採掘に成功し、ビットコインネットワークに投げる可能性がある。

  • ある状態でビットコインネットワークに、メインチェーンのフォークが存在しない場合状態からスタートする。

f:id:msyksphinz:20180207235530p:plain
図. ブロックチェーンのフォークが生じる過程の可視化 - フォークが生じる前
  • ほぼ同時に異なったブロックを採掘した2つのマイナーが存在する。それぞれのマイナーが同時にビットコインネットワークにブロックをブロードキャストする。
    • 赤 : カナダで作ったブロック
    • 緑 : オーストラリアで作ったブロック
f:id:msyksphinz:20180207235739p:plain
図. ブロックチェーンのフォークが生じる過程の可視化 - 2つのブロックが同時に見つかった
  • それぞれのマイニングブロックはビットコインネットワーク中を進んでいき、各ノードは最新のdifficultyを持ったブロックをメインチェーンに設定する。
    • 最終的には、それぞれのメインチェーンがネットワーク上のある境界で衝突した状態になる。
f:id:msyksphinz:20180208000015p:plain
図. ブロックチェーンのフォークが生じる過程の可視化 - 2つのブロックが伝搬しBitcoinネットワークを2つに分割している
f:id:msyksphinz:20180208000303p:plain
図. ブロックチェーンのフォークが生じる過程の可視化 - 新しいブロックが1つのフォークを拡張
f:id:msyksphinz:20180208000447p:plain
図. ブロックチェーンのフォークが生じる過程の可視化 -Bitcoinネットワークが新しい最長ブロックチェーンに再収縮する

コンセンサス攻撃

  • 悪意のあるマイナーの攻撃。
    • 自分のウォレットで、ダブルスペンド(2重支払い)を発生させる攻撃。
  • 全世界のビットコインノードの、半分以上のマイニングパワーを持っていると、積み上げられたブロックチェーンの改ざんが可能になる。
    • 「51%攻撃」
      • トランザクションが承認される前。
      • いくつかのブロックをもとに戻せるような優位性を持っている。
  • 例 : 「悪意ある攻撃者マロリーがキャロルの画廊に行き、サトシ・ナカモトをプロメテウスとして書いた美しい絵画を購入する」

「Mastering Bitcoin」を読む (第8章 マイニングとコンセンサス)

「Mastering Bitcoin」を読んでいる。いよいよマイニングだ。 Bitcoinのマイニングは、どのような仕組みで、どのような計算をしているのかについて解説している。

ただし、このプロセスを踏むことによって、なぜマイナーが不正を行っていないことの証明になるのかが理解できない。 例えば、マイナーが既知のハッシュペアを組み合わせることによって不正なブロックを作ることもできそうだ。 これを防ぐ仕組みは、他のブロックが順方向にハッシュの計算をしても分からないのでは?

  • 例 : 悪意のあるトランザクションを含むブロックを構築する。
    • 自分で、そのブロックのハッシュを計算し、それをマイニング結果として放出する。
    • これが、他社により棄却できるのはなぜ?
      • そもそも、そのような悪意のあるトランザクションは作れない、ということなんだろうか... とすると、検証の意味がなくなってしまう...

もう少し読み進めていかなければ、理解できそうにない。

ビットコインとブロックチェーン:暗号通貨を支える技術

ビットコインとブロックチェーン:暗号通貨を支える技術

関連記事

これは著者が読んだ内容をまとめているだけなので、誤訳、理解不足により誤っている可能性があります!鵜呑みにしないようにお願いします。 文章の途中に挿入している画像は、 https://www.bitcoinbook.info/translations/ja/book.pdf に含まれている画像を使用させていただいています。

第6章、第7章は一応読んだが、第8章のほうが面白そうなので先にまとめる。

第8章 マイニングとコンセンサス

イントロダクション

  • マイニングにより、不正なトランザクションや、同じビットコインが二度使用される(ダブルスペンド)を防ぐことができる。
  • ビットコインのマイニングにより、2つの手段で報酬を得ることができる。
  • 新しいブロックを作ることにより得られる報酬は、採掘される総量に応じて減少している。
    • おおよそ4年に1度(正確には210,000ブロック)半減される。
    • この調子でいくとおおよそ2040年にはすべてのビットコインが彫りつくされ、マイナーは報酬を得ることができなくなる。
      • トランザクション手数料は残るため、こちらで稼ぐことになる。
      • 総額に応じて発行するビットコインの量を制限する仕組みは、デフレを防ぐ仕組みとなっている。
        • 紙幣のように、銀行が無限に発行することができないため、デフレを抑制する。

分散化コンセンサス

独立したトランザクション検証

マイニングノード

  • マイニングノードは特別な専用ビットコインノード
  • 通常のビットコインノードと同様に、新しいブロックを持っているが、別の新しいブロックが伝搬してくるということは、マイナー同士の競争が終了したことを示している。
    • この場合、新しいブロックを構成して再度マイニングをスタートさせる。

ブロックへのトランザクション集積

  • ブロックは、複数のトランザクションを集めて形成される。これを「候補ブロック」と呼ぶ。
  • 例えば、ジンが、ブロック277,314までのブロックチェーンを持っており、次の277,315のブロックをマイニングしているとする。
    • その間に、次のマイニングすべきブロックを組み立てる。
    • 277,315のマイニング中に、別のノードから277,315のブロックを受け取ると、競争が終わったことを示す。
      • すると、ブロック277,315に含まれている、マイニング済みのトランザクションを削除し、次の277,316のマイニングブロックの構成を作り始める。

トランザクション年齢、トランザクション手数料、トランザクション優先度

Generation トランザクション

ブロックのマイニング

  • SHA256関数を使って、ビットコインのマイニングを実行する。
  • 入力をランダムに修正しながら、偶然に欲しいハッシュが現れるまで試行を繰り返すことを、マイニングと呼ぶ。

Proof-of-Workアルゴリズム

  • SHA256アルゴリズムを用いる。再現性があり、同じ入力を与えれば、必ず同じっけ化を出力する。
  • 例 : テキストをSHA256によってハッシュ化するのだが、テキストの最後に "nonce" と呼ばれる数値を追加して、ハッシュ化した値の上位1桁の16進数が"0"となる "nonce" を算出せよ。
    • "nonce" を 0 から 15 までずらしていき、どの値によりハッシュ値が 0 になるかを確かめる。
    • 例 : "nonce=13" の場合ハッシュ値の上位1桁の値が "0" となれば、「マイニング完了」
    • この「ハッシュ化した値の上位1桁」が target difficulty となる。計算能力が上がれば、この target difficulty を再調整し、 10分に1度のマイニング競争が保たれるように調整される。
      • target difficulty は各ビットコインノードにより自動的に調整される。
      • また、急激な複雑性の変動がないように調整されている。
  • 本書が書かれている時点で、ビットコインネットワークは 000000000000004c296e6376db3a241271f43fd3f5de7ba18986e517a243baa7 よりも小さなハッシュヘッダを持つブロックを計算する必要がある。

うまく行ったブロックのマイニング

  • ジンはASICを使ってビットコインのマイニングを行っている。ブロック277,316のマイニングを始めて11分後に、ハードウェアが解を発見。
    • → 陣のマイニングノードはブロックをすべてのピアに送信する。
    • 次のマイニングを開始する。

新しいブロックの検証

  • マイニングに成功したブロックの検証を行う。
    • ブロックのデータ構造が有効である。
    • ブロックのヘッダハッシュが target difficulty よりも小さいこと。
    • etc ...
  • ビットコインノードによって独立した検証が実施され、マイナーが不正を行うことを防いでいる。

999ドルでマルチコア RISC-Vプロセッサが手に入る (HiFive Unleashed 発表)

SiFiveが提供するRISC-V IPコア、昨年8月のHotChipsで、SiFive初のRISC-VマルチコアIP UC54-MCが発表されてから約半年、やっとリリースが告知された。

SiFive のマルチコア RISC-V チップ & 評価ボード HiFive Unleashed が発表された!すばらしい!

www.sifive.com

こちらで予約ももう始まっているのかな?

www.crowdsupply.com

Early Access 版だと3月終わりには出荷が始まる。ただしお値段は少し高くて $1,250 + $40 for worldwide shipping 、それ以外の通常版は $999 + $40 for worldwide shipping ただし発送は6月終わりとなる。

チップの構成としては、

  • 4+1マルチコア構成。最大動作周波数1.5GHz (U54-MCのマニュアルはこちらから入手できる)
    • 64ビットRISC-Vコア (RV64GC) x4、 Sv39仮想メモリサポート
    • 64ビットRISC-Vコア (RV64IMAC) マネージメントコア
  • 2MB コヒーレント L2キャッシュ
  • ECC付き 64-bit DDR4
  • 1x ギガビット Ethernet
  • 28nm プロセスにて製造

ボード全体の構成としては、

  • SiFive U540 SoC (U540の正式な仕様書はまだ存在していない。 U500の仕様書はこちらから入手できる)
  • ECC付き 8GB DDR4-SDRAM
  • ギガビット Ethernet ポート
  • 32MB Quad SPI フラッシュメモリ
  • MicroSDカードストレージ
  • アドインカード接続用のFMCコネクタ

と、かなり凝った作りになっている。Linuxもサポートしており、本格的に施行することができそうなSoCだ。

早く手に入れて使ってみたい。「HiFive1」はお遊びボードだ、などの言ってしまったけれど、こちらは期待。

関連記事

「Mastering Bitcoin」を読む (第5章 トランザクション)

「Mastering Bitcoin」を読んでいる。今回はトランザクションについて。 Bitcoinのトランザクションはどのような仕組みになっているのかを解説している。

個人的には、スタックベースのスクリプト言語を使っているというのが非常に面白い。

ビットコインとブロックチェーン:暗号通貨を支える技術

ビットコインとブロックチェーン:暗号通貨を支える技術

関連記事

これは著者が読んだ内容をまとめているだけなので、誤訳、理解不足により誤っている可能性があります!鵜呑みにしないようにお願いします。 文章の途中に挿入している画像は、 https://www.bitcoinbook.info/translations/ja/book.pdf に含まれている画像を使用させていただいています。

第05章 トランザクション

イントロダクション

f:id:msyksphinz:20180210122752p:plain

トランザクションのライフサイクル

  1. 組成 (orgazition)
  2. トランザクションが生成されると、資金の所有者により署名される。
  3. ブロードキャスト
  4. 個々のノードで検証される
    • 無効ならば棄却
  5. このトランザクションは署名されているため、どのような通信手段を使っても構わない。
  6. 検証
  7. マイニングノード

トランザクションの構造

  • 所有者だけが持っている秘密鍵でロックする
  • Locktime : 先日付小切手のようなもの

トランザクションインプットとアウトプット

トランザクションアウトプットの構成

  • satoshi単位であらわされたビットコイン金額
  • locking script (解除条件が含まれている)
  • UTXOへのポインタ
  • locking script : UTXOのロックを解除するためのスクリプト
    • UTXOの中から、支払い可能なものを選択し、署名を含むunlocking scriptを生成する。

      トランザクション手数料

  • マイニングするために必要
  • 値段 : データサイズ・市場原理に基づいて生成される。
  • Input - Output で自動的に手数料が決まってしまう。
    • 例: Inputが20BTCで、1BTCの買い物をした場合、おつりで19BTCを生成しないと、それがそのままマイナーに渡ってしまう!
# get unspent outputs from blockchain API
import json
import requests
# example address
address = '1Dorian4RoXcnBv9hnQ4Y2C1an6NJ4UrjX'
# The API URL is https://blockchain.info/unspent?active=<address>
# It returns a JSON object with a list "unspent_outputs", containing UTXO, like this:
#{ "unspent_outputs":[
# {
# "tx_hash":"ebadfaa92f1fd29e2fe296eda702c48bd11ffd52313e986e99ddad9084062167",
# "tx_index":51919767,
# "tx_output_n": 1,
# "script":"76a9148c7e252f8d64b0b6e313985915110fcfefcf4a2d88ac",
# "value": 8000000,
# "value_hex": "7a1200",
# "confirmations":28691
# },
# ...
#]}
resp = requests.get('https://blockchain.info/unspent?active=%s' % address)
utxo_set = json.loads(resp.text)["unspent_outputs"]
for utxo in utxo_set:
    print("%s:%d - %ld Satoshis" % (utxo['tx_hash'], utxo['tx_output_n'], utxo['value']))
dbb3853afdb127cb7555bf44a033fa69b57335720132b8c016239ca80e4e570b:0 - 101010 Satoshis

トランザクションの連鎖とオーファントランザクション

トランザクションscriptとScript言語

  1. unlocking scriptを実行する
  2. unlocking scriptの実行結果をスタックに残したまま、locking scriptを実行する。 → TRUEならば、成功である。

Script言語

  • スタックベースの非常にシンプルな言語
  • スタックに入っている値と、次のlocking scriptをつなげて、検証を行う。
  • チューリング不完全であるという性質を持っており、処理時間が予測できる。
  • すてーつれすであり、実行前の状態を使わず、実行後の状態も使わない。

2 7 OP_ADD 3 OP_SUB 1 OP_ADD 7 OP_EQUAL
f:id:msyksphinz:20180204220546p:plain

標準的なトランザクション

5つの標準的なトランザクションが存在する。 - Pay-to-Publishing Hash (P2PKH) - Pay-to-Public-Key - マルチシグネチャ - データアウトプット - Pay-to-Script-Hash (P2SH)

P2PKH

  • Locking scriptが含まれる。
f:id:msyksphinz:20180204220600p:plain

Pay-to-Public-Key

  • 公開鍵そのものを、locknig scriptに配置する。
  • アドレスをより短くして使いやすくする。

マルチシグネチャ

  • N個の公開鍵 + M個の署名 ( $M \le N$ )
  • セキュリティを高めることが目的。
  • (コインチェックの問題で話題になった)
  • 2-of-3マルチシグネチャの場合
  • 例1. : ボブとボブの奥さんのトランザクション
  • 例2. : ゴペッシュのビジネス
    • ビジネス用に2-of-3マルチシグネチャアドレスを持っている。
    • 少なくともビジネスパートナーの2人がトランザクションに署名をしなければ、このアドレスに紐づく資金を使うことができない。
  • N個の公開鍵とM個の署名で構成される場合
    • トランザクションアウトプットに含まれるlocking scriptには、N個の公開鍵を含むlocking scriptが含まれている。
    • トランザクションインプットに含まれるunlocking scriptには、N個の公開鍵に対応したM個の秘密鍵から作られた署名が含まれている。
    • M個の有効な署名を持っていることが、有効なunlocking scriptの条件となる。
f:id:msyksphinz:20180210122809p:plain

データアウトプット

  • トランザクションの日付を利用して、ファイルの存在証明を行う。
  • これらの無関係なトランザクションのために、データが肥大化してしまう。
  • OP_RETURNは、UTXOセットに保持される必要のない "明示的使用不可アウトプット" を作り出す。
    • 使用するための、 unlocking script は存在しない。

Pay-to-Script-Hash (P2SH)

2 <Mohammed's Public Key> <Partner1 Public Key> <Partner2 Public Key> <Partner3 Public Key> <Attorney Public Key> 5 OP_CHECKMULTISIG
2
04C16B8698A9ABF84250A7C3EA7EEDEF9897D1C8C6ADF47F06CF73370D74DCCA01CDCA79DCC5C395D7EEC6984D83F1F50C900A24DD47F569FD4193AF5DE762C58704A2192968D8655D6A935BEAF2CA23E3FB87A3495E7AF308EDF08DAC3C1FCBFC2C75B4B0F4D0B1B70CD2423657738C0C2B1D5CE65C97D78D0E34224858008E8B49047E63248B75DB7379BE9CDA8CE5751D16485F431E46117B9D0C1837C9D5737812F393DA7D4420D7E1A9162F0279CFC10F1E8E8F3020DECDBC3C0DD389D99779650421D65CBD7149B255382ED7F78E946580657EE6FDA162A187543A9D85BAAA93A4AB3A8F044DADA618D087227440645ABE8A35DA8C5B73997AD343BE5C2AFD94A5043752580AFA1ECED3C68D446BCAB69AC0BA7DF50D56231BE0AABF1FDEEC78A6A45E394BA29A1EDF518C022DD618DA774D207D137AAB59E0B000EB7ED238F4D800 5 OP_CHECKMULTISIG

→ これを20バイトの暗号化ハッシュで表現する。

Pay-to-Script-hash の利点

  • トランザクションの削減
  • 実装の簡素化
  • scriptを校正する負担を、送りてから受け手に移す。
    • データストレージの負担を最小化する。
    • 負担が生じる時刻を移す。
    • 手数料の負担削減

redeem script と isStandard 検証

  • redeem script は P2SHアウトプットを使用しようとするまで、ビットコインネットワークには使用されない。

「Mastering Bitcoin」を読む (第4章 鍵、アドレス、ウォレット)

ビットコインとブロックチェーン:暗号通貨を支える技術

ビットコインとブロックチェーン:暗号通貨を支える技術

関連記事

これは著者が読んだ内容をまとめているだけなので、誤訳、理解不足により誤っている可能性があります!鵜呑みにしないようにお願いします。 文章の途中に挿入している画像は、 https://www.bitcoinbook.info/translations/ja/book.pdf に含まれている画像を使用させていただいています。

第03章 ビットコインクライアント

クライアントの使い方がメインなので省略。

第04章 鍵、アドレス、ウォレット

イントロダクション

ビットコインの所有権の基礎 : 「デジタル鍵」「ビットコインアドレス」「デジタル署名」

公開鍵暗号と暗号通貨

公開鍵、秘密鍵ビットコインアドレスの関係性

  • 秘密鍵はランダムに生成される値である。このアドレスをもとに公開鍵とビットコインアドレスが生成される。
  • 秘密鍵は所有権そのものを意味する。秘密鍵の値が漏れてしまうと、所有権が移されてしまうのと同義である。
    • また、秘密鍵を紛失しても、その秘密鍵に結びついている個人の資産に永久にアクセスできなくなってしまうことを意味する。

秘密鍵の生成

正確には、秘密鍵は1から n-1 までの任意の整数である。 n楕円曲線の異数であり、 2^{256} よりもわずかに小さな値である。

公開鍵

楕円曲線上のスカラー倍算を使って秘密鍵から生成する。これは不可逆の計算である。  K=k * G k秘密鍵 G は生成元と呼ばれる定点、 K は公開鍵となっている。

この公開鍵は一方向でのみ導出することができ、公開鍵から秘密鍵を導出することができない。 また、公開鍵から生成されるビットコインアドレスからも、秘密鍵が計算することができないため、ビットコインアドレスは誰と共有しても問題とならない。

楕円曲線暗号

ビットコイン楕円曲線暗号は、米国国立標準技術研究所(NIST)のsecp256k1という標準で定義された楕円曲線と定数を使っている。

$$y^{2} = \left(x^{3}+7\right) \text{over} (F_p)$$

または、

$$y^{2} \mod p = (x^{3}+7) \mod p$$

として定義される。ここで p 2^{256}-2^{32}-2^{9}-2^{8}-2^{7}-2^{6}-2^{4}-1 として定義される非常に大きな素数である。

例えば、以下のP楕円曲線上の点である。Pythonを使って確かめる。

P = (55066263022277343669578718895168534326250603453777594175500187360389116729240,
32670510020758816978083085130507043184471273380659243275938904335757337482424)
>>> P = [55066263022277343669578718895168534326250603453777594175500187360389116729240, 32670510020758816978083085130507043184471273380659243275938904335757337482424]
>>> p = 2**256-2**32-2**9-2**8-2**7-2**6-2**4-1
>>> (P[0]**3+7 - P[1]**2)%p
0

※ 注記 : 楕円曲線暗号での計算の方法は、以下のサイトが分かりやすかった。

https://btcnews.jp/elliptc-curve-diy/

ビットコインアドレス

ビットコインアドレスとは、資金の受取人としてトランザクションに登場する。 数字と文字で構成された文字列。

  • ビットコインアドレスは、一方向のハッシュ化アルゴリズムを使って生成される。
    • 公開鍵からビットコインアドレスを生成するためには、SHA(Secure Hash Algorithm)とRIPEMD(RACE Integrity Primitives Evaluation Message Digest)が使われる。
    • その中で、SHA256とRIPEMD160が使用される。
    •  A= \text{RIPEMD160}(\text{SHA256}(K)) ただし、Kは公開鍵で、Aビットコインアドレス

さらに、ビットコインアドレスはBase58Checkと呼ばれる形にエンコードされる。 これは、可読性を上げ、転写時のエラーを防ぐ目的がある。

Base58 と Base58Checkエンコード

Base64エンコードは、もともとE-mailなどでバイナリを送信するために利用されているエンコードだが、Base58はよりコンパクトで、可読性、エラー防止などの機能をバランスよく提供している。 - 0(ゼロ)、O(大文字のオー)、l(小文字のエル)、I(大文字のアイ)、記号「+」や「/」を除去したものである。

さらに、書き間違いや転写間違いを防ぐために、Base58にチェックサムが組み込まれている。これがBase58Check。

checksum = SHA256(SHA256(prefix+data))

生成される32バイトのハッシュ値から最初の4バイトだけを取り出す。

鍵フォーマット

人々が鍵を間違えずに容易に読み転写できるようになることを第一の目的として用いられている。

秘密鍵フォーマット

秘密鍵を表現するために使われる3つの形式として、「16進数」「WIF」「圧縮WIF」が用いられる。

公開鍵フォーマット

公開鍵は楕円曲線上の点であり、 (x, y) の形式で表現されている。さらに、プレフィックス04が付加されている。

以下の秘密鍵から生成した公開鍵は、プレフィックス04が付加されて以下のように公開鍵となる。

x = F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF579DC341A
y = 07CF33DA18BD734C600B96A72BBC4749D5141C90EC8AC328AE52DDFE2E505BDB
K = 04F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF579DC341A07CF33DA18BD734C600B96A72BBC4749D5141C90EC8AC328AE52DDFE2E505BDB

圧縮された公開鍵

公開鍵のサイズを圧縮するために、 (x, y) のうち x のみを保持するという方法がある。 これは、楕円曲線の上に載っている場合、 x が分かれば y も計算可能であるという原理に基づいている。 具体的には、 y^{2}\mod p = (x^{3}+7)\mod p を解くことで、 y を計算することができる。 これにより公開鍵のサイズを50%圧縮することができる。

しかし、 x から y を導こうとすると平方根の関係上正負の値が生成されてしまうため、 y 座標の符号は省略できず、保存する必要がある。 y 座標は偶数または奇数になり、これは正負に対応している。 したがって、y が偶数ならば02を、奇数ならば03を公開鍵の先頭に付与する。

以下が圧縮された公開鍵である。

K = 03F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF579DC341A

圧縮された公開鍵は一般的に使用されるようになっているが、圧縮された公開鍵に対応していないクライアントから転送されたトランザクションに対応するために、そのトランザクションを解釈する必要がある。

秘密鍵をウォレットからエクスポートする場合、これまでとは異なるWallet Import Formatを使用する。 圧縮された公開鍵が秘密鍵から作られていることを示しており、ビットコインアドレスが圧縮されているということをが示されている。

圧縮された秘密鍵

秘密鍵自体は圧縮されておらず、圧縮することができない。 このため、圧縮された秘密鍵というのは、実際には秘密鍵の最後に01を付加したものになっており、秘密鍵よりも1バイト長いものになっている。

圧縮された公開鍵を実装した新しいウォレットでは、秘密鍵はWIF圧縮形式(先頭がKまたはL)でエクスポートされるが、そうでなければWIF形式(先頭が5)でエクスポートされる。

鍵とビットコインアドレスのPythonでの実装

ウォレット

非決定性ウォレット

  • ランダムに生成された鍵を使用する。
  • この場合の欠点は、鍵がバックアップされておらずその鍵を紛失した場合には、すべての資産を紛失することになるというものである。
  • 非決定性ウォレットを使ってしまうと、トランザクションの度に別の鍵を作成し、そのすべてを管理しなければならなくなり、複雑になってしまう。
f:id:msyksphinz:20180203194231p:plain
Type-0非決定性(ランダム)ウォレット : ランダムに生成された鍵のコレクション

決定性ウォレット

  • 一つのシードから秘密鍵を生成し、同じシードから何度も別の秘密鍵を生成することができる。
  • このシードをバックアップしておけば、同じ秘密鍵を何度も再生成することができるという利点がある。

Mnemonic Code Words

  • 決定性ウォレットを生成する際にシードとして使った乱数を表現するための、英単語の列。

階層的決定性ウォレット (Hierarchical Deterministicウォレット : HDウォレット)

  • 親鍵が子鍵群を生成する。
  • ツリー構造であることにより、特定の機能ごと、口座ごとに「ブランチ」を割り当てることができる。
  • 秘密鍵にアクセスすることなく、ユーザが公開鍵を生成することができる。
f:id:msyksphinz:20180203194632p:plain
Type-2階層的決定性ウォレット : 1つのシードから生成された鍵ツリー

シードからHDウォレットの生成

  • HDウォレットは、ルートシードから生成する。
  • ルートシードをHMAC-SHA512アルゴリズムに入力される。
    • 出力 : マスター秘密鍵 (m)、マスターchain code
    • さらに、マスター秘密鍵からマスター公開鍵が生成される。
    • マスターchain codeは、親鍵から子鍵を生成するプロセスの中で、エントロピー(乱雑さ)を導入するために使われる。
f:id:msyksphinz:20180203194756p:plain
ルートシードからのマスターカギとマスターchain codeの生成

秘密鍵の導出

  • 子鍵導出関数は、以下を組み合わせた一方向ハッシュ関数となっている。
    • 秘密鍵または親公開鍵 (ECDSA非圧縮鍵)
    • chain code(256ビット)と呼ばれるシード
    • インデックス (32ビット)
  • インデックスを変えることで、いくつもの子鍵を作ることができる。
f:id:msyksphinz:20180203195158p:plain
秘密鍵を生成するための親秘密鍵拡張

導出された子鍵の使用

拡張鍵

  • 子鍵生成に必要な、本質的なインプットは、鍵とchain codeであるため、これを組み合わせて拡張鍵とする。
  • 拡張秘密鍵 : 秘密鍵とchain codeを組み合わせて、子秘密鍵を生成する。さらに、子秘密鍵から子公開鍵を生成する。
  • 拡張公開鍵 : 公開鍵とchain codeを組み合わせて、子公開鍵を生成する。
    • この、秘密鍵を使うことなく、親公開鍵から、子公開鍵を生成できるという特徴を持っている。

子公開鍵の導出

  • 秘密鍵を持たないサーバにおいても、拡張公開鍵を持っていればいくらでも公開鍵を生成することができる。
  • Eコマースなどで、サーバ内で公開鍵が生成できるようになる。
f:id:msyksphinz:20180203195254p:plain
子公開鍵を導出するための親公開鍵拡張

強化子公開鍵

  • 万が一子秘密鍵が漏洩してしまった場合、すべての子秘密鍵を漏洩できる危険性がある。
  • これを防ぐために「強化導出」というものを使っている。
    • 親公開鍵と子chain codeの関係を壊す。
    • 親公開鍵の代わりに、親秘密鍵を使って子chain codeを導出する。
f:id:msyksphinz:20180203195406p:plain
子鍵強化導出 : 親公開鍵の省略

高度な鍵とアドレス

暗号化秘密鍵

Pay-to-Script Hash(P2SH)とマルチシグネチャアドレス

  • 3から始まるビットコインアドレスはpay-to-script hash(P2SH)アドレス
    • トランザクションは、受取人を公開鍵の所有者の代わりにscriptおハッシュを使って指定する。
    • このアドレスに送った資金は、その所有権を示すために、1つの公開鍵ハッシュと1つの秘密鍵署名以上のものを提示することが必要になる。

Vanity Address

  • ビットコインアドレス内に、人間の読み取ることのできる文字列を挿入する。
    • これにより、慈善団体が寄付を募るためのコードに、任意の文字を入れることができる。
    • ただし、このようなVanity Addressを探し出すためには、一つずつ計算を行っていく必要があり、5~6文字以上は現実的ではない。

Vanity Addressのセキュリティ

  • このVanity Addressを悪意のある人間が誤用させるためには、Vanity Adressの文字列の部分を長さ+2くらいの長さの似たようなビットコインアドレスが必要になる。
    • 8文字のVanity Addressを含むアドレスを生成したらならば、悪意のある人間は+2の10文字を生成する必要がある。これは現実的ではない。
    • より長いVanity Addressを生成すると、悪意のある人間もそれに伴って多くの計算量が必要となる。

ペーパーウォレット

  • 秘密鍵を紙に印刷する。
    • コールドストレージとして機能する。
f:id:msyksphinz:20180203195807p:plain
bitaddress.org から持ってきたシンプルなペーパーウォレットの例

「Mastering Bitcoin」を読む (第1章 イントロダクション・第2章 ビットコインの仕組み)

世の中ではビットコインをはじめとする仮想通貨がブームとなっているが、正直その仕組みが分かっておらず、手を出すのが怖い。

まあクレジットカードの仕組みを知らないとクレジットカードが使えないというわけでもなく、世の中のインフラには乗っかっている私だが、ビットコインについては昨今の事件の話もあり、その仕組みをしっかりと勉強してみたい。

というわけで、本を1冊買って読んでみることにした。少し古い本で、Amazonのレビューによると情報も古いみたいなのだが、まずは基本的な部分を理解する必要があるので、それを学んで行きたい。少しずつ読みながら、まとめていくことにした。

ビットコインとブロックチェーン:暗号通貨を支える技術

ビットコインとブロックチェーン:暗号通貨を支える技術

関連記事

これは著者が読んだ内容をまとめているだけなので、誤訳、理解不足により誤っている可能性があります!鵜呑みにしないようにお願いします。 文章の途中に挿入している画像は、 https://www.bitcoinbook.info/translations/ja/book.pdf に含まれている画像を使用させていただいています。

第01章 イントロダクション

  • ビットコインとは、デジタルマネーのエコシステムの基礎となるコンセプト。
  • ビットコインは分散されたpeer-to-peerのシステムではなく、中央サーバを持たない。

  • ビットコインは、マイニングという処理を通じて取引の検証と記録を行う。

  • 平均して10分に1回の頻度で、過去10分の取引が検証され、その解の発見者にはビットコインが新たに与えられる。
    • これがマイニングに相当する。
    • この報酬は、トランザクションに含まれる手数料 (インプットとアウトプットの差分)から支払われる。

ビットコイン以前のデジタル通貨

デジタル通貨は、以下の2つの問題を解決する必要がある。 1. そのデジタルマネーは本物と信じて良いか?偽物ではないのか? 2. このデジタルマネーが、私ではなく他人のものと主張されることはないか?(二重支払問題)

一方で、ビットコインは以下の4つの鍵となるイノベーションを組み合わせる。 - 分散化されたpeer-to-peerネットワーク(ビットコインプロトコル) - 公開された取引元帳(ブロックチェーン) - 数学に基づきあらかじめ決定された、分散化された通貨発行(分散マイニング) - 分散化された取引検証システム (トランザクションscirot)

ビットコインの歴史

  • サトシ・ナカモトによる論文をベースにしている。
  • 2009年にビットコインネットワークがスタート。現在の分散コンピュータの規模は、すーぱコンピュータの処理能力の合計を超えている。
  • 「ピザンチン将軍問題」に対する現実的な解法を示している。
    • 信用できない潜在的に危ういネットワークにおいて、情報を交換することで、構成員全体の行動について合意できるか、というもの。

ビットコインを誰がどのように使うのか

  • 少額物品の販売 : ビットコインのソフトウェア・取引所・基本的な取引について説明する。
  • 高額物品の販売 : 「51%合意攻撃」
  • 海外請負サービス : ビットコインを用いたアウトソーシング、請負サービス、国際電信送金
  • 通貨や国境を超えたグローバルな資金調達 : 慈善団体への寄付の透明性の向上
  • BtoBビジネス : ビットコインを用いた国際的な資金決済
  • マイニング : ビットコインネットワークの堅牢性を高め、通貨発行を担っている専用システム

ビットコインをはじめよう

  • 多くのクライアントソフトウェアが存在する。主に3つのタイプ
    • フルクライアント : ビットコインが始まって以来のすべての履歴を保持している。
    • 軽量クライアント : ユーザのウォレット保持するものの、取引情報などは、第三者が管理するサーバを介して行う。
    • ウェブクライアント : ウェブブラウザを通じてアクセスするもの。ユーザのウォレットを第三者のサーバに保持している。

クイックスタート

  • いくつかの方法でクライアントソフトウェアをダウンロードして、自分の「ビットコインアドレス」生成する。
    • ビットコインアドレスは隠す必要がない。
    • 他者とビットコインアドレスを共有することで、ウォレットに直接お金を送金することができるようになる。

最初のビットコインを手に入れる

ビットコインを送る・受け取る

  • ビットコインウォレットが作成されていると、ビットコインを受け取る準備はできている。
  • ただし、この時点でアリスのビットコインアドレスはビットコインネットワークに伝えられていない。
    • ブロックチェーン(公開元帳)に登録されるまでは、有効なアドレス候補の一つに過ぎない。
    • 公開元帳に書き込まれると、ネットワークはアリスのビットコインアドレスを認識し、そのアドレスの資金と残高を参照できるようになる。

第02章 ビットコインの仕組み

トランザクション、ブロック、マイニング、ブロックチェーン

ビットコインの1つのトランザクションを負うことで詳細にビットコインの仕組みを調べる。

登場人物: ジョー、アリス、ボブ

ビットコイン概観

f:id:msyksphinz:20180203124534p:plain

コーヒー代金の支払い

アリスがボブのカフェでコーヒーの代金を支払う。支払いの総額は0.015BTCである。 これは1.5USDに相当する。

このトランザクションでは、アリスが支払いを確定させるためにsendボタンを押し、ボブがトランザクションの完了を確認する。

ビットコインは様々な額で取引を行うことができる。 最小単位は「satoshi」で、1/100,000,000 bitcoinのことを指す。

ビットコイントランザクション

  • トランザクションには、1つ以上の「インプット」「アウトプット」が記載されている。

f:id:msyksphinz:20180203124540p:plain

アリスがボブのカフェで支払いをするとき、

コーヒー代の支払いのトランザクションをボブのビットコインアドレスと紐づけることによって、このトランザクションのアウトプットを使用するためには、ボブの署名が必要になる。

ビットコイントランザクション

  • 1つのインプットと2つのアウトプットの形式 (一般的なトランザクション)

    • インプット0 : From アリス、アリスによる署名付き
    • アウトプット0 : To ボブ
    • アウトプット1 : To アリス (おつり)
  • 集約型トランザクション (小さなコインや小額紙幣をまとめて大きな額の紙幣にするトランザクション)

    • インプット 0 ... N
    • アウトプット0
  • 分配型トランザクション (企業内での給与の支払いなど)

    • インプット 0
    • アウトプット 0 ... N

トランザクションの構築

トランザクションを作ったり署名を行うのに、ビットコインネットワークに接続されている必要はない。 最終的にそのトランザクションが送られれば問題ない。

正しいインプットをどのように得るか

ほとんどのウォレットは、未使用トランザクションアウトプット(UTXO)を保持するデータベースを持っていて、ウォレットの秘密鍵でロックされている。

フルインデックスのウォレットを持っている場合は自分が十分な量のウォレットを持っているかどうかを確認できるが、そうでない場合は、ビットコインネットワークに問い合わせることができる。

アウトプットの生成

アリスの資金 0.1BTC からコーヒー代金 0.015BTC を支払うとおつりが発生する。アリスは0.85BTCのおつりをもらう。

さらに、トランザクションビットコインネットワークで早く処理されるために、アリスのウォレットは少額のトランザクション手数料を加える (0.0005BTC)。 この差額がトランザクションの手数料となり、ブロックチェーンに組み込むための手数料としてマイナーにより徴収される。

トランザクションを元帳にどうやって取り込むか

トランザクションビットコインネットワークに取り込まれてはじめて、ブロックチェーンの一部になる。

ビットコインネットワークへのトランザクションの送信

ビットコインクライアントは、いくつかほかのビットコインクライアントとつながることで、ビットコインネットワークに参加している。 トランザクションとブロックをすべてのビットコインクラインとに伝えることである。

どのようにビットコインネットワークを伝わっていくのか

アリスのウォレットはボブのウォレットと直接つながっている必要はなく、ビットコインネットワークを通じてPeer-to-Peerで転送されていき、数秒以内で大半のノードに到達する。

ボブの視点で見た時には

アリスからボブへのトランザクションが、ボブのウォレットに到達すると、ボブのウォレットはそれを認識する。 これは、このトランザクションがボブの秘密鍵でのみ復号できるアウトプットになっているからである。

この時点で、ボブは多少のリスクがあるものの、このトランザクションがすぐにブロックに含められ承認されるものとみなすことができる。

※ 少額の場合はブロックが生成されるまで10分も待つ必要はなく、コーヒー一杯のような少額の商品には必要がない。

ビットコインマイニング

  • マイニングにより検証されブロックに取り込まれるまでは、共有されている元帳であるブロックチェーンの一部になることはできない。
  • マイニングにより、トランザクションが「ブロック」の中に取り込まれる。

  • マイニングの目的

    • 新しいビットコインを発行するためにマイニングを行う。この量は時間で決められており、時間がたつと減少していく。
    • 信用を作り出す。トランザクションが承認され、より多くのブロックが存在したということは、多くの計算量を要したという意味で、信用度が高い。
  • マイニングとは数独パズルのようなものである。

    • 約10分間で解けるように難しさが自動的に調整される。
    • 数独パズルは、解くのは難しいが、検証は容易である。
  • マイナーは約10分ごとに開放を見つけるレースに参加している。
    • Proof of Work : 前もって決められたパターンに合う解法が現れるまで反復的に、ブロックのヘッダとランダム値をSHA256暗号化アルゴリズムでハッシュ化する。
    • 最初に解法を見つけたマイナーがそのブロックの勝者 → ブロックをブロックチェーンに組み込む。

ブロック内のトランザクションのマイニング

トランザクション