def test_sign_block(self, b, alice): from bigchaindb.common.crypto import PrivateKey, PublicKey from bigchaindb.common.utils import gen_timestamp, serialize from bigchaindb.models import Block, Transaction transactions = [ Transaction.create([alice.public_key], [([alice.public_key], 1)]) ] timestamp = gen_timestamp() voters = ['Qaaa', 'Qbbb'] expected_block = { 'timestamp': timestamp, 'transactions': [tx.to_dict() for tx in transactions], 'node_pubkey': alice.public_key, 'voters': voters, } expected_block_serialized = serialize(expected_block).encode() expected = PrivateKey( alice.private_key).sign(expected_block_serialized) block = Block(transactions, alice.public_key, timestamp, voters) block = block.sign(alice.private_key) assert block.signature == expected.decode() public_key = PublicKey(alice.public_key) assert public_key.verify(expected_block_serialized, block.signature)
def verify_vote_signature(cls, vote): """Verify the signature of a vote """ signature = vote.get('signature') pk_base58 = vote.get('node_pubkey') if not (type(signature) == str and type(pk_base58) == str): raise ValueError('Malformed vote: %s' % vote) public_key = PublicKey(pk_base58) body = serialize(vote['vote']).encode() return public_key.verify(body, signature)
def is_signature_valid(self): """Check the validity of a Block's signature. Returns: bool: Stating the validity of the Block's signature. """ block = self.to_dict()['block'] # cc only accepts bytestring messages block_serialized = serialize(block).encode() public_key = PublicKey(block['node_pubkey']) try: # NOTE: CC throws a `ValueError` on some wrong signatures # https://github.com/bigchaindb/cryptoconditions/issues/27 return public_key.verify(block_serialized, self.signature) except (ValueError, AttributeError): return False
def from_dict(cls, block_body): """Transform a Python dictionary to a Block object. Args: block_body (dict): A block dictionary to be transformed. Returns: :class:`~Block` Raises: InvalidHash: If the block's id is not corresponding to its data. InvalidSignature: If the block's signature is not corresponding to it's data or `node_pubkey`. """ # TODO: Reuse `is_signature_valid` method here. block = block_body['block'] block_serialized = serialize(block) block_id = hash_data(block_serialized) public_key = PublicKey(block['node_pubkey']) try: signature = block_body['signature'] except KeyError: signature = None if block_id != block_body['id']: raise InvalidHash() if signature is not None: # NOTE: CC throws a `ValueError` on some wrong signatures # https://github.com/bigchaindb/cryptoconditions/issues/27 try: signature_valid = public_key\ .verify(block_serialized.encode(), signature) except ValueError: signature_valid = False if signature_valid is False: raise InvalidSignature('Invalid block signature') transactions = [ Transaction.from_dict(tx) for tx in block['transactions'] ] return cls(transactions, block['node_pubkey'], block['timestamp'], block['voters'], signature)