Adds Comment Signing and Validation

This commit is contained in:
Oleg Silkin 2019-06-12 20:20:30 -04:00 committed by Lex Berezhny
parent 756d17bada
commit ce5dd5022b

View file

@ -1,42 +1,47 @@
import logging import logging
import time
import hashlib
import binascii
import aiohttp import aiohttp
import hashlib import ecdsa
from cryptography.hazmat.backends import default_backend from torba.client.hash import sha256
from cryptography.hazmat.primitives import hashes from lbrynet.wallet.transaction import Output
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.asymmetric import utils
from cryptography.hazmat.primitives.asymmetric.rsa import generate_private_key
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
def sign_comment(**kwargs): def get_encoded_signature(signature):
private_key = generate_private_key( signature = signature.encode() if type(signature) is str else signature
public_exponent=65537, r = int(signature[:int(len(signature) / 2)], 16)
key_size=4096, s = int(signature[int(len(signature) / 2):], 16)
backend=default_backend() return ecdsa.util.sigencode_der(r, s, len(signature) * 4)
)
chosen_hash = hashes.SHA256()
hasher = hashes.Hash(chosen_hash, default_backend())
value_to_hash = b':'.join(bytes(v, 'utf-8') for v in kwargs.values() if type(v) is str)
hasher.update(value_to_hash)
digest = hasher.finalize()
signature = private_key.sign(
digest,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
utils.Prehashed(chosen_hash)
)
m = hashlib.sha3_256()
m.update(signature)
return m.hexdigest()
def rpc_body(method: str, rpc_id: any, **params) -> dict: def is_comment_signed_by_channel(comment: dict, channel: Output):
return {'jsonrpc': '2.0', 'id': rpc_id, 'method': method, 'params': {**params}} try:
pieces = [
comment['signing_ts'].encode(),
channel.claim_hash,
comment['comment'].encode()
]
return Output.is_signature_valid(
get_encoded_signature(comment['signature']),
sha256(b''.join(pieces)),
channel.claim.channel.public_key_bytes
)
except KeyError:
pass
return False
def sign_comment(comment: dict, channel: Output):
timestamp = str(int(time.time())).encode()
pieces = [timestamp, channel.claim_hash, comment['comment'].encode()]
digest = sha256(b''.join(pieces))
signature = channel.private_key.sign_digest_deterministic(digest, hashfunc=hashlib.sha256)
comment['signature'] = binascii.hexlify(signature).decode()
comment['signing_ts'] = timestamp.decode()
async def jsonrpc_post(url: str, method: str, **params) -> any: async def jsonrpc_post(url: str, method: str, **params) -> any: