Beispiel #1
0
    def test_script(self):
        genesis_block = self.genesis_blocks[0]

        # random keys to be used
        random_priv = 'MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgMnAHVIyj7Hym2yI' \
                      'w+JcKEfdCHByIp+FHfPoIkcnjqGyhRANCAATX76SGshGeoacUcZDhXEzERt' \
                      'AHbd30CVpUg8RRnAIhaFcuMY3G+YFr/mReAPRuiLKCnolWz3kCltTtNj36rJyd'
        private_key_random = get_private_key_from_bytes(
            base64.b64decode(random_priv))

        # create input data with incorrect private key
        _input = TxInput(genesis_block.hash, 0, b'')
        value = genesis_block.outputs[0].value

        address = get_address_from_public_key(self.genesis_public_key)
        script = P2PKH.create_output_script(address)
        output = TxOutput(value, script)

        tx = Transaction(inputs=[_input],
                         outputs=[output],
                         storage=self.tx_storage,
                         timestamp=self.last_block.timestamp + 1)

        data_to_sign = tx.get_sighash_all()
        public_bytes, signature = self.wallet.get_input_aux_data(
            data_to_sign, private_key_random)
        data_wrong = P2PKH.create_input_data(public_bytes, signature)
        _input.data = data_wrong

        with self.assertRaises(InvalidInputData):
            tx.verify_inputs()
def main():
    from hathor.cli.util import create_parser
    from hathor.crypto.util import get_private_key_from_bytes

    parser = create_parser()

    parser.add_argument('data',
                        nargs='+',
                        help='Encode data in oracle format.')
    parser.add_argument(
        '--keyfile', help='Path to a private key file, used to sign the data')
    args = parser.parse_args()

    binary_data = b''

    for d in args.data:
        [t, _data] = d.split(':')
        if t == 'int':
            b = encode_int(_data)
        elif t == 'str':
            b = encode_str(_data)
        else:
            print('wrong data type {}'.format(d))
            return 1

        binary_data += (bytes([len(b)]) + b)

    print('data (base64):', base64.b64encode(binary_data).decode('utf-8'))

    with open(args.keyfile, 'r') as key_file:
        private_key_bytes = base64.b64decode(key_file.read())
    private_key = get_private_key_from_bytes(private_key_bytes)
    signature = private_key.sign(binary_data, ec.ECDSA(hashes.SHA256()))
    print('signature (base64):', base64.b64encode(signature).decode('utf-8'))
def main():
    from hathor.cli.util import create_parser
    from hathor.crypto.util import get_hash160, get_private_key_from_bytes, get_public_key_bytes_compressed

    parser = create_parser()

    parser.add_argument('filepath',
                        help='Get public key hash given the private key file')
    args = parser.parse_args()

    with open(args.filepath, 'r') as key_file:
        private_key_bytes = base64.b64decode(key_file.read())
    private_key = get_private_key_from_bytes(private_key_bytes)
    public_key_bytes = get_public_key_bytes_compressed(
        private_key.public_key())
    print('base64:', base64.b64encode(public_key_bytes).decode('utf-8'))
    print('hash base64:',
          base64.b64encode(get_hash160(public_key_bytes)).decode('utf-8'))
Beispiel #4
0
    def get_private_key(self, password: bytes) -> _EllipticCurvePrivateKey:
        """
        :param password: password to decode private key
        :type password: bytes

        :return: Private key object.
        :rtype: :py:class:`cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey`

        :raises WalletLocked: wallet password was not provided
        :raises IncorrectPassword: password provided cannot decrypt keys
        """
        if not password:
            raise WalletLocked
        if self._cache_priv_key_unlock is None:
            try:
                assert self.private_key_bytes is not None
                self._cache_priv_key_unlock = get_private_key_from_bytes(self.private_key_bytes, password=password)
            except ValueError:
                raise IncorrectPassword
        return self._cache_priv_key_unlock
Beispiel #5
0
def generate_signature(tx: Transaction,
                       private_key_bytes: bytes,
                       password: Optional[bytes] = None) -> bytes:
    """ Create a signature for the tx

        :param tx: transaction with the data to be signed
        :type tx: :py:class:`hathor.transaction.transaction.Transaction`

        :param private_key_bytes: private key to generate the signature
        :type private_key_bytes: bytes

        :param password: password to decrypt the private key
        :type password: bytes

        :return: signature of the tx
        :rtype: bytes
    """
    private_key = get_private_key_from_bytes(private_key_bytes,
                                             password=password)
    data_to_sign = tx.get_sighash_all()
    hashed_data = hashlib.sha256(data_to_sign).digest()
    signature = private_key.sign(hashed_data, ec.ECDSA(hashes.SHA256()))
    return signature
Beispiel #6
0
    def test_spend_multisig(self):
        # Adding funds to the wallet
        blocks = add_new_blocks(self.manager, 2, advance_clock=15)
        add_blocks_unlock_reward(self.manager)
        self.assertEqual(
            self.manager.wallet.balance[settings.HATHOR_TOKEN_UID],
            WalletBalance(0, sum(blk.outputs[0].value for blk in blocks)))

        first_block_amount = blocks[0].outputs[0].value

        # First we send tokens to a multisig address
        outputs = [
            WalletOutputInfo(address=self.multisig_address,
                             value=first_block_amount,
                             timelock=int(self.clock.seconds()) + 15)
        ]

        tx1 = self.manager.wallet.prepare_transaction_compute_inputs(
            Transaction, outputs)
        tx1.weight = 10
        tx1.parents = self.manager.get_new_tx_parents()
        tx1.timestamp = int(self.clock.seconds())
        tx1.resolve()
        self.manager.propagate_tx(tx1)
        self.clock.advance(10)

        self.assertEqual(
            self.manager.wallet.balance[settings.HATHOR_TOKEN_UID],
            WalletBalance(0, first_block_amount))

        # Then we create a new tx that spends this tokens from multisig wallet
        tx = Transaction.create_from_struct(tx1.get_struct())
        tx.weight = 10
        tx.parents = self.manager.get_new_tx_parents()
        tx.timestamp = int(self.clock.seconds())

        multisig_script = create_output_script(self.multisig_address)

        multisig_output = TxOutput(200, multisig_script)
        wallet_output = TxOutput(300, create_output_script(self.address))
        outside_output = TxOutput(first_block_amount - 200 - 300,
                                  create_output_script(self.outside_address))

        tx.outputs = [multisig_output, wallet_output, outside_output]

        tx_input = TxInput(tx1.hash, 0, b'')
        tx.inputs = [tx_input]

        signatures = []
        for private_key_hex in self.private_keys:
            signature = generate_signature(tx,
                                           bytes.fromhex(private_key_hex),
                                           password=b'1234')
            signatures.append(signature)

        input_data = MultiSig.create_input_data(self.redeem_script, signatures)
        tx.inputs[0].data = input_data

        tx.resolve()
        # Transaction is still locked
        self.assertFalse(self.manager.propagate_tx(tx))

        self.clock.advance(6)
        tx.timestamp = int(self.clock.seconds())
        tx.resolve()

        # First we try to propagate with a P2PKH input
        private_key_obj = get_private_key_from_bytes(bytes.fromhex(
            self.private_keys[0]),
                                                     password=b'1234')
        pubkey_obj = private_key_obj.public_key()
        public_key_compressed = get_public_key_bytes_compressed(pubkey_obj)
        p2pkh_input_data = P2PKH.create_input_data(public_key_compressed,
                                                   signatures[0])
        tx2 = Transaction.create_from_struct(tx.get_struct())
        tx2.inputs[0].data = p2pkh_input_data
        tx2.resolve()
        self.assertFalse(self.manager.propagate_tx(tx2))

        # Now we propagate the correct
        self.assertTrue(self.manager.propagate_tx(tx))

        self.assertEqual(
            self.manager.wallet.balance[settings.HATHOR_TOKEN_UID],
            WalletBalance(0, first_block_amount + 300))

        # Testing the MultiSig class methods
        cls_script = parse_address_script(multisig_script)
        self.assertTrue(isinstance(cls_script, MultiSig))
        self.assertEqual(cls_script.address, self.multisig_address_b58)

        expected_dict = {
            'type': 'MultiSig',
            'address': self.multisig_address_b58,
            'timelock': None
        }
        self.assertEqual(cls_script.to_human_readable(), expected_dict)

        script_eval(tx, tx_input, tx1)

        # Script error
        with self.assertRaises(ScriptError):
            create_output_script(
                base58.b58decode('55d14K5jMqsN2uwUEFqiPG5SoD7Vr1BfnH'))
Beispiel #7
0
def get_genesis_key():
    private_key_bytes = base64.b64decode(
        'MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgOCgCddzDZsfKgiMJLOt97eov9RLwHeePyBIK2WPF8MChRA'
        'NCAAQ/XSOK+qniIY0F3X+lDrb55VQx5jWeBLhhzZnH6IzGVTtlAj9Ki73DVBm5+VXK400Idd6ddzS7FahBYYC7IaTl'
    )
    return get_private_key_from_bytes(private_key_bytes)
Beispiel #8
0
 def test_privkey_serialization(self):
     private_key_bytes = get_private_key_bytes(self.private_key)
     self.assertEqual(
         self.private_key.private_numbers(),
         get_private_key_from_bytes(private_key_bytes).private_numbers())