Browse Source

Brain wallet module in AZ.

cl-refactor
Gav Wood 10 years ago
parent
commit
8e1efe2847
  1. 71
      alethzero/BrainWallet.cpp
  2. 44
      alethzero/BrainWallet.h
  3. 136
      alethzero/BrainWallet.ui
  4. 3
      alethzero/CMakeLists.txt
  5. 1
      alethzero/Context.h
  6. 28
      alethzero/Main.ui
  7. 4
      alethzero/MainWin.cpp
  8. 2
      alethzero/MainWin.h
  9. 5041
      libdevcrypto/WordList.cpp
  10. 31
      libdevcrypto/WordList.h
  11. 33
      libethcore/KeyManager.cpp

71
alethzero/BrainWallet.cpp

@ -0,0 +1,71 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file BrainWallet.h
* @author Gav Wood <i@gavwood.com>
* @date 2015
*/
#include "BrainWallet.h"
#include <QMenu>
#include <QDialog>
#include <boost/random/random_device.hpp>
#include <boost/random/uniform_int_distribution.hpp>
#include <libdevcore/Log.h>
#include <libdevcrypto/WordList.h>
#include <libethcore/KeyManager.h>
#include <libethereum/Client.h>
#include "ui_BrainWallet.h"
using namespace std;
using namespace dev;
using namespace az;
using namespace eth;
BrainWallet::BrainWallet(MainFace* _m):
Plugin(_m, "BrainWallet")
{
QAction* a = new QAction("New Brain Wallet...", main());
QMenu* m = _m->findChild<QMenu*>("menuTools");
m->addSeparator();
m->addAction(a);
connect(a, SIGNAL(triggered()), SLOT(create()));
}
BrainWallet::~BrainWallet()
{
}
void BrainWallet::create()
{
QDialog d;
Ui_BrainWallet u;
u.setupUi(&d);
d.setWindowTitle("New Brain Wallet");
connect(u.generate, &QPushButton::clicked, [&](){
boost::random_device d;
boost::random::uniform_int_distribution<unsigned> pickWord(0, WordList.size() - 1);
QString t;
for (int i = 0; i < 13; ++i)
t += (t.size() ? " " : "") + QString::fromStdString(WordList[pickWord(d)]);
u.seed->setPlainText(t);
});
if (d.exec() == QDialog::Accepted)
{
main()->keyManager().importBrain(u.seed->toPlainText().trimmed().toStdString(), u.name->text().toStdString(), u.hint->toPlainText().toStdString());
main()->noteKeysChanged();
}
}

44
alethzero/BrainWallet.h

@ -0,0 +1,44 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file BrainWallet.h
* @author Gav Wood <i@gavwood.com>
* @date 2015
*/
#pragma once
#include "MainFace.h"
namespace dev
{
namespace az
{
class BrainWallet: public QObject, public Plugin
{
Q_OBJECT
public:
BrainWallet(MainFace* _m);
~BrainWallet();
private slots:
void create();
};
}
}

136
alethzero/BrainWallet.ui

@ -0,0 +1,136 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>BrainWallet</class>
<widget class="QDialog" name="BrainWallet">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>511</width>
<height>508</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;WARNING: Brain wallets, or human-entropic seeds, are practically and cryptographically insecure. They're a terrible idea for protecteding anything of value and this functionality is here only as a toy.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;That said, if you're intent on using one, make the phrase as long and random as you can. If you're sensible, you'll ask the internet for a list of words to memorise and use those. Write the phrase down on paper and bury it under an oak tree or something - if you forget it, you're screwed.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="name">
<property name="placeholderText">
<string>Please name of this account here e.g. My Brain Wallet</string>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="seed">
<property name="placeholderText">
<string>Write your seed phrase here. Make it long and random. Don't ever forget it. If you want it to have any chance at being secure, ask a machine to select 13 dictionary words at random.</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;You can leave a hint here if you want; don't rely on it or there's little point in it being a &lt;span style=&quot; font-style:italic;&quot;&gt;brain&lt;/span&gt; wallet.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="hint">
<property name="placeholderText">
<string>An optional hint for the text above.</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="generate">
<property name="text">
<string>&amp;Generate</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="cancel">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="create">
<property name="text">
<string>&amp;Create</string>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>create</sender>
<signal>clicked()</signal>
<receiver>BrainWallet</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>462</x>
<y>484</y>
</hint>
<hint type="destinationlabel">
<x>449</x>
<y>504</y>
</hint>
</hints>
</connection>
<connection>
<sender>cancel</sender>
<signal>clicked()</signal>
<receiver>BrainWallet</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>381</x>
<y>483</y>
</hint>
<hint type="destinationlabel">
<x>351</x>
<y>506</y>
</hint>
</hints>
</connection>
</connections>
</ui>

