From 0a53ad57219969412d453bff4929551576dfa501 Mon Sep 17 00:00:00 2001 From: Victor Shyba Date: Thu, 24 Dec 2020 02:55:47 -0300 Subject: [PATCH] use the comment api signing implementation --- lbry/extras/daemon/comment_client.py | 47 ++++++++++--------- lbry/extras/daemon/daemon.py | 9 +--- .../blockchain/test_claim_commands.py | 21 ++++----- 3 files changed, 34 insertions(+), 43 deletions(-) diff --git a/lbry/extras/daemon/comment_client.py b/lbry/extras/daemon/comment_client.py index 434e41f75..3791f91f6 100644 --- a/lbry/extras/daemon/comment_client.py +++ b/lbry/extras/daemon/comment_client.py @@ -26,42 +26,45 @@ def is_comment_signed_by_channel(comment: dict, channel: Output, sign_comment_id if isinstance(channel, Output): try: signing_field = comment['comment_id'] if sign_comment_id else comment['comment'] - pieces = [ - comment['signing_ts'].encode(), - cid2hash(comment['channel_id']), - signing_field.encode() - ] - return Output.is_signature_valid( - get_encoded_signature(comment['signature']), - sha256(b''.join(pieces)), - channel.claim.channel.public_key_bytes - ) + return verify(channel, signing_field.encode(), comment) except KeyError: pass return False +def verify(channel, data, signature): + pieces = [ + signature['signing_ts'].encode(), + channel.claim_hash, + data + ] + return Output.is_signature_valid( + get_encoded_signature(signature['signature']), + sha256(b''.join(pieces)), + channel.claim.channel.public_key_bytes + ) + + def sign_comment(comment: dict, channel: Output, sign_comment_id=False): - timestamp = str(int(time.time())) signing_field = comment['comment_id'] if sign_comment_id else comment['comment'] - pieces = [timestamp.encode(), channel.claim_hash, signing_field.encode()] + comment.update(sign(channel, signing_field.encode())) + + +def sign(channel, data): + timestamp = str(int(time.time())) + pieces = [timestamp.encode(), channel.claim_hash, data] digest = sha256(b''.join(pieces)) signature = channel.private_key.sign_digest_deterministic(digest, hashfunc=hashlib.sha256) - comment.update({ + return { 'signature': binascii.hexlify(signature).decode(), 'signing_ts': timestamp - }) + } + def sign_reaction(reaction: dict, channel: Output): - timestamp = str(int(time.time())) signing_field = reaction['channel_name'] - pieces = [timestamp.encode(), channel.claim_hash, signing_field.encode()] - digest = sha256(b''.join(pieces)) - signature = channel.private_key.sign_digest_deterministic(digest, hashfunc=hashlib.sha256) - reaction.update({ - 'signature': binascii.hexlify(signature).decode(), - 'signing_ts': timestamp - }) + reaction.update(sign(channel, signing_field.encode())) + async def jsonrpc_post(url: str, method: str, params: dict = None, **kwargs) -> any: params = params or {} diff --git a/lbry/extras/daemon/daemon.py b/lbry/extras/daemon/daemon.py index f2ab2184c..8b098e451 100644 --- a/lbry/extras/daemon/daemon.py +++ b/lbry/extras/daemon/daemon.py @@ -22,7 +22,6 @@ from aiohttp import web from prometheus_client import generate_latest as prom_generate_latest, Gauge, Histogram, Counter from google.protobuf.message import DecodeError -from lbry.crypto.hash import sha256 from lbry.wallet import ( Wallet, ENCRYPT_ON_DISK, SingleKey, HierarchicalDeterministic, Transaction, Output, Input, Account, database @@ -2816,13 +2815,7 @@ class Daemon(metaclass=JSONRPCServerType): signing_channel = await self.get_channel_or_error( wallet, channel_account_id, channel_id, channel_name, for_signing=True ) - digest = sha256(unhexlify(hexdata)) - signature = signing_channel.private_key.sign_digest_deterministic(digest, hashfunc=hashlib.sha256) - return { - "signature": hexlify(signature), - "digest": hexlify(digest), - "signing_channel": signing_channel - } + return comment_client.sign(signing_channel, unhexlify(hexdata)) @requires(WALLET_COMPONENT) async def jsonrpc_channel_abandon( diff --git a/tests/integration/blockchain/test_claim_commands.py b/tests/integration/blockchain/test_claim_commands.py index f6b044050..17a322ed5 100644 --- a/tests/integration/blockchain/test_claim_commands.py +++ b/tests/integration/blockchain/test_claim_commands.py @@ -5,13 +5,12 @@ import asyncio from binascii import unhexlify from urllib.request import urlopen -import ecdsa - from lbry.error import InsufficientFundsError +from lbry.extras.daemon.comment_client import verify from lbry.extras.daemon.daemon import DEFAULT_PAGE_SIZE from lbry.testcase import CommandTestCase -from lbry.wallet.transaction import Transaction, Output +from lbry.wallet.transaction import Transaction from lbry.wallet.util import satoshis_to_coins as lbc @@ -1010,17 +1009,13 @@ class ChannelCommands(CommandTestCase): data_to_sign = "CAFEBABE" # claim new name await self.channel_create('@someotherchan') - channel_tx = await self.channel_create('@signer') - channel_id = self.get_claim_id(channel_tx) + channel_tx = await self.daemon.jsonrpc_channel_create('@signer', '0.1') + await self.confirm_tx(channel_tx.id) + channel = channel_tx.outputs[0] signature1 = await self.out(self.daemon.jsonrpc_channel_sign(channel_name='@signer', hexdata=data_to_sign)) - signature2 = await self.out(self.daemon.jsonrpc_channel_sign(channel_id=channel_id, hexdata=data_to_sign)) - self.assertEqual(signature2, signature1) - key = unhexlify(channel_tx['outputs'][0]['value']['public_key']) - signature = signature1["signature"] - r = int(signature[:int(len(signature)/2)], 16) - s = int(signature[int(len(signature)/2):], 16) - signature = ecdsa.util.sigencode_der(r, s, len(signature)*4) - self.assertTrue(Output.is_signature_valid(signature, unhexlify(signature1["digest"]), key)) + signature2 = await self.out(self.daemon.jsonrpc_channel_sign(channel_id=channel.claim_id, hexdata=data_to_sign)) + self.assertTrue(verify(channel, unhexlify(data_to_sign), signature1)) + self.assertTrue(verify(channel, unhexlify(data_to_sign), signature2)) async def test_channel_export_import_before_sending_channel(self): # export