Published Date : 2021年7月1日17:34

005 Pythonでビットコインを学ぶ (ブロックチェーン デジタル署名)
005 Use python to learn bitcoin (Blockchain Digital signature)


This blog has an English translation


ニコニコ動画にアップした動画のまとめ記事です。

This is a summary blog post about a video I uploaded to NicoNico.

細かい部分は動画を参考にしてください。

Please refer to the video for details.


目次

Table of Contents




① 動画の説明
① Video Description



前回の続きです。

Continued from last time.

まずは中央集権型のクライアントサーバー通信システムです。

The first is a centralized client-server communication system.

そしてAとBが送金のやり取りを行う取引があるとします。

And suppose A and B make a transfer transaction.

中央集権型の場合は銀行等の中央機関がこの取引を管理します。

In the case of a centralized system, a central organization such as a bank manages this transaction.

次に分散型のネットワーク通信を考えてみましょう。

Now consider distributed network communications.

これはノードと言われる各デバイスが直接ネットワークを通じて通信するイメージです。

Consider that each device, called a node, is communicating directly over the network.

今度はAとBの取引を分散型ネットワーク上で管理することを考えてみましょう。

Now consider managing transactions between A and B on a distributed network.

AとBが取引を行ったら、その取引をネットワークに繋がれた全ノードに知らせます。

When A and B make a transaction, they inform all nodes connected to the network of the transaction.

各ノードはそれぞれ取引内容をコピーして、その内容を確かめ合います。

Each node copies the transaction and verifies its contents.

ここで勝手に第三者がAとBの取引を偽造しようとしました。

A third party tried to forge a transaction between A and B without permission.

これを防ぐにはデジタル署名を使います。

Use digital signatures to prevent this.

A本人が行った取引である証明をするのです。

In other words, it proves that the transaction was made by A himself.

丁度紙に本人がサインをするのと同じようにデジタルのサインを取引毎に行います。

Just like you sign a piece of paper, you digitally sign each transaction.

デジタル署名を作成するには前回紹介した公開鍵暗号を使います。

To create a digital signature, we use the public key cryptography I introduced in the video last time.

公開鍵暗号方式を使用して、公開鍵と秘密鍵を作成します。

Create public and private keys using public key cryptography.

秘密鍵はデジタル署名作成するのに使います。

The private key is used to create a digital signature.

一方、公開鍵はそのデジタル署名が正しいかどうかの検証を行うのに使います。

The public key, on the other hand, is used to verify that the digital signature is correct.

これらの署名と検証を各取引毎に行い、一つ前の取引のハッシュ値を現在の取引に記録します。

Each transaction is signed and verified, and the hash value of the previous transaction is recorded in the current transaction.

ではPythonを使ってデジタル署名と検証を体験してみましょう。

Now let's experiment with digital signatures and validations using Python.

Part1の時と同様に[cryptography.io]を使います。

Use [cryptography.io] as in the video for Part 1.

公開鍵暗号方式は楕円曲線暗号を使用します。

Public key cryptography uses elliptic curve cryptography.

ECDSA(Elliptic Curve Digital Signature Algorithm)と検索しましょう。

Search for ECDSA (Elliptic Curve Digital Signature Algorithm).

secp256k1とはビットコインの公開鍵暗号で使われる楕円曲線のパラメータです。

secp256k1 is an elliptic curve parameter used in Bitcoin public key cryptography.

このパラメーターを変化させることによって楕円曲線の形が変わります。

Changing this parameter changes the shape of the elliptic curve.

詳しくはWikiを参照してください。

See the wiki for more information.

必要なモジュールをインポートします。

Import the required modules.

from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec

試しにAはBに1BTCを送金するというメッセージを作成します。

As a trial, Create a message that [A will send 1BTC to B].

message = "AはBに1BTCを送金する"

プライベートキーをsecp256k1で作成します。

Create the private key in secp256k1.

private_key = ec.generate_private_key(ec.SECP256K1)

先ほどのメッセージをutf-8でエンコードして、文字列をバイト列にします。

Encode the previous message with utf-8 to turn the string into a string of bytes.

そしてsha256でハッシュ化して、プライベートキーを利用してデジタル署名を作成します。

It is then hashed with sha256 to create a digital signature using the private key.

