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_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, 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_compact(self, h): """Produce a compact signature for (hashed) message h""" if self.prv is None: raise ValueError('Missing private key') return wally.ec_sig_from_bytes( self.prv, h, wally.EC_FLAG_ECDSA | wally.EC_FLAG_GRIND_R)
def sign_message(privkey_wif: str, message: str) -> str: """Sign a message with a private key of a P2PKH address 'privkey_wif' must be in WIF format, message and signature are formatted as 'signmessage' RPC does. """ privkey = PrivateKey.from_wif(privkey_wif) h = wally.format_bitcoin_message(message.encode('ascii'), wally.BITCOIN_MESSAGE_FLAG_HASH) flags = wally.EC_FLAG_ECDSA | wally.EC_FLAG_RECOVERABLE recoverable_signature = wally.ec_sig_from_bytes(privkey.prv, h, flags) return base64.b64encode(recoverable_signature)
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 server_call(self, private_key, client, endpoint, pin_secret, entropy): # Make and encrypt the payload (ie. pin secret) ske, cke = client.get_key_exchange() sig = ec_sig_from_bytes(private_key, sha256(cke + pin_secret + entropy), EC_FLAG_ECDSA | EC_FLAG_RECOVERABLE) payload = pin_secret + entropy + sig encrypted, hmac = client.encrypt_request_payload(payload) # Make call and parse response urldata = { 'ske': b2h(ske), 'cke': b2h(cke), 'encrypted_data': b2h(encrypted), 'hmac_encrypted_data': b2h(hmac) } response = self.post(endpoint, urldata) encrypted = h2b(response['encrypted_key']) hmac = h2b(response['hmac']) # Return decrypted payload return client.decrypt_response_payload(encrypted, hmac)
def get_signature(self, preimage_hash): return wally.ec_sig_from_bytes(self.key, preimage_hash, wally.EC_FLAG_ECDSA)
def sign_compact(self, h: bytes) -> bytes: """Produce a compact ECDSA signature for (hashed) message h""" return wally.ec_sig_from_bytes( self.prv, h, wally.EC_FLAG_ECDSA | wally.EC_FLAG_GRIND_R)
vin, 0xffffffff, None, # scriptSig None, # witness None, # nonce None, # entropy None, # issuance amount None, # inflation keys None, # issuance amount rangeproof None, # inflation keys rangeproof None, # pegin witness vout) privkey = wally.bip32_key_get_priv_key(wallet_derived_key) pubkey = wally.ec_public_key_from_private_key(privkey) sighash = wally.tx_get_btc_signature_hash(output_tx, vout, script_pubkey, 0, wally.WALLY_SIGHASH_ALL, 0) signature = wally.ec_sig_from_bytes(privkey, sighash, wally.EC_FLAG_ECDSA) scriptsig = wally.scriptsig_p2pkh_from_sig(pubkey, signature, wally.WALLY_SIGHASH_ALL) wally.tx_set_input_script(output_tx, vout, scriptsig) # end-sign # start-to_hex tx_hex = wally.tx_to_hex(output_tx, wally.WALLY_TX_FLAG_USE_WITNESS) # end-to_hex
def _sign_with_static_key(cls, msg): cls._load_private_key() hashed = sha256(msg) return ec_sig_from_bytes(cls.STATIC_SERVER_PRIVATE_KEY, hashed, EC_FLAG_ECDSA)
def make_payload(signing_key, cke, secret_in, entropy_in): # Build the expected payload sig = ec_sig_from_bytes(signing_key, sha256(cke + secret_in + entropy_in), EC_FLAG_ECDSA | EC_FLAG_RECOVERABLE) return secret_in + entropy_in + sig
def get_signature(self, preimage_hash): flags = wally.EC_FLAG_ECDSA | wally.EC_FLAG_GRIND_R return wally.ec_sig_from_bytes(self.key, preimage_hash, flags)