Exemplo n.º 1
0
 def witness(self, signature_hash: bytes):
     sig = self.privkey.sign_compact(signature_hash)
     sig_der = wally.ec_sig_to_der(sig) + bytearray([wally.WALLY_SIGHASH_ALL])
     witness = wally.tx_witness_stack_init(2)
     wally.tx_witness_stack_add(witness, sig_der)
     wally.tx_witness_stack_add(witness, self.witness_script())
     return witness
Exemplo n.º 2
0
 def sign_message(self, path: List[int], message: str) -> bytearray:
     message = message.encode('utf-8')
     formatted = wally.format_bitcoin_message(message, wally.BITCOIN_MESSAGE_FLAG_HASH)
     privkey = self.get_privkey(path)
     signature = wally.ec_sig_from_bytes(privkey, formatted,
                                         wally.EC_FLAG_ECDSA | wally.EC_FLAG_GRIND_R)
     return wally.ec_sig_to_der(signature)
Exemplo n.º 3
0
    def sign_tx(self, details):
        txdetails = details['transaction']

        utxos = txdetails['used_utxos'] or txdetails['old_used_utxos']
        signatures = []
        for index, utxo in enumerate(utxos):
            wally_tx = wally.tx_from_hex(txdetails['transaction'],
                                         wally.WALLY_TX_FLAG_USE_WITNESS)
            is_segwit = utxo['script_type'] in [14, 15, 159, 162]  # FIXME!!
            if not is_segwit:
                # FIXME
                raise NotImplementedError("Non-segwit input")
            flags = wally.WALLY_TX_FLAG_USE_WITNESS if is_segwit else 0
            prevout_script = wally.hex_to_bytes(utxo['prevout_script'])
            txhash = wally.tx_get_btc_signature_hash(wally_tx, index,
                                                     prevout_script,
                                                     utxo['satoshi'],
                                                     wally.WALLY_SIGHASH_ALL,
                                                     flags)

            path = utxo['user_path']
            privkey = self.get_privkey(path)
            signature = wally.ec_sig_from_bytes(
                privkey, txhash, wally.EC_FLAG_ECDSA | wally.EC_FLAG_GRIND_R)
            signature = wally.ec_sig_to_der(signature)
            signature.append(wally.WALLY_SIGHASH_ALL)
            signatures.append(wally.hex_from_bytes(signature))
            logging.debug('Signature (der) input %s path %s: %s', index, path,
                          signature)

        return json.dumps({'signatures': signatures})
Exemplo n.º 4
0
    def _sign_tx(self, details, wally_tx):
        txdetails = details['transaction']
        utxos = txdetails['used_utxos'] or txdetails['old_used_utxos']

        signatures = []
        for index, utxo in enumerate(utxos):

            is_segwit = utxo['script_type'] in [14, 15, 159, 162]  # FIXME!!
            if not is_segwit:
                # FIXME
                raise NotImplementedError("Non-segwit input")

            txhash = self._get_sighash(wally_tx, index, utxo)

            path = utxo['user_path']
            privkey = self.get_privkey(path)
            signature = wally.ec_sig_from_bytes(
                privkey, txhash, wally.EC_FLAG_ECDSA | wally.EC_FLAG_GRIND_R)
            signature = wally.ec_sig_to_der(signature)
            signature.append(wally.WALLY_SIGHASH_ALL)
            signatures.append(wally.hex_from_bytes(signature))
            logging.debug('Signature (der) input %s path %s: %s', index, path,
                          signature)

        return {'signatures': signatures}
Exemplo n.º 5
0
 def sign_message(self, required_data):
     sig = btc.sign_message(self.client, "Bitcoin", required_data['path'],
                            required_data['message'])
     # TODO: trezor appears to generate a recoverable sig
     sig_der = wally.ec_sig_to_der(sig['signature'][1:])
     return json.dumps({
         'signature':
         sig_der.hex(),
         'signature_b64':
         base64.b64encode(sig['signature']).decode('ascii')
     })
Exemplo n.º 6
0
    def witness(self, signature_hash: bytes):
        # TODO: allow partial signing
        witness = wally.tx_witness_stack_init(self.threshold + 2)
        wally.tx_witness_stack_add_dummy(witness, wally.WALLY_TX_DUMMY_NULL)
        num_sigs = 0
        for privkey in self.privkeys:
            if privkey and num_sigs < self.threshold:
                sig = privkey.sign_compact(signature_hash)
                sig_der = wally.ec_sig_to_der(sig) + bytearray([wally.WALLY_SIGHASH_ALL])
                wally.tx_witness_stack_add(witness, sig_der)
                num_sigs += 1

        wally.tx_witness_stack_add(witness, self.witness_script())
        return witness
