Bitcoinで使われる技術要素
ここでは、Bitcoinで使われている技術要素、Hash関連、Base58関連、ECDSA関連(秘密鍵、公開鍵)について簡単に説明したいと思います。
それぞれに、詳しく書いてあるリンクを貼っておきますので、詳しく知りたい方は、そちらを参照願います。
1.Hash
Bitcoinで主に使われているHashが、2つあります。
また、それらを組み合わせる事によって、HASH256、HASH160というHashを定義します。
SHA256
アメリカ国家安全保障局 (NSA)よって設計されたHash
いろいろな言語で実装されています。
ここでは以下のような式で表す事にします。
結果は、256ビットなので、32バイトとなります。
[hash] = SHA256([data])
詳しくは、WikipediaはRFCを参照ください。
RIPEMD160
オープンな学術コミュニティによって開発された為、特許などの問題がないそうです。
SHA1と同等のパフォーマンスを発揮するそうです。
ここでは以下のような式で表す事にします。
結果は、160ビットなので、20バイトとなります。
[hash] = RIPEMD160([data])
詳しくは、Wikipediaはspecificationを参照ください。
Bitcoinでは、これら2つを組み合わせたHashが良く使われます。(一部SHA256を利用する場合もあります。)
ここでは、組み合わせたHashをHASH256とHASH160と定義します。
HASH256
単純にSHA256を2回おこなったHash値となります。
ここでは以下のような式で表す事にします。
結果は、256ビットなので、32バイトとなります。
[hash] = SHA256(SHA256([data]))
私のBitcoin関連の投稿では以下のように表します。
[hash] = HASH256([data])
意味は、以下のとおりです。
HASH256([data]) = SHA256(SHA256([data]))
HASH160
最初にSHA256を行い、その結果をRIPEMD160したHash値となります。
ここでは以下のような式で表す事にします。
結果は、160ビットなので、20バイトとなります。
[hash] = RIPEMD160(SHA256([data]))
私のBitcoin関連の投稿では以下のように表します。
[hash] = HASH160([data])
意味は、以下のとおりです。
HASH160([data]) = RIPEMD160(SHA256([data]))
2.Base58
Base58
簡単に言うと、Base64の58文字版です。
Bitcoinで扱う文字列は、次のとおりです123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz
数値、大文字小文字アルファベットから、「0(零)」「「I(大文字のアイ)」「O(大文字のオー)」「l(小文字のエル)」の58文字となっています。
計算は非常に単純で、まず対象のバイナリを数値にします。
それを58で割り、余りを該当する文字に、その商を次に割る対象とします。
商が0になるまで続けます。
先頭が00の場合、1をその分だけ付与します。
例
0x0fffc34b = 268419915
268419915 / 58 = 4627929 ... 33(a)
4627929 / 58 = 79791 ... 51(t)
79791 / 58 = 1375 ... 41(i)
1375 / 58 = 23 ... 41(i)
23 / 58 = 0 ... 23(Q)
Qiita
0x000fffc34b = 268419915
268419915 / 58 = 4627929 ... 33(a)
4627929 / 58 = 79791 ... 51(t)
79791 / 58 = 1375 ... 41(i)
1375 / 58 = 23 ... 41(i)
23 / 58 = 0 ... 23(Q)
00分の1を付与
1Qiita
Base58Check
Base58にチェック機能を付与したものです。
簡単に説明すると、version+payload
をHASH256
した値の先頭4byte(checkcode
)を連結し、
それをBase58で表したものとなります。
このBase58Checkは、Bitcoinのアドレスとして使われます。
payload
は、HASH160
した値なので20byteとなります。
version
の値によって先頭の文字がある程度決まります。
version | header symbol | use |
---|---|---|
0x00 | 1 | Bitcoin pubkey hash |
0x05 | 3 | Bitcoin script hash |
0x6f | m / n | Bitcoin testnet pubkey hash |
0xc4 | 2 | Bitcoin testnet script hash |
例
version:0x6f
payload:0x4da5a6284aedba6eecb14585233041c5952de733
HASH256(version+payload)=0x0cd9d1235644cdd6974de3033ab9f3c27abc6d1a5273b061576bed9125e5915a
checkcode:0x0cd9d123
version+payload+checkcodeをBase58文字列に変換
mnbWmKgU3QvNHWNWjwfyoUHnPKDvc9hqsp
3.ECDSA
ECDSAとは、Bitcoin上で使われる電子署名である、楕円曲線DSAです。
y^2 = x^3 + ax + b
Bitcoinでは、secp256k1
というパラメータを使います。
このパラメータでは、a=0
、b=7
としている為、楕円曲線の関数は以下のようになります。
y^2 = x^3 + 7
この曲線状の点について、加算を定義します。
P_C(x_3,y_3) = P_A(x_1,y_1) + P_B(x_2,y_2)
また、2倍算を定義します
2P_A = P_A + P_A
これらを利用して、整数倍算を定義します。
Q = dP \\
dは整数 \\
この時、結合法則が成り立ちます。 \\
d = a + b \\
d,a,b はいずれも整数\\
P_A = aP \\
P_B = bP \\
Q = dP = aP + bP = P_A + P_B \\
ECDSAの公開鍵と秘密鍵は、secp256k1
で定義されている基点G
を何回(秘密鍵)足したときの点Q
(公開鍵)となります。
Q = dG \\
秘密鍵:d \\
公開鍵:Q \\
これらを、剰余環で扱います。
\begin{eqnarray*}
p &=& FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F \\
&=& 2^{256} - 2^{32} - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1
\end{eqnarray*}
実際のところ、私も内容は理解しておりません。(汗)
秘密鍵
基点G
をd
回足した時のd
が秘密鍵で、32byte
の大きな数値です。
公開鍵
秘密鍵の回数分、基点G
を足した、楕円曲線上の点Q
04
から始まる場合は、x座標(32byte
)、y座標(32byte
)の65byte
x座標さえあればy座標は計算できるので
02
又は03
から始まる場合は、x座標(32byte
)の33byte
の値となります。
02
、03
は、y座標が偶数か奇数かの違いです。