Mastering Ethereum 4章 Cryptography
現在の段階では、Ethereum上のやり取りは全てみることができる。情報保護の観点から暗号化は重要な問題であり、
いくつかの解決策が走っている。
ゼロ知識証明
Homomorphic encryption
キーとアドレス
EOAとCAがあり、EOAはプライベートキー(以下PK)、アドレス、電子署名によって管理されている。
PKは絶対に公開しないでね!電子署名とアドレスだけおっけい!
トランザクションがブロックチェーンに格納されるには電子署名が必要で、電子署名はPKから生成される。
PKは銀行口座でいうPINであり、パブリックキーは口座番号。
Public Key Cryptography and Cryptocurrency
Etheruem内で鍵となっている暗号
マジック!
Elliptic curve mathematics means that anyone can verify that a transaction is valid, by checking that the digital signature matches the transaction details and the Ethereum address to which access is being requested. The verification doesn’t involve the private key at all; that remains private. However, the verification process determines beyond doubt that the transaction could have only come from someone with the private key that corresponds to the public key behind the Ethereum address. This is the "magic" of public key cryptography.
PKは電子署名を創り出すために使われ、トランザクションでは電子署名を転送するが受けてはPKでサインされていることが確認できる。
プライベートキー
プライベートキーの大きさは256bit。つまり、$ 2^{256}
$ 2^{256} ≒ 10^{80} ≒ 観測可能な宇宙にある原子総数
プライベートキーを生成するのはオフラインで行われる。
実際の表示形式としては、$ 2^{256}を16進法に直した64桁で表現される。
例:
f8f8a2f43c8376ccb0871305060d7b27b0554d2cc72bccf41b2705608452f315
パブリックキー
パブリックキーは楕円暗号曲線上の点。つまり楕円曲線上の(x,y)で表される。
パブリックキーの番号は2つの数字をくっつけたものであり、2つの数字はPKから作成される。
パブリックキーからプライベートキーを作成することはできないが逆は可能。
公開鍵は
$ K = k * G
で作成される。$ Kは公開鍵、$ kは秘密鍵。$ GはGenerator point
$ *はelliptic curve "multiplication" operator
$ Kから$ kを探すのは離散対数問題であり、現実的には解けない。
楕円暗号曲線について
楕円暗号曲線(Elliptic curve cryptography)は離散対数問題(ZK-SNARKs 離散対数問題)に基づいていて、パブリックキーは楕円曲線上の点と点の掛け算で生成される。 Ethereumではsecp256k1という楕円暗号曲線を利用しており、これはBitcoinと同じ。
https://gyazo.com/cdaaf254c1c6490acecd6ea33b31013d
secp256k1はUS National Institute of Standards and Technology (NIST)が作成した。
$ y 2 = \frac{ x 3 + 7 } { 𝔽 p }
$ y 2 \quad mod\quad p = ( x 3 + 7 ) \quad mod p
で表される、 𝔽 pってなんぞや?あーmodと同じ役割か!
https://gyazo.com/66e0b524e565de2b970c1d2d2e30619e
mod 17の場合、17でサイクルができるからx,y軸は17。
イメージ通り、mod pのpが大きくなればなるにつれて点が大きなる→セキュリティが硬くなる。
楕円号曲線状の実際の処理
楕円暗号曲線上のP1とP2を取り、
P1+P2=P3となるような点を取る。
楕円曲線上で2点(P1とP2)を取りその点と点を直線で結ぶと1点で曲線と交わる。まさかのその点がP1+P2になっている!!!
P1とP2のx軸が同じ場合、交わることはない。
要勉強!
公開鍵を生成する処理
プライベートキーからランダムに生成されたkを楕円曲線上の任意の点Gで掛け算をすることによってパブリックキーKを生成する。kとKの関係性は定義されているけどK→kは導けない。
K = f8f8a2f43c8376ccb0871305060d7b27b0554d2cc72bccf41b2705608452f315 * G
秘密鍵かからGを掛けて点Kを生成
K = (x, y)
点Kはx,yで表される。
x = 6e145ccef1033dea239875dd00dfb4fee6e3348b84985c92f103444683bae07b
y = 83b5c38e5e2b0c8529d7fa3f64d46daa1ece2d9ac14cab9477d042c84c32ccd0
https://gyazo.com/7f2c9283f36750a908c3aecf534ff49a
Ethereumでは0x04のuncompressed public keysのみ使用。
これ楕円暗号曲線と関係あって、x軸が同じ場合、多分0x00になる。2点が同じ場合、0x02か0x03になる
04 + x-coordinate (32 bytes/64 hex) + y-coordinate (32 bytes/64 hex)
なので生成される公開鍵はこんな感じになる。
046e145ccef1033dea239875dd00dfb4fee6e3348b84985c92f103444683bae07b83b5c38e5e2b0 \ c8529d7fa3f64d46daa1ece2d9ac14cab9477d042c84c32ccd0
楕円曲線のライブラリー
これがsecp256k1とかサポートしている。
Bitcoin Core’s libsecp256k1 is a C-language implementation of the secp256k1 elliptic curve
暗号学的ハッシュ関数
ハッシュ関数の定義
“any function that can be used to map data of arbitrary size to data of fixed size.”
ハッシュ関数の特徴
一意決定性
同じインプットからは同じアウトプットがでてくる
検証可能性
ハッシュ計算が速い
相関のなさ
インプットの小さな変更で大きな違いがアウトプットに生まれる
一方向性
アウトプットからインプットにできない
対衝突耐性
違うインプットから同じアウトプットが生まれない
ハッシュ関数が使われているところ
Data fingerprinting
Message integrity (error detection)
Proof of work
Authentication (password hashing and key stretching)
Pseudorandom number generators
Message commitment (commit–reveal mechanisms)
Unique identifiers
Keccak-256とは?
SHA-3のサブとして生まれた。
Federal Information Processing Standard (FIPS) 202のスタンダードの暗号になっている。
Ethereumが実装しているのはKeccak-256 。実装のタイミングでKeccak-256 を改善したFIPS-202 SHA-3が出たが、タイミング的にはこちらは採用されていない。
どのハッシュ関数を使っているかを見るにはハッシュ関数に何も入れずに確認するのがいい
Keccak256("") = c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
SHA3("") = a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a
Ethereumのアドレス
EthereumのアドレスはPublic KeyかコントラクトからKeccak-256を通して作成されたもの
Private Key
k = f8f8a2f43c8376ccb0871305060d7b27b0554d2cc72bccf41b2705608452f315
Public Key
K = 6e145ccef1033dea239875dd00dfb4fee6e3348b84985c92f103444683bae07b83b5c38e5e...
作成方法は上記で説明済み。Kの時点ではhex 0x00がついていない
Public Keyのハッシュを作成
Keccak256(K) = 2a5bc342ed616b5ba5732269001d3f1ef827552ae1114027bd3ecf1f086ba0f9
作成されたハッシュ値の最後の20桁を保存する
001d3f1ef827552ae1114027bd3ecf1f086ba0f9
前に0xを足す
0x001d3f1ef827552ae1114027bd3ecf1f086ba0f9