signature = private_key.sign(message.encode('utf-8'), ec.ECDSA(hashes.SHA256()))

プライベートキーからパブリックキーを作成します。

Create a public key from your private key.

public_key = private_key.public_key()

では、署名が正しいかどうかをパブリックキーを使って検証してみましょう。

Now let's use the public key to verify that the signature is correct.

try:
    public_key.verify(signature, message.encode('utf-8'), ec.ECDSA(hashes.SHA256()))
    print("正しい署名です!")
except InvalidSignature:
    print("どうやら間違った署名ようですね!へっ!")

検証のメソッドは間違っていると例外を発生させます。

The validation method raises an exception if it is wrong.

なので、予めInvalidSignatureをインポートして、TryExcept文を使います。

So import InvalidSignature in advance and use the Try and Except statement.

試しにもう一つ別のプライベートキーを作成しましょう。

Let's try creating another private key.

private_key2 = ec.generate_private_key(ec.SECP256K1)
bad_signature = private_key2.sign(message.encode('utf-8'), ec.ECDSA(hashes.SHA256()))

同じメッセージですが、間違った署名が作られたと仮定します。

Assume the same message but with an incorrect signature.

先ほどの署名は最初に作られたパブリックキーなら検証が成功しますが、間違った署名の場合は検証に失敗するはずです。

The signature above should validate successfully for the first public key created, but not for the wrong signature.

try:
    public_key.verify(bad_signature, message.encode('utf-8'), ec.ECDSA(hashes.SHA256()))
    print("正しい署名です!")
except InvalidSignature:
    print("どうやら間違った署名ようですね!へっ!")

ではプライベートキーとパブリックキーの作成の関数、署名の関数、検証の関数をそれぞれ作成して、簡単なテストを行ってみましょう。

Now let's create a private key and a public key creation function, a signature function, and a validation function, and test them briefly.

検証の関数はTrueかFalseを返すようにします。

The validation function should return True or False.

まずプライベートキーとパブリックキーを作成してPrintメソッドで中身を確認してみましょう。

First, let's create a private key and a public key, then use the print method to examine the contents.

メッセージを作成して、デジタル署名を作成してPrintメソッドで中身を確認してみましょう。

Let's create a message, create a digital signature, and check its contents with the print method.

検証が正しいかどうかのブール値を取得します。

Gets the boolean value that indicates whether validation is correct.

検証が正しいかどうかを確認します。

Verify that the validation is correct.

次に先ほどとは別のプライベートキーとパブリックキーを作成します。

Then create another private and public key.

そしてプライベートキーを使って先ほどとは別のデジタル署名を作成します。

You then use the private key to create another digital signature.

先ほどとは別の署名だけを使って同じように検証が正しいかどうかを確認してみましょう。

Just use a different signature to verify that the validation is correct as well.

次はメッセージを改竄してみましょう。Aは"C"に1BTCを送金するという偽のメッセージを作成します。

Next, let's falsify the message. A creates a fake message saying that it will send 1 BTC to "C".

今度は改竄されたメッセージのみを使って検証を行います。メッセージのハッシュ値が異なるため検証は失敗するはずです。

This time, only the falsified message is used for verification. Validation should fail because the hash value of the message is different.

パブリックキーは文字通り公開されていますから、誰でも使用できます。

The public key is literally public, so anyone can use it.

そしてデジタル署名もコピーは可能です。そしてメッセージもコピー可能です。

Digital signatures can also be copied. You can also copy messages.

しかし、取引を行う時に作成されるプライベートキーとそれを基に作成されるデジタル署名は一回毎にまったく違ったバイト列に変わっているはずです。

However, the private key that is created when you make a transaction and the digital signature that is created from it should change to a completely different sequence of bytes each time.

なので、例えデジタル署名をコピーして再利用しようとしても、その署名がすでに使われていて、検証が成功していれば、間違った署名として処理できるはずです。

So even if you try to copy and reuse a digital signature, if the signature is already in use and has been successfully verified, you should be able to treat it as an incorrect signature.

これで取引における本人のなりすまし、偽造や改竄の脅威の心配は無くなりそうです。

Now you don't have to worry about impersonation, forgery or falsification.



以上です。お疲れ様です。

That's all. Thank you for your hard work.