URI: 
       tencrypt/decrypt messages in gui - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit da6f292dd53d7f13a58522a9ad05dc50c92031bc
   DIR parent 1face99346b2376d095b6abd72c9301d14de958c
  HTML Author: ThomasV <thomasv@gitorious>
       Date:   Mon,  3 Mar 2014 10:39:10 +0100
       
       encrypt/decrypt messages in gui
       
       Diffstat:
         M gui/qt/main_window.py               |     107 +++++++++++++++++++++++++------
         M lib/bitcoin.py                      |       4 ++++
         M lib/commands.py                     |      12 +++++-------
         M lib/wallet.py                       |      18 ++++++++++++++++++
       
       4 files changed, 113 insertions(+), 28 deletions(-)
       ---
   DIR diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py
       t@@ -403,16 +403,14 @@ class ElectrumWindow(QMainWindow):
                #preferences_menu.setShortcut(QKeySequence.Preferences)
                preferences_menu.triggered.connect(self.settings_dialog)
        
       -        network = tools_menu.addAction(_("&Network"))
       -        network.triggered.connect(self.run_network_dialog)
       -
       -        plugins_labels = tools_menu.addAction(_("&Plugins"))
       -        plugins_labels.triggered.connect(self.plugins_dialog)
       +        tools_menu.addAction(_("&Network"), self.run_network_dialog)
       +        tools_menu.addAction(_("&Plugins"), self.plugins_dialog)
        
                tools_menu.addSeparator()
       +        tools_menu.addAction(_("&Sign/verify message"), self.sign_verify_message)
       +        tools_menu.addAction(_("&Encrypt/decrypt message"), self.encrypt_message)
        
       -        verifymessage = tools_menu.addAction(_("&Verify message"))
       -        verifymessage.triggered.connect(lambda: self.sign_verify_message(False))
       +        tools_menu.addSeparator()
        
                csv_transaction_menu = tools_menu.addMenu(_("&Create transaction"))
        
       t@@ -1155,7 +1153,8 @@ class ElectrumWindow(QMainWindow):
                    menu.addAction(_("Edit label"), lambda: self.edit_label(True))
                    if self.wallet.seed:
                        menu.addAction(_("Private key"), lambda: self.show_private_key(addr))
       -                menu.addAction(_("Sign message"), lambda: self.sign_verify_message(True,addr))
       +                menu.addAction(_("Sign/verify message"), lambda: self.sign_verify_message(addr))
       +                menu.addAction(_("Encrypt/decrypt message"), lambda: self.encrypt_message(addr))
                    if addr in self.wallet.imported_keys:
                        menu.addAction(_("Remove from wallet"), lambda: self.delete_imported_key(addr))
        
       t@@ -1731,35 +1730,39 @@ class ElectrumWindow(QMainWindow):
                    self.show_message(_("Error: wrong signature"))
        
        
       -    def sign_verify_message(self, sign, address=''):
       -        if sign and not address: return
       +    def sign_verify_message(self, address=''):
                d = QDialog(self)
                d.setModal(1)
       -        d.setWindowTitle(_('Sign Message') if sign else _('Verify Message'))
       +        d.setWindowTitle(_('Sign/verify Message'))
                d.setMinimumSize(410, 290)
        
                layout = QGridLayout(d)
        
       -        address_e = QLineEdit()
       -        address_e.setText(address)
       -        layout.addWidget(QLabel(_('Address')), 1, 0)
       -        layout.addWidget(address_e, 1, 1)
       -
                message_e = QTextEdit()
       -        layout.addWidget(QLabel(_('Message')), 2, 0)
       -        layout.addWidget(message_e, 2, 1)
       +        layout.addWidget(QLabel(_('Message')), 1, 0)
       +        layout.addWidget(message_e, 1, 1)
                layout.setRowStretch(2,3)
        
       +        address_e = QLineEdit()
       +        address_e.setText(address)
       +        layout.addWidget(QLabel(_('Address')), 2, 0)
       +        layout.addWidget(address_e, 2, 1)
       +
                signature_e = QTextEdit()
                layout.addWidget(QLabel(_('Signature')), 3, 0)
                layout.addWidget(signature_e, 3, 1)
                layout.setRowStretch(3,1)
        
                hbox = QHBoxLayout()
       -        b = QPushButton(_("Sign") if sign else _("Verify"))
       +
       +        b = QPushButton(_("Sign"))
       +        b.clicked.connect(lambda: self.do_sign(address_e, message_e, signature_e))
       +        hbox.addWidget(b)
       +
       +        b = QPushButton(_("Verify"))
       +        b.clicked.connect(lambda: self.do_verify(address_e, message_e, signature_e))
                hbox.addWidget(b)
       -        f = self.do_sign if sign else self.do_verify
       -        b.clicked.connect(lambda: f(address_e, message_e, signature_e))
       +
                b = QPushButton(_("Close"))
                b.clicked.connect(d.accept)
                hbox.addWidget(b)
       t@@ -1767,6 +1770,68 @@ class ElectrumWindow(QMainWindow):
                d.exec_()
        
        
       +    @protected
       +    def do_decrypt(self, message_e, pubkey_e, encrypted_e, password):
       +        try:
       +            decrypted = self.wallet.decrypt_message(str(pubkey_e.text()), str(encrypted_e.toPlainText()), password)
       +            message_e.setText(decrypted)
       +        except Exception as e:
       +            self.show_message(str(e))
       +
       +
       +    def do_encrypt(self, message_e, pubkey_e, encrypted_e):
       +        message = unicode(message_e.toPlainText())
       +        message = message.encode('utf-8')
       +        try:
       +            encrypted = bitcoin.encrypt_message(message, str(pubkey_e.text()))
       +            encrypted_e.setText(encrypted)
       +        except Exception as e:
       +            self.show_message(str(e))
       +
       +
       +
       +    def encrypt_message(self, address = ''):
       +        d = QDialog(self)
       +        d.setModal(1)
       +        d.setWindowTitle(_('Encrypt/decrypt Message'))
       +        d.setMinimumSize(610, 490)
       +
       +        layout = QGridLayout(d)
       +
       +        message_e = QTextEdit()
       +        layout.addWidget(QLabel(_('Message')), 1, 0)
       +        layout.addWidget(message_e, 1, 1)
       +        layout.setRowStretch(2,3)
       +
       +        pubkey_e = QLineEdit()
       +        if address:
       +            pubkey = self.wallet.getpubkeys(address)[0]
       +            pubkey_e.setText(pubkey)
       +        layout.addWidget(QLabel(_('Public key')), 2, 0)
       +        layout.addWidget(pubkey_e, 2, 1)
       +
       +        encrypted_e = QTextEdit()
       +        layout.addWidget(QLabel(_('Encrypted')), 3, 0)
       +        layout.addWidget(encrypted_e, 3, 1)
       +        layout.setRowStretch(3,1)
       +
       +        hbox = QHBoxLayout()
       +        b = QPushButton(_("Encrypt"))
       +        b.clicked.connect(lambda: self.do_encrypt(message_e, pubkey_e, encrypted_e))
       +        hbox.addWidget(b)
       +
       +        b = QPushButton(_("Decrypt"))
       +        b.clicked.connect(lambda: self.do_decrypt(message_e, pubkey_e, encrypted_e))
       +        hbox.addWidget(b)
       +
       +        b = QPushButton(_("Close"))
       +        b.clicked.connect(d.accept)
       +        hbox.addWidget(b)
       +
       +        layout.addLayout(hbox, 4, 1)
       +        d.exec_()
       +
       +
            def question(self, msg):
                return QMessageBox.question(self, _('Message'), msg, QMessageBox.Yes | QMessageBox.No, QMessageBox.No) == QMessageBox.Yes
        
   DIR diff --git a/lib/bitcoin.py b/lib/bitcoin.py
       t@@ -303,6 +303,10 @@ def verify_message(address, signature, message):
                return False
        
        
       +def encrypt_message(message, pubkey):
       +    return EC_KEY.encrypt_message(message, pubkey.decode('hex'))
       +
       +
        def chunks(l, n):
            return [l[i:i+n] for i in xrange(0, len(l), n)]
        
   DIR diff --git a/lib/commands.py b/lib/commands.py
       t@@ -207,15 +207,11 @@ class Commands:
                return out
        
            def getpubkeys(self, addr):
       -        assert is_valid(addr) and self.wallet.is_mine(addr)
                out = { 'address':addr }
       -        account, sequence = self.wallet.get_address_index(addr)
       -        if account != -1:
       -            a = self.wallet.accounts[account]
       -            out['pubkeys'] = a.get_pubkeys( sequence )
       -
       +        out['pubkeys'] = self.wallet.getpubkeys(addr)
                return out
        
       +
            def getbalance(self, account= None):
                if account is None:
                    c, u = self.wallet.get_balance()
       t@@ -400,8 +396,10 @@ class Commands:
                else:
                    return "unknown transaction"
        
       +
            def encrypt(self, pubkey, message):
       -        return EC_KEY.encrypt_message(message, pubkey.decode('hex'))
       +        return bitcoin.encrypt_message(message, pubkey)
       +
        
            def decrypt(self, secret, message):
                ec = regenerate_key(secret)
   DIR diff --git a/lib/wallet.py b/lib/wallet.py
       t@@ -593,6 +593,14 @@ class NewWallet:
                raise Exception("Address not found", address)
        
        
       +    def getpubkeys(self, addr):
       +        assert is_valid(addr) and self.is_mine(addr)
       +        account, sequence = self.get_address_index(addr)
       +        if account != -1:
       +            a = self.accounts[account]
       +            return a.get_pubkeys( sequence )
       +
       +
            def get_roots(self, account):
                roots = []
                for a in account.split('&'):
       t@@ -771,6 +779,16 @@ class NewWallet:
                return key.sign_message(message, compressed, address)
        
        
       +
       +    def decrypt_message(self, pubkey, message, password):
       +        address = public_key_to_bc_address(pubkey.decode('hex'))
       +        keys = self.get_private_key(address, password)
       +        secret = keys[0]
       +        ec = regenerate_key(secret)
       +        decrypted = ec.decrypt_message(message)
       +        return decrypted[0]
       +
       +
            def change_gap_limit(self, value):
                if value >= self.gap_limit:
                    self.gap_limit = value