def encrypt_message(pubkey, message, display_only, bip32, coin, address_n): if len(address_n) > 0: priv_node = bip32.get_private_node(address_n) priv_key = tools.EcKey(priv_node.private_key) signing = True else: signing = False if signing: if display_only: payload = chr(0x80 + 1) else: payload = chr(1) address, signature = sign_message(bip32, coin, address_n, message) address_bin = tools.bc_address_decode(address)[:21] payload += tools.ser_length(len(message)) + message + address_bin + signature else: if display_only: payload = chr(0x80) else: payload = chr(0) payload += tools.ser_length(len(message)) + message nonce = tools.get_local_entropy() nonce_key = tools.EcKey(nonce) nonce_pub = binascii.unhexlify(nonce_key.get_public_key(True)) dest_pub = tools.public_key_to_point(pubkey) shared_secret_point = dest_pub * nonce_key.privkey.secret_multiplier shared_secret = tools.point_to_public_key(shared_secret_point, True) keying_bytes = PBKDF2(shared_secret, "Bitcoin Secure Message" + nonce_pub, iterations=2048, macmodule=hmac, digestmodule=sha256).read(80) aes_key = keying_bytes[:32] hmac_key = keying_bytes[32:64] aes_iv = keying_bytes[64:] encrypter = pyaes.Encrypter(pyaes.AESModeOfOperationCFB(key=aes_key, iv=aes_iv, segment_size=16)) payload = encrypter.feed(payload) + encrypter.feed() msg_hmac = hmac.HMAC(key=hmac_key, msg=payload, digestmod=sha256).digest()[:8] return (nonce_pub, payload, msg_hmac)
def serialize_input(self, inp): if self.have_inputs >= self.inputs_len: raise Exception("Already have all inputs") r = '' if self.have_inputs == 0: r += self._serialize_header() r += ser_uint256(int(binascii.hexlify(inp.prev_hash), 16)) r += struct.pack("<I", inp.prev_index) r += tools.ser_length(len(inp.script_sig)) r += inp.script_sig r += struct.pack("<I", inp.sequence) self.have_inputs += 1 self.size += len(r) return r
def serialize_output(self, output): if self.have_inputs < self.inputs_len: raise Exception("Need all inputs first") if self.have_outputs >= self.outputs_len: raise Exception("Already have all outputs") r = '' if self.have_outputs == 0: # First output, let's serialize tx middle r += self._serialize_middle() r += struct.pack("<q", output.amount) r += tools.ser_length(len(output.script_pubkey)) r += output.script_pubkey self.have_outputs += 1 if self.have_outputs == self.outputs_len: r += self._serialize_footer() self.size += len(r) return r
def message_magic(message): magic = chr(24) + "Bitcoin Signed Message:\n" + tools.ser_length(len(message)) + message return magic
def _serialize_middle(self): return tools.ser_length(self.outputs_len)
def _serialize_header(self): r = struct.pack("<i", self.version) r += tools.ser_length(self.inputs_len) return r