2021年8月18日 4 min read

秘密鍵はどのように生成されているのか?

こんにちは。AndGoのハードウェア担当の片山です。

突然ですが,日本の小学校の教室には写真のようなロッカーがあります。実は皆さんの暗号資産はこのようなロッカーの中に入っているのと同じです。鍵がかけられていないので,資産が入っている場所さえわかれば簡単に盗み出すことができてしまいます。

え!?っと思った方も多いでしょうが,小学校のロッカーとの違いはロッカーの個数です。小学校のロッカーは30個程度しかないので,全数探索することができてしまいます。一方でビットコインの場合はロッカーの個数が2の256乗個あります。10進数で77桁の数字となります。もし世界の全人類が貴方のビットコインが入っているロッカーを探そうとした場合に,全員が1ナノ秒に1回調べても宇宙の年齢の10000000000000000000000000000000000000000倍かかりますので,探すことは不可能です。このロッカー一つ一つに割り当てられているのが秘密鍵であり,ビットコインアドレスは秘密鍵から生成されています。

もし秘密鍵が完全に無作為に作られていれば,貴方のビットコインを盗み出すことは事実上不可能ですが,もし秘密鍵に規則性があったらどうでしょうか?

秘密鍵は256bitの情報ですので,硬貨を256回投げて表なら1,裏なら0のように決めていくこともできます(実際にそのように決めることも可能でしょう!)。もしここで,表が出る確率が高かったらどうでしょうか。極端な話ですが,ほとんど256回に1回しか裏がでない硬貨を使っていたとしたら,秘密鍵はほとんど1になりますので,秘密鍵の特定は非常に簡単になります。

皆さんの秘密鍵はどのように生成されているのでしょうか?

プログラミングをされたことがある方なら乱数を使ったことがあると思います。乱数は無作為な数値のことです。C言語の場合は,下記のようなプログラムで乱数を生成することができます。ただし,このプログラムでは実行する度に毎回同じ乱数が表示されてしまいます。

#include <stdio.h>
#include <stdlib.h>
int main(void) {
for (int i = 0; i < 10; ++i) {
printf("%ld, ", random());
}
}
$ ./a.out
1804289383, 846930886, 1681692777, 1714636915, 1957747793, 424238335, 719885386, 1649760492, 596516649, 1189641421,
$ ./a.out
1804289383, 846930886, 1681692777, 1714636915, 1957747793, 424238335, 719885386, 1649760492, 596516649, 1189641421,
$ ./a.out
1804289383, 846930886, 1681692777, 1714636915, 1957747793, 424238335, 719885386, 1649760492, 596516649, 1189641421,

これは,ある計算式をつかって乱数を生成する,疑似乱数という仕組みを使っているからです。実際にはシードというパラメータを現在時刻等を使って決めているので,もう少しまともな乱数になります。それでも,秘密鍵をつくった時刻が分かってしまうと,秘密鍵をある程度推測出来てしまうことになります。

Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to ビットコイン研究所.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.