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
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)
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})
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}
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') })
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
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:])
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()}
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
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
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
def _to_der(sig): return wally.ec_sig_to_der(sig) + bytearray([wally.WALLY_SIGHASH_ALL])
def sign(self, h): """Produce a DER signature for (hashed) message h""" return wally.ec_sig_to_der(self.sign_compact(h))