3
alethzero/CMakeLists.txt

@ -40,6 +40,7 @@ qt5_wrap_ui(ui_GasPricing.h GasPricing.ui)
# Extensions
qt5_wrap_ui(ui_AllAccounts.h AllAccounts.ui)
qt5_wrap_ui(ui_LogPanel.h LogPanel.ui)
qt5_wrap_ui(ui_BrainWallet.h BrainWallet.ui)
file(GLOB HEADERS "*.h")
@ -52,7 +53,7 @@ endif ()
# eth_add_executable is defined in cmake/EthExecutableHelper.cmake
eth_add_executable(${EXECUTABLE}
ICON alethzero
UI_RESOURCES alethzero.icns Main.ui Connect.ui Debugger.ui Transact.ui ExportState.ui GetPassword.ui GasPricing.ui AllAccounts.ui LogPanel.ui
UI_RESOURCES alethzero.icns Main.ui Connect.ui Debugger.ui Transact.ui ExportState.ui GetPassword.ui GasPricing.ui AllAccounts.ui LogPanel.ui BrainWallet.ui
WIN_RESOURCES alethzero.rc
)

1
alethzero/Context.h

@ -69,6 +69,7 @@ public:
virtual std::string render(dev::Address const& _a) const = 0;
virtual dev::Secret retrieveSecret(dev::Address const& _a) const = 0;
virtual dev::eth::KeyManager& keyManager() = 0;
virtual void noteKeysChanged() = 0;
virtual dev::u256 gasPrice() const = 0;
};

28
alethzero/Main.ui

@ -135,13 +135,13 @@
<height>24</height>
</rect>
</property>
<widget class="QMenu" name="menu_File">
<widget class="QMenu" name="menuFile">
<property name="title">
<string>&amp;File</string>
</property>
<addaction name="quit"/>
</widget>
<widget class="QMenu" name="menu_Network">
<widget class="QMenu" name="menuNetwork">
<property name="title">
<string>&amp;Network</string>
</property>
@ -153,7 +153,7 @@
<addaction name="connect"/>
<addaction name="hermitMode"/>
</widget>
<widget class="QMenu" name="menu_Tools">
<widget class="QMenu" name="menuTools">
<property name="title">
<string>&amp;Tools</string>
</property>
@ -175,13 +175,13 @@
<addaction name="separator"/>
<addaction name="exportState"/>
</widget>
<widget class="QMenu" name="menu_Help">
<widget class="QMenu" name="menuHelp">
<property name="title">
<string>&amp;Help</string>
</property>
<addaction name="about"/>
</widget>
<widget class="QMenu" name="menu_Debug">
<widget class="QMenu" name="menuSpecial">
<property name="title">
<string>&amp;Special</string>
</property>
@ -202,7 +202,7 @@
<addaction name="confirm"/>
<addaction name="rewindChain"/>
</widget>
<widget class="QMenu" name="menu_View">
<widget class="QMenu" name="menuView">
<property name="title">
<string>&amp;View</string>
</property>
@ -225,22 +225,22 @@
<addaction name="debugDumpStatePre"/>
<addaction name="dumpBlockState"/>
</widget>
<widget class="QMenu" name="menu_Config">
<widget class="QMenu" name="menuConfig">
<property name="title">
<string>&amp;Config</string>
</property>
<addaction name="gasPrices"/>
<addaction name="sentinel"/>
</widget>
<addaction name="menu_File"/>
<addaction name="menu_View"/>
<addaction name="menu_Network"/>
<addaction name="menu_Tools"/>
<addaction name="menuFile"/>
<addaction name="menuView"/>
<addaction name="menuNetwork"/>
<addaction name="menuTools"/>
<addaction name="menuWhispe"/>
<addaction name="menuDebug"/>
<addaction name="menu_Config"/>
<addaction name="menu_Help"/>
<addaction name="menu_Debug"/>
<addaction name="menuConfig"/>
<addaction name="menuHelp"/>
<addaction name="menuSpecial"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<widget class="QDockWidget" name="dockWidget_3">

4
alethzero/MainWin.cpp