Exemplo n.º 7
0
    def sign_message(self, path: List[int], message: str) -> bytes:
        """Return der encoded signature of a message

        path: BIP32 path of key to use for signing
        message: Message to be signed
        """
        path = HWIDevice._path_to_string(path)

        click.echo('Signing with hardware device {}'.format(self.name))
        click.echo('Please check the device for interaction')

        signature = hwilib.commands.signmessage(self._device, message,
                                                path)['signature']
        return wally.ec_sig_to_der(base64.b64decode(signature)[1:])
Exemplo n.º 8
0
    def sign_message(self, details: Dict) -> Dict:
        """Return der encoded signature of a message

        details: Details of message to sign
        """
        message = details['message']
        path = HWIDevice._path_to_string(details['path'])

        click.echo('Signing with hardware device {}'.format(self.name))
        click.echo('Please check the device for interaction')

        signature = hwilib.commands.signmessage(self._device, message,
                                                path)['signature']
        signature = base64.b64decode(signature)
        if len(signature) == wally.EC_SIGNATURE_RECOVERABLE_LEN:
            signature = signature[1:]

        return {'signature': wally.ec_sig_to_der(signature).hex()}
Exemplo n.º 9
0
    def sign_message(self, details: Dict) -> Dict:
        message = details['message'].encode('utf-8')
        formatted = wally.format_bitcoin_message(
            message, wally.BITCOIN_MESSAGE_FLAG_HASH)
        privkey = self.get_privkey(details['path'])

        result = {}
        if details['use_ae_protocol']:
            signer_commitment, signature = self._make_ae_signature(
                privkey, formatted, details)
            signer_commitment = signer_commitment.hex()
            logging.debug('Signer commitment: %s', signer_commitment)
            result['signer_commitment'] = signer_commitment
        else:
            signature = wally.ec_sig_from_bytes(
                privkey, formatted,
                wally.EC_FLAG_ECDSA | wally.EC_FLAG_GRIND_R)

        result['signature'] = wally.ec_sig_to_der(signature).hex()
        return result
Exemplo n.º 10
0
    def _sign_tx(self, details, wally_tx):
        txdetails = details['transaction']
        utxos = details['signing_inputs']
        use_ae_protocol = details['use_ae_protocol']

        signatures = []
        signer_commitments = []
        for index, utxo in enumerate(utxos):
            is_segwit = utxo['address_type'] in [
                'p2wsh', 'csv', 'p2wpkh', 'p2sh-p2wpkh'
            ]
            flags = wally.WALLY_TX_FLAG_USE_WITNESS if is_segwit else 0

            txhash = self._get_sighash(wally_tx, index, utxo, flags)
            path = utxo['user_path']
            privkey = self.get_privkey(path)
            logging.debug('Processing input %s, path %s', index, path)

            if use_ae_protocol:
                signer_commitment, signature = self._make_ae_signature(
                    privkey, txhash, utxo)

                signer_commitment = signer_commitment.hex()
                logging.debug('Signer commitment: %s', signer_commitment)
                signer_commitments.append(signer_commitment)
            else:
                signature = wally.ec_sig_from_bytes(
                    privkey, txhash,
                    wally.EC_FLAG_ECDSA | wally.EC_FLAG_GRIND_R)

            signature = wally.ec_sig_to_der(signature)
            signature.append(wally.WALLY_SIGHASH_ALL)
            signature = signature.hex()
            logging.debug('Signature (der): %s', signature)
            signatures.append(signature)

        result = {
            'signer_commitments': signer_commitments
        } if use_ae_protocol else {}
        result['signatures'] = signatures
        return result
Exemplo n.º 11
0
    def sign_message(self, details: Dict) -> Dict:
        path = details['path']
        message = details['message']
        result = {}

        if details['use_ae_protocol']:
            ae_host_commitment =  bytes.fromhex(details['ae_host_commitment'])
            ae_host_entropy = bytes.fromhex(details['ae_host_entropy'])
            signer_commitment, sig_encoded = self.jade.sign_message(path, message, True,
                                                                    ae_host_commitment,
                                                                    ae_host_entropy)
            result['signer_commitment'] = signer_commitment.hex()
        else:
            sig_encoded = self.jade.sign_message(path, message)

        sig_decoded = base64.b64decode(sig_encoded)

        # Need to truncate lead byte if recoverable signature
        if len(sig_decoded) == wally.EC_SIGNATURE_RECOVERABLE_LEN:
            sig_decoded = sig_decoded[1:]

        der_sig = wally.ec_sig_to_der(sig_decoded)
        result['signature'] = der_sig.hex()
        return result
Exemplo n.º 12
0
def _to_der(sig):
    return wally.ec_sig_to_der(sig) + bytearray([wally.WALLY_SIGHASH_ALL])
Exemplo n.º 13
0
 def sign(self, h):
     """Produce a DER signature for (hashed) message h"""
     return wally.ec_sig_to_der(self.sign_compact(h))