diff --git a/LeftPanel.qml b/LeftPanel.qml
index 5fc3ff33..fb4c7397 100644
--- a/LeftPanel.qml
+++ b/LeftPanel.qml
@@ -47,6 +47,7 @@ Rectangle {
     signal settingsClicked()
     signal addressBookClicked()
     signal miningClicked()
+    signal signClicked()
 
     function selectItem(pos) {
         menuColumn.previousButton.checked = false
@@ -57,6 +58,7 @@ Rectangle {
         else if(pos === "AddressBook") menuColumn.previousButton = addressBookButton
         else if(pos === "Mining") menuColumn.previousButton = miningButton
         else if(pos === "TxKey")  menuColumn.previousButton = txkeyButton
+        else if(pos === "Sign") menuColumn.previousButton = signButton
         else if(pos === "Settings") menuColumn.previousButton = settingsButton
 
         menuColumn.previousButton.checked = true
@@ -352,6 +354,20 @@ Rectangle {
                 height: 1
             }
             */
+            // ------------- Sign/verify tab ---------------
+            MenuButton {
+                id: signButton
+                anchors.left: parent.left
+                anchors.right: parent.right
+                text: qsTr("Sign/verify") + translationManager.emptyString
+                symbol: qsTr("S") + translationManager.emptyString
+                dotColor: "#AAFFBB"
+                onClicked: {
+                    parent.previousButton.checked = false
+                    parent.previousButton = signButton
+                    panel.signClicked()
+                }
+            }
             // ------------- Settings tab ---------------
             MenuButton {
                 id: settingsButton
diff --git a/MiddlePanel.qml b/MiddlePanel.qml
index 1d1b86e6..7080e338 100644
--- a/MiddlePanel.qml
+++ b/MiddlePanel.qml
@@ -47,6 +47,7 @@ Rectangle {
     property Receive receiveView: Receive { }
     property TxKey txkeyView: TxKey { }
     property History historyView: History { }
+    property Sign signView: Sign { }
     property Settings settingsView: Settings { }
 
 
@@ -117,6 +118,9 @@ Rectangle {
             }, State {
                 name: "AddressBook"
                 PropertyChanges { /*TODO*/ }
+            }, State {
+                name: "Sign"
+               PropertyChanges { target: root; currentView: signView }
             }, State {
                 name: "Settings"
                PropertyChanges { target: root; currentView: settingsView }
diff --git a/main.qml b/main.qml
index 6f5bdde4..9872409d 100644
--- a/main.qml
+++ b/main.qml
@@ -724,6 +724,7 @@ ApplicationWindow {
             onTxkeyClicked: middlePanel.state = "TxKey"
             onAddressBookClicked: middlePanel.state = "AddressBook"
             onMiningClicked: middlePanel.state = "Minning"
+            onSignClicked: middlePanel.state = "Sign"
             onSettingsClicked: middlePanel.state = "Settings"
         }
 
diff --git a/pages/Sign.qml b/pages/Sign.qml
new file mode 100644
index 00000000..58e07278
--- /dev/null
+++ b/pages/Sign.qml
@@ -0,0 +1,499 @@
+// Copyright (c) 2014-2015, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+//    conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+//    of conditions and the following disclaimer in the documentation and/or other
+//    materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+//    used to endorse or promote products derived from this software without specific
+//    prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import QtQuick 2.0
+import QtQuick.Controls 1.4
+import QtQuick.Controls.Styles 1.4
+import QtQuick.Layouts 1.1
+import QtQuick.Dialogs 1.2
+
+import "../components"
+import moneroComponents.Clipboard 1.0
+import moneroComponents.WalletManager 1.0
+
+Rectangle {
+    id: mainLayout
+
+    property int labelWidth: 120
+    property int editWidth: 400
+    property int lineEditFontSize: 12
+
+    color: "#F0EEEE"
+
+    Clipboard { id: clipboard }
+
+    function checkAddress(address, testnet) {
+      return walletManager.addressValid(address, testnet)
+    }
+
+    MessageDialog {
+        // dynamically change onclose handler
+        property var onCloseCallback
+        id: signatureVerificationMessage
+        standardButtons: StandardButton.Ok
+        onAccepted:  {
+            if (onCloseCallback) {
+                onCloseCallback()
+            }
+        }
+    }
+
+    function displayVerificationResult(result) {
+        if (result) {
+            signatureVerificationMessage.title = qsTr("Good signature") + translationManager.emptyString
+            signatureVerificationMessage.text  = qsTr("This is a good signature") + translationManager.emptyString
+            signatureVerificationMessage.icon = StandardIcon.Information
+        }
+        else {
+            signatureVerificationMessage.title = qsTr("Bad signature") + translationManager.emptyString
+            signatureVerificationMessage.text  = qsTr("This signature did not verify") + translationManager.emptyString
+            signatureVerificationMessage.icon = StandardIcon.Critical
+        }
+        signatureVerificationMessage.open()
+    }
+
+    // ================
+    // Sign a message
+    //   message:       [                   ] [SIGN]
+    //   [SELECT] file: [                   ] [SIGN]
+    //   signature:     [                   ]
+    // ================
+    // verify a message
+    //   address:       [                   ]
+    //   message:       [                   ] [VERIFY]
+    //   [SELECT] file: [                   ] [VERIFY]
+    //   signature:     [                   ]
+    // ================
+
+    // sign / verify
+    ColumnLayout {
+        anchors.margins: 10
+        anchors.left: parent.left
+        anchors.right: parent.right
+        anchors.top: parent.top
+        anchors.bottom: parent.bottom
+
+        spacing: 20
+
+        Rectangle {
+            anchors.fill: signBox
+            color: "#00000000"
+            border.width: 2
+            border.color: "#CCCCCC"
+            anchors.margins: -15
+        }
+
+        // sign
+        ColumnLayout {
+            id: signBox
+            anchors.margins: 40
+            anchors.left: parent.left
+            anchors.right: parent.right
+            anchors.top: parent.top
+
+            RowLayout {
+                ColumnLayout {
+                    spacing: 8
+                    Label {
+                        text: qsTr("Sign a message or file contents with your address:") + translationManager.emptyString
+                        fontSize: 18
+                    }
+                    Label {}
+                }
+            }
+
+            Label {
+                id: signMessageLabel
+                fontSize: 14
+                text: qsTr("Either message:") + translationManager.emptyString
+                width: mainLayout.labelWidth
+            }
+
+            RowLayout {
+                id: signMessageRow
+                anchors.topMargin: 17
+                anchors.left: parent.left
+                anchors.right: parent.right
+
+                LineEdit {
+                    id: signMessageLine
+                    anchors.left: parent.left
+                    anchors.right: signMessageButton.left
+                    fontSize: mainLayout.lineEditFontSize
+                    placeholderText: qsTr("Message to sign") + translationManager.emptyString;
+                    readOnly: false
+                    Layout.fillWidth: true
+                    onTextChanged: signSignatureLine.text = ""
+
+                    IconButton {
+                        imageSource: "../images/copyToClipboard.png"
+                        onClicked: {
+                            if (signMessageLine.text.length > 0) {
+                                clipboard.setText(signMessageLine.text)
+                            }
+                        }
+                    }
+                }
+
+                StandardButton {
+                    id: signMessageButton
+                    anchors.right: parent.right
+                    width: 60
+                    text: qsTr("SIGN") + translationManager.emptyString
+                    shadowReleasedColor: "#FF4304"
+                    shadowPressedColor: "#B32D00"
+                    releasedColor: "#FF6C3C"
+                    pressedColor: "#FF4304"
+                    enabled: true
+                    onClicked: {
+                      var signature = appWindow.currentWallet.signMessage(signMessageLine.text, false)
+                      signSignatureLine.text = signature
+                    }
+                }
+            }
+
+            Label {
+                id: signMessageFileLabel
+                fontSize: 14
+                text: qsTr("Or file:") + translationManager.emptyString
+                width: mainLayout.labelWidth
+            }
+
+            RowLayout {
+                id: signFileRow
+                anchors.topMargin: 17
+                anchors.left: parent.left
+		anchors.right: parent.right
+
+                FileDialog {
+                    id: signFileDialog
+                    title: "Please choose a file to sign"
+                    folder: "file://"
+                    nameFilters: [ "*"]
+
+                    onAccepted: {
+                        signFileLine.text = walletManager.urlToLocalPath(signFileDialog.fileUrl)
+                    }
+                }
+
+                StandardButton {
+                    id: loadFileToSignButton
+                    anchors.rightMargin: 17
+                    width: 60
+                    text: qsTr("SELECT") + translationManager.emptyString
+                    shadowReleasedColor: "#FF4304"
+                    shadowPressedColor: "#B32D00"
+                    releasedColor: "#FF6C3C"
+                    pressedColor: "#FF4304"
+                    enabled: true
+                    onClicked: {
+                      signFileDialog.open()
+                    }
+                }
+                LineEdit {
+                    id: signFileLine
+                    anchors.left: loadFileToSignButton.right
+                    anchors.right: signFileButton.left
+                    fontSize: mainLayout.lineEditFontSize
+                    placeholderText: qsTr("Filename with message to sign") + translationManager.emptyString;
+                    readOnly: false
+                    Layout.fillWidth: true
+                    onTextChanged: signSignatureLine.text = ""
+
+                    IconButton {
+                        imageSource: "../images/copyToClipboard.png"
+                        onClicked: {
+                            if (signFileLine.text.length > 0) {
+                                clipboard.setText(signFileLine.text)
+                            }
+                        }
+                    }
+                }
+
+                StandardButton {
+                    id: signFileButton
+                    anchors.right: parent.right
+                    width: 60
+                    text: qsTr("SIGN") + translationManager.emptyString
+                    shadowReleasedColor: "#FF4304"
+                    shadowPressedColor: "#B32D00"
+                    releasedColor: "#FF6C3C"
+                    pressedColor: "#FF4304"
+                    enabled: true
+                    onClicked: {
+                      var signature = appWindow.currentWallet.signMessage(signFileLine.text, true)
+                      signSignatureLine.text = signature
+                    }
+                }
+            }
+
+            RowLayout {
+                id: signSignatureRow
+                anchors.left: parent.left
+                anchors.right: parent.right
+                anchors.topMargin: 17
+
+                Label {
+                    id: signSignatureLabel
+                    fontSize: 14
+                    text: qsTr("Signature") + translationManager.emptyString
+                    width: mainLayout.labelWidth
+                }
+
+                LineEdit {
+                    id: signSignatureLine
+                    anchors.left: signSignatureLabel.right
+                    anchors.right: parent.right
+                    fontSize: mainLayout.lineEditFontSize
+                    placeholderText: qsTr("Signature") + translationManager.emptyString;
+                    readOnly: true
+                    Layout.fillWidth: true
+
+                    IconButton {
+                        imageSource: "../images/copyToClipboard.png"
+                        onClicked: {
+                            if (signSignatureLine.text.length > 0) {
+                                clipboard.setText(signSignatureLine.text)
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        Rectangle {
+            anchors.fill: verifyBox
+            color: "#00000000"
+            border.width: 2
+            border.color: "#CCCCCC"
+            anchors.margins: -15
+        }
+
+        // verify
+        ColumnLayout {
+            id: verifyBox
+            anchors.margins: 40
+            anchors.left: parent.left
+            anchors.right: parent.right
+            anchors.top: signBox.bottom
+
+            RowLayout {
+                ColumnLayout {
+                    spacing: 8
+                    Label {
+                        text: qsTr("Verify a message or file signature from an address:") + translationManager.emptyString
+                        fontSize: 18
+                    }
+                    Label {}
+                }
+            }
+
+            Label {
+                id: verifyMessageLabel
+                fontSize: 14
+                text: qsTr("Either message:") + translationManager.emptyString
+                width: mainLayout.labelWidth
+            }
+
+            RowLayout {
+                id: verifyMessageRow
+                anchors.topMargin: 17
+                anchors.left: parent.left
+                anchors.right: parent.right
+
+                LineEdit {
+                    id: verifyMessageLine
+                    anchors.left: parent.left
+                    anchors.right: verifyMessageButton.left
+                    fontSize: mainLayout.lineEditFontSize
+                    placeholderText: qsTr("Message to verify") + translationManager.emptyString;
+                    readOnly: false
+                    Layout.fillWidth: true
+
+                    IconButton {
+                        imageSource: "../images/copyToClipboard.png"
+                        onClicked: {
+                            if (verifyMessageLine.text.length > 0) {
+                                clipboard.setText(verifyMessageLine.text)
+                            }
+                        }
+                    }
+                }
+
+                StandardButton {
+                    id: verifyMessageButton
+                    anchors.right: parent.right
+                    width: 60
+                    text: qsTr("VERIFY") + translationManager.emptyString
+                    shadowReleasedColor: "#FF4304"
+                    shadowPressedColor: "#B32D00"
+                    releasedColor: "#FF6C3C"
+                    pressedColor: "#FF4304"
+                    enabled: true
+                    onClicked: {
+                      var verified = appWindow.currentWallet.verifySignedMessage(verifyMessageLine.text, verifyAddressLine.text, verifySignatureLine.text, false)
+                      displayVerificationResult(verified)
+                    }
+                }
+            }
+
+            Label {
+                id: verifyMessageFileLabel
+                fontSize: 14
+                text: qsTr("Or file:") + translationManager.emptyString
+                width: mainLayout.labelWidth
+            }
+
+            RowLayout {
+                id: verifyFileRow
+                anchors.topMargin: 17
+                anchors.left: parent.left
+		anchors.right: parent.right
+
+                FileDialog {
+                    id: verifyFileDialog
+                    title: "Please choose a file to verify"
+                    folder: "file://"
+                    nameFilters: [ "*"]
+
+                    onAccepted: {
+                        verifyFileLine.text = walletManager.urlToLocalPath(verifyFileDialog.fileUrl)
+                    }
+                }
+
+                StandardButton {
+                    id: loadFileToVerifyButton
+                    anchors.rightMargin: 17
+                    width: 60
+                    text: qsTr("SELECT") + translationManager.emptyString
+                    shadowReleasedColor: "#FF4304"
+                    shadowPressedColor: "#B32D00"
+                    releasedColor: "#FF6C3C"
+                    pressedColor: "#FF4304"
+                    enabled: true
+                    onClicked: {
+                      verifyFileDialog.open()
+                    }
+                }
+                LineEdit {
+                    id: verifyFileLine
+                    anchors.left: loadFileToVerifyButton.right
+                    anchors.right: verifyFileButton.left
+                    fontSize: mainLayout.lineEditFontSize
+                    placeholderText: qsTr("Filename with message to verify") + translationManager.emptyString;
+                    readOnly: false
+                    Layout.fillWidth: true
+
+                    IconButton {
+                        imageSource: "../images/copyToClipboard.png"
+                        onClicked: {
+                            if (verifyFileLine.text.length > 0) {
+                                clipboard.setText(verifyFileLine.text)
+                            }
+                        }
+                    }
+                }
+
+                StandardButton {
+                    id: verifyFileButton
+                    anchors.right: parent.right
+                    width: 60
+                    text: qsTr("VERIFY") + translationManager.emptyString
+                    shadowReleasedColor: "#FF4304"
+                    shadowPressedColor: "#B32D00"
+                    releasedColor: "#FF6C3C"
+                    pressedColor: "#FF4304"
+                    enabled: true
+                    onClicked: {
+                      var verified = appWindow.currentWallet.verifySignedMessage(verifyFileLine.text, verifyAddressLine.text, verifySignatureLine.text, true)
+                      displayVerificationResult(verified)
+                    }
+                }
+            }
+
+            Label {
+                id: verifyAddressLabel
+                fontSize: 14
+                width: mainLayout.labelWidth
+                textFormat: Text.RichText
+                text: qsTr("<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style>\
+                            Signing address <font size='2'>  ( Type in  or select from </font> <a href='#'>Address</a><font size='2'> book )</font>")
+                      + translationManager.emptyString
+
+        onLinkActivated: appWindow.showPageRequest("AddressBook")
+            }
+
+            LineEdit {
+                id: verifyAddressLine
+                anchors.left: parent.left
+                anchors.right: parent.right
+                anchors.top: verifyAddressLabel.bottom
+                anchors.topMargin: 5
+                placeholderText: "4..."
+                // validator: RegExpValidator { regExp: /[0-9A-Fa-f]{95}/g }
+            }
+
+            RowLayout {
+                id: verifySignatureRow
+                anchors.left: parent.left
+                anchors.right: parent.right
+                anchors.topMargin: 17
+
+                Label {
+                    id: verifySignatureLabel
+                    fontSize: 14
+                    text: qsTr("Signature") + translationManager.emptyString
+                    width: mainLayout.labelWidth
+                }
+
+                LineEdit {
+                    id: verifySignatureLine
+                    anchors.left: verifySignatureLabel.right
+                    anchors.right: parent.right
+                    fontSize: mainLayout.lineEditFontSize
+                    placeholderText: qsTr("Signature") + translationManager.emptyString;
+                    Layout.fillWidth: true
+
+                    IconButton {
+                        imageSource: "../images/copyToClipboard.png"
+                        onClicked: {
+                            if (verifySignatureLine.text.length > 0) {
+                                clipboard.setText(verifySignatureLine.text)
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    function onPageCompleted() {
+        console.log("Sign/verify page loaded");
+    }
+
+}
diff --git a/qml.qrc b/qml.qrc
index f54d2d0f..17873589 100644
--- a/qml.qrc
+++ b/qml.qrc
@@ -119,5 +119,6 @@
         <file>components/ProcessingSplash.qml</file>
         <file>components/DaemonProgress.qml</file>
         <file>components/StandardDialog.qml</file>
+        <file>pages/Sign.qml</file>
     </qresource>
 </RCC>
diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp
index d281c03a..18ded2c8 100644
--- a/src/libwalletqt/Wallet.cpp
+++ b/src/libwalletqt/Wallet.cpp
@@ -275,6 +275,78 @@ QString Wallet::getTxKey(const QString &txid) const
   return QString::fromStdString(m_walletImpl->getTxKey(txid.toStdString()));
 }
 
+QString Wallet::signMessage(const QString &message, bool filename) const
+{
+  if (filename) {
+    QFile file(message);
+    uchar *data = NULL;
+
+    try {
+      if (!file.open(QIODevice::ReadOnly))
+        return "";
+      quint64 size = file.size();
+      if (size == 0) {
+        file.close();
+        return QString::fromStdString(m_walletImpl->signMessage(std::string()));
+      }
+      data = file.map(0, size);
+      if (!data) {
+        file.close();
+        return "";
+      }
+      std::string signature = m_walletImpl->signMessage(std::string((const char*)data, size));
+      file.unmap(data);
+      file.close();
+      return QString::fromStdString(signature);
+    }
+    catch (const std::exception &e) {
+      if (data)
+        file.unmap(data);
+      file.close();
+      return "";
+    }
+  }
+  else {
+    return QString::fromStdString(m_walletImpl->signMessage(message.toStdString()));
+  }
+}
+
+bool Wallet::verifySignedMessage(const QString &message, const QString &address, const QString &signature, bool filename) const
+{
+  if (filename) {
+    QFile file(message);
+    uchar *data = NULL;
+
+    try {
+      if (!file.open(QIODevice::ReadOnly))
+        return false;
+      quint64 size = file.size();
+      if (size == 0) {
+        file.close();
+        return m_walletImpl->verifySignedMessage(std::string(), address.toStdString(), signature.toStdString());
+      }
+      data = file.map(0, size);
+      if (!data) {
+        file.close();
+        return false;
+      }
+      bool ret = m_walletImpl->verifySignedMessage(std::string((const char*)data, size), address.toStdString(), signature.toStdString());
+      file.unmap(data);
+      file.close();
+      return ret;
+    }
+    catch (const std::exception &e) {
+      if (data)
+        file.unmap(data);
+      file.close();
+      return false;
+    }
+  }
+  else {
+    return m_walletImpl->verifySignedMessage(message.toStdString(), address.toStdString(), signature.toStdString());
+  }
+}
+
 Wallet::Wallet(Bitmonero::Wallet *w, QObject *parent)
     : QObject(parent)
     , m_walletImpl(w)
diff --git a/src/libwalletqt/Wallet.h b/src/libwalletqt/Wallet.h
index 458dea90..102429d5 100644
--- a/src/libwalletqt/Wallet.h
+++ b/src/libwalletqt/Wallet.h
@@ -140,6 +140,12 @@ public:
     //! integrated address
     Q_INVOKABLE QString integratedAddress(const QString &paymentId) const;
 
+    //! signing a message
+    Q_INVOKABLE QString signMessage(const QString &message, bool filename = false) const;
+
+    //! verify a signed message
+    Q_INVOKABLE bool verifySignedMessage(const QString &message, const QString &address, const QString &signature, bool filename = false) const;
+
 
     //! saved payment id
     QString paymentId() const;