@ -76,6 +76,7 @@
#include "ExportState.h"
#include "AllAccounts.h"
#include "LogPanel.h"
#include "BrainWallet.h"
#include "ui_Main.h"
#include "ui_GetPassword.h"
#include "ui_GasPricing.h"
@ -255,7 +256,7 @@ Main::Main(QWidget* _parent):
ethereum()->setDefault(LatestBlock);
m_vmSelectionGroup = new QActionGroup{ui->menu_Debug};
m_vmSelectionGroup = new QActionGroup{ui->menuDebug};
m_vmSelectionGroup->addAction(ui->vmInterpreter);
m_vmSelectionGroup->addAction(ui->vmJIT);
m_vmSelectionGroup->addAction(ui->vmSmart);
@ -294,6 +295,7 @@ Main::Main(QWidget* _parent):
loadPlugin<dev::az::AllAccounts>();
#endif
loadPlugin<dev::az::LogPanel>();
loadPlugin<dev::az::BrainWallet>();
}
Main::~Main()

2
alethzero/MainWin.h

@ -93,6 +93,7 @@ public:
dev::u256 gasPrice() const override;
dev::eth::KeyManager& keyManager() override { return m_keyManager; }
void noteKeysChanged() override { refreshBalances(); }
bool doConfirm();
dev::Secret retrieveSecret(dev::Address const& _address) const override;
@ -244,7 +245,6 @@ private:
void refreshAll();
void refreshPending();
void refreshAccounts();
void refreshBlockCount();
void refreshBalances();

5041
libdevcrypto/WordList.cpp

File diff suppressed because it is too large

31
libdevcrypto/WordList.h

@ -0,0 +1,31 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file WordList.h
* @author Gav Wood <i@gavwood.com>
* @date 2015
*/
#pragma once
#include "Common.h"
namespace dev
{
extern strings const WordList;
}

33
libethcore/KeyManager.cpp

@ -105,7 +105,7 @@ bool KeyManager::load(string const& _pass)
m_keyInfo[addr] = KeyInfo(h256(i[2]), string(i[3]), i.itemCount() > 4 ? string(i[4]) : "");
}
else
cwarn << "Missing key!";
cwarn << "Missing key:" << uuid << addr;
}
else
{
@ -137,10 +137,13 @@ bool KeyManager::load(string const& _pass)
Secret KeyManager::secret(Address const& _address, function<string()> const& _pass) const
{
auto it = m_addrLookup.find(_address);
if (it == m_addrLookup.end())
auto it = m_keyInfo.find(_address);
if (it == m_keyInfo.end())
return Secret();
return secret(it->second, _pass);
if (m_addrLookup.count(_address))
return secret(m_addrLookup.at(_address), _pass);
else
return brain(_pass());
}
Secret KeyManager::secret(h128 const& _uuid, function<string()> const& _pass) const
@ -190,10 +193,10 @@ h128 KeyManager::uuid(Address const& _a) const
Address KeyManager::address(h128 const& _uuid) const
{
for (auto const& i: m_addrLookup)
if (i.second == _uuid)
return i.first;
auto it = m_uuidLookup.find(_uuid);
if (it == m_uuidLookup.end())
return Address();
return it->second;
}
h128 KeyManager::import(Secret const& _s, string const& _accountName, string const& _pass, string const& _passwordHint)
@ -300,16 +303,15 @@ KeyPair KeyManager::presaleSecret(std::string const& _json, function<string(bool
Addresses KeyManager::accounts() const
{
Addresses ret;
ret.reserve(m_addrLookup.size());
for (auto const& i: m_addrLookup)
if (m_keyInfo.count(i.first) > 0)
ret.reserve(m_keyInfo.size());
for (auto const& i: m_keyInfo)
ret.push_back(i.first);
return ret;
}
bool KeyManager::hasAccount(const Address& _address) const
bool KeyManager::hasAccount(Address const& _address) const
{
return m_addrLookup.count(_address) && m_keyInfo.count(_address);
return m_keyInfo.count(_address);
}
string const& KeyManager::accountName(Address const& _address) const
@ -328,7 +330,10 @@ string const& KeyManager::passwordHint(Address const& _address) const
{
try
{
return m_passwordHint.at(m_keyInfo.at(_address).passHash);
auto& info = m_keyInfo.at(_address);
if (info.passwordHint.size())
return info.passwordHint;
return m_passwordHint.at(info.passHash);
}
catch (...)
{
@ -375,7 +380,7 @@ void KeyManager::write(SecureFixedHash<16> const& _key, string const& _keysFile)
{
h128 id = uuid(address);
auto const& ki = m_keyInfo.at(address);
s.appendList(4) << address << id << ki.passHash << ki.accountName << ki.passwordHint;
s.appendList(5) << address << id << ki.passHash << ki.accountName << ki.passwordHint;
}
s.appendList(m_passwordHint.size());
for (auto const& i: m_passwordHint)

Loading…
Cancel
Save