pythonで秘密鍵を用いて任意のデータを署名して公開鍵で署名を検証する

技術メモ

前回実施した内容をベースに進めていく。

やっぱり、テストソースが参考になる。

class KeyTest(unittest.TestCase):

    def test_sign_verify(self):
        secret = 1
        private_key = Key(secret_exponent=1)
        h = b"x00" * 32
        sig = private_key.sign(h)
        self.assertTrue(private_key.verify(h, sig))
        public_key = private_key.public_copy()
        self.assertTrue(public_key.verify(h, sig))
        h160_key = Key(hash160=private_key.hash160())
        self.assertTrue(h160_key.verify(h, sig))
 :
 :

のソースの部分。 h の変数を任意の文字列にして実行する。

>>> from pycoin.key import Key
>>> private_key = Key(secret_exponent=1)
>>> key = 'todoroki'
>>> sig = private_key.sign(key)
>>> sig
'0Dx02 R>xc7x1axd75xacxd0(xecx14Rx17j_xaax8cxa6x96).]9gAx99xa7xf1fxe2x82xbfx02 )xa9tx86B{.xb0|x94Nxadxd1Axe9mx8f)-15xa9xdd5x8axcfxa5^Ux0eqx03'
>>> public_key = private_key.public_copy()
>>> public_key.verify(key, sig)
True

これでよさそうだけど、どう署名しているかがさっぱり中身がわかっていないので少し追っていく。

署名のアルゴリズムはwikipediaが詳しくのっている。

signしている箇所は以下。ecdsa.signで求めたr, s を sigencode_der で DERにしている。DERの説明はこのあたりを

https://github.com/richardkiss/pycoin/blob/1105b29dfae217b41944c6bd379c1a6d9eb4fdb7/pycoin/key/Key.py#L232

    def sign(self, h):
        """
        Return a der-encoded signature for a hash h.
        Will throw a RuntimeError if this key is not a private key
        """
        if not self.is_private():
            raise RuntimeError("Key must be private to be able to sign")
        val = from_bytes_32(h)
        r, s = ecdsa.sign(ecdsa.generator_secp256k1, self.secret_exponent(),
                          val)
        return sigencode_der(r, s)

sigencode_derの部分。DER化。

https://github.com/richardkiss/pycoin/blob/1105b29dfae217b41944c6bd379c1a6d9eb4fdb7/pycoin/tx/script/der.py#L113

def sigencode_der(r, s):
return encode_sequence(encode_integer(r), encode_integer(s))

def encode_sequence(*encoded_pieces):
total_len = sum([len(p) for p in encoded_pieces])
return b"x30" + encode_length(total_len) + b"".join(encoded_pieces)

def encode_integer(r):
assert r >= 0 # can't support negative numbers yet
h = "%x" % r
if len(h) % 2:
h = "0" + h
s = binascii.unhexlify(h.encode("utf8"))
if ord(s[:1])

Sponsored Link

ビットコイン(Bitcoin)、イーサリアム(Ethereum)、リップル(Ripple)、ネム(NEM)などの仮想通貨を買うならコインチェックがおすすめです。

※アプリは指値売買ができず手数料が高いので、アプリをダウンロードするのではなくメール&パスワード登録へ!まずは5万円ほど入金して仮想通貨とブロックチェーンの世界を楽しんでください!

ビットコイン取引高日本一の仮想通貨取引所 coincheck bitcoin

コメントはまだありません

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


miningpoolhub
miningpoolhubのAPIを使って自動スイッチングを試してみる in ethOS

* アイキャッチの男性は、Flicker上のライセンスフリーの画像ひっぱってきているだけで、本文とま …

NEM
[memo] NEMを送金しようとするとFAILURE_TIMESTAMP_TOO_FAR_IN_FUTUREが出る

Docker上のコンテナで、NEM-libraryを使ってmosaicの送金を試していたところ FA …

NEM
NEMのテストネットワークで独自通貨を試す

NEMアプリケーションを作る際にテストネットワークでのテスト非常に重要になってきます。 このため今回 …