subtly
10 years ago
422 changed files with 26397 additions and 12712 deletions
@ -0,0 +1,123 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<ui version="4.0"> |
|||
<class>GetPassword</class> |
|||
<widget class="QDialog" name="GetPassword"> |
|||
<property name="geometry"> |
|||
<rect> |
|||
<x>0</x> |
|||
<y>0</y> |
|||
<width>400</width> |
|||
<height>187</height> |
|||
</rect> |
|||
</property> |
|||
<property name="windowTitle"> |
|||
<string>Enter Password</string> |
|||
</property> |
|||
<layout class="QVBoxLayout" name="verticalLayout"> |
|||
<item> |
|||
<spacer name="verticalSpacer_3"> |
|||
<property name="orientation"> |
|||
<enum>Qt::Vertical</enum> |
|||
</property> |
|||
<property name="sizeHint" stdset="0"> |
|||
<size> |
|||
<width>20</width> |
|||
<height>40</height> |
|||
</size> |
|||
</property> |
|||
</spacer> |
|||
</item> |
|||
<item> |
|||
<widget class="QLabel" name="label"> |
|||
<property name="text"> |
|||
<string/> |
|||
</property> |
|||
<property name="textFormat"> |
|||
<enum>Qt::RichText</enum> |
|||
</property> |
|||
<property name="wordWrap"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<spacer name="verticalSpacer_2"> |
|||
<property name="orientation"> |
|||
<enum>Qt::Vertical</enum> |
|||
</property> |
|||
<property name="sizeHint" stdset="0"> |
|||
<size> |
|||
<width>20</width> |
|||
<height>40</height> |
|||
</size> |
|||
</property> |
|||
</spacer> |
|||
</item> |
|||
<item> |
|||
<widget class="QLineEdit" name="entry"> |
|||
<property name="echoMode"> |
|||
<enum>QLineEdit::Password</enum> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<spacer name="verticalSpacer"> |
|||
<property name="orientation"> |
|||
<enum>Qt::Vertical</enum> |
|||
</property> |
|||
<property name="sizeHint" stdset="0"> |
|||
<size> |
|||
<width>20</width> |
|||
<height>40</height> |
|||
</size> |
|||
</property> |
|||
</spacer> |
|||
</item> |
|||
<item> |
|||
<widget class="QDialogButtonBox" name="buttonBox"> |
|||
<property name="orientation"> |
|||
<enum>Qt::Horizontal</enum> |
|||
</property> |
|||
<property name="standardButtons"> |
|||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
</layout> |
|||
</widget> |
|||
<resources/> |
|||
<connections> |
|||
<connection> |
|||
<sender>buttonBox</sender> |
|||
<signal>accepted()</signal> |
|||
<receiver>GetPassword</receiver> |
|||
<slot>accept()</slot> |
|||
<hints> |
|||
<hint type="sourcelabel"> |
|||
<x>248</x> |
|||
<y>254</y> |
|||
</hint> |
|||
<hint type="destinationlabel"> |
|||
<x>157</x> |
|||
<y>274</y> |
|||
</hint> |
|||
</hints> |
|||
</connection> |
|||
<connection> |
|||
<sender>buttonBox</sender> |
|||
<signal>rejected()</signal> |
|||
<receiver>GetPassword</receiver> |
|||
<slot>reject()</slot> |
|||
<hints> |
|||
<hint type="sourcelabel"> |
|||
<x>316</x> |
|||
<y>260</y> |
|||
</hint> |
|||
<hint type="destinationlabel"> |
|||
<x>286</x> |
|||
<y>274</y> |
|||
</hint> |
|||
</hints> |
|||
</connection> |
|||
</connections> |
|||
</ui> |
@ -0,0 +1,13 @@ |
|||
{ |
|||
"title": "Ethereum", |
|||
"icon": "appdmg_icon.icns", |
|||
"background": "appdmg_background.png", |
|||
"icon-size": 80, |
|||
"contents": [ |
|||
{ "x": 600, "y": 170, "type": "link", "path": "/Applications" }, |
|||
{ "x": 150, "y": 90, "type": "file", "path": "${ETH_ALETHZERO_APP}" }, |
|||
{ "x": 150, "y": 260, "type": "file", "path": "${ETH_MIX_APP}" } |
|||
] |
|||
} |
|||
|
|||
|
After Width: | Height: | Size: 171 KiB |
@ -0,0 +1,322 @@ |
|||
# - Find the Windows SDK aka Platform SDK |
|||
# |
|||
# Relevant Wikipedia article: http://en.wikipedia.org/wiki/Microsoft_Windows_SDK |
|||
# |
|||
# Variables: |
|||
# WINDOWSSDK_FOUND - if any version of the windows or platform SDK was found that is usable with the current version of visual studio |
|||
# WINDOWSSDK_LATEST_DIR |
|||
# WINDOWSSDK_LATEST_NAME |
|||
# WINDOWSSDK_FOUND_PREFERENCE - if we found an entry indicating a "preferred" SDK listed for this visual studio version |
|||
# WINDOWSSDK_PREFERRED_DIR |
|||
# WINDOWSSDK_PREFERRED_NAME |
|||
# |
|||
# WINDOWSSDK_DIRS - contains no duplicates, ordered most recent first. |
|||
# WINDOWSSDK_PREFERRED_FIRST_DIRS - contains no duplicates, ordered with preferred first, followed by the rest in descending recency |
|||
# |
|||
# Functions: |
|||
# windowssdk_name_lookup(<directory> <output variable>) - Find the name corresponding with the SDK directory you pass in, or |
|||
# NOTFOUND if not recognized. Your directory must be one of WINDOWSSDK_DIRS for this to work. |
|||
# |
|||
# get_windowssdk_from_component(<file or dir> <output variable>) - Given a library or include dir, |
|||
# find the Windows SDK root dir corresponding to it, or NOTFOUND if unrecognized. |
|||
# |
|||
# get_windowssdk_library_dirs(<directory> <output variable>) - Find the architecture-appropriate |
|||
# library directories corresponding to the SDK directory you pass in (or NOTFOUND if none) |
|||
# |
|||
# get_windowssdk_include_dirs(<directory> <output variable>) - Find the |
|||
# include directories corresponding to the SDK directory you pass in (or NOTFOUND if none) |
|||
# |
|||
# Requires these CMake modules: |
|||
# FindPackageHandleStandardArgs (known included with CMake >=2.6.2) |
|||
# |
|||
# Original Author: |
|||
# 2012 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net> |
|||
# http://academic.cleardefinition.com |
|||
# Iowa State University HCI Graduate Program/VRAC |
|||
# |
|||
# Copyright Iowa State University 2012. |
|||
# Distributed under the Boost Software License, Version 1.0. |
|||
# (See accompanying file LICENSE_1_0.txt or copy at |
|||
# http://www.boost.org/LICENSE_1_0.txt) |
|||
|
|||
set(_preferred_sdk_dirs) |
|||
set(_win_sdk_dirs) |
|||
set(_win_sdk_versanddirs) |
|||
if(MSVC_VERSION GREATER 1310) # Newer than VS .NET/VS Toolkit 2003 |
|||
|
|||
# Environment variable for SDK dir |
|||
if(EXISTS "$ENV{WindowsSDKDir}" AND (NOT "$ENV{WindowsSDKDir}" STREQUAL "")) |
|||
message(STATUS "Got $ENV{WindowsSDKDir} - Windows/Platform SDK directories: ${_win_sdk_dirs}") |
|||
list(APPEND _preferred_sdk_dirs "$ENV{WindowsSDKDir}") |
|||
endif() |
|||
|
|||
if(MSVC_VERSION LESS 1600) |
|||
# Per-user current Windows SDK for VS2005/2008 |
|||
get_filename_component(_sdkdir |
|||
"[HKEY_CURRENT_USER\\Software\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]" |
|||
ABSOLUTE) |
|||
if(EXISTS "${_sdkdir}") |
|||
list(APPEND _preferred_sdk_dirs "${_sdkdir}") |
|||
endif() |
|||
|
|||
# System-wide current Windows SDK for VS2005/2008 |
|||
get_filename_component(_sdkdir |
|||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]" |
|||
ABSOLUTE) |
|||
if(EXISTS "${_sdkdir}") |
|||
list(APPEND _preferred_sdk_dirs "${_sdkdir}") |
|||
endif() |
|||
endif() |
|||
|
|||
if(MSVC_VERSION LESS 1700) |
|||
# VC 10 and older has broad target support |
|||
set(_winsdk_vistaonly) |
|||
else() |
|||
# VC 11 by default targets Vista and later only, so we can add a few more SDKs that (might?) only work on vista+ |
|||
if("${CMAKE_VS_PLATFORM_TOOLSET}" MATCHES "_xp") |
|||
# This is the XP-compatible v110 toolset |
|||
elseif("${CMAKE_VS_PLATFORM_TOOLSET}" STREQUAL "v100") |
|||
# This is the VS2010 toolset |
|||
else() |
|||
if(NOT WINDOWSSDK_FOUND AND NOT WindowsSDK_FIND_QUIETLY) |
|||
message(STATUS "FindWindowsSDK: Detected Visual Studio 2012 or newer, not using the _xp toolset variant: including SDK versions that drop XP support in search!") |
|||
endif() |
|||
# These versions have no XP (and possibly Vista pre-SP1) support |
|||
set(_winsdk_vistaonly) |
|||
if(NOT MSVC_VERSION LESS 1800) |
|||
list(APPEND _winsdk_vistaonly |
|||
# Windows Software Development Kit (SDK) for Windows 8.1 |
|||
# http://msdn.microsoft.com/en-gb/windows/desktop/bg162891 |
|||
v8.1) |
|||
endif() |
|||
list(APPEND _winsdk_vistaonly |
|||
# Included in Visual Studio 2012 |
|||
v8.0A |
|||
|
|||
# Microsoft Windows SDK for Windows 8 and .NET Framework 4.5 |
|||
# This is the first version to also include the DirectX SDK |
|||
# http://msdn.microsoft.com/en-US/windows/desktop/hh852363.aspx |
|||
v8.0 |
|||
|
|||
# Microsoft Windows SDK for Windows 7 and .NET Framework 4 |
|||
# http://www.microsoft.com/downloads/en/details.aspx?FamilyID=6b6c21d2-2006-4afa-9702-529fa782d63b |
|||
v7.1 |
|||
) |
|||
endif() |
|||
endif() |
|||
foreach(_winsdkver |
|||
${_winsdk_vistaonly} |
|||
|
|||
# Included in Visual Studio 2013 |
|||
# Includes the v120_xp toolset |
|||
v8.1A |
|||
|
|||
# Included with VS 2012 Update 1 or later |
|||
# Introduces v110_xp toolset |
|||
v7.1A |
|||
|
|||
# Included with VS 2010 |
|||
v7.0A |
|||
|
|||
# Windows SDK for Windows 7 and .NET Framework 3.5 SP1 |
|||
# Works with VC9 |
|||
#http://www.microsoft.com/en-us/download/details.aspx?id=18950 |
|||
v7.0 |
|||
|
|||
# Two versions call themselves "v6.1": |
|||
# Older: |
|||
# Windows Vista Update & .NET 3.0 SDK |
|||
# http://www.microsoft.com/en-us/download/details.aspx?id=14477 |
|||
|
|||
# Newer: |
|||
# Windows Server 2008 & .NET 3.5 SDK |
|||
# may have broken VS9SP1? they recommend v7.0 instead, or a KB... |
|||
# http://www.microsoft.com/en-us/download/details.aspx?id=24826 |
|||
v6.1 |
|||
|
|||
# Included in VS 2008 |
|||
v6.0A |
|||
|
|||
# Microsoft Windows Software Development Kit for Windows Vista and .NET Framework 3.0 Runtime Components |
|||
# http://blogs.msdn.com/b/stanley/archive/2006/11/08/microsoft-windows-software-development-kit-for-windows-vista-and-net-framework-3-0-runtime-components.aspx |
|||
v6.0) |
|||
|
|||
get_filename_component(_sdkdir |
|||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\${_winsdkver};InstallationFolder]" |
|||
ABSOLUTE) |
|||
if(EXISTS "${_sdkdir}") |
|||
list(APPEND _win_sdk_dirs "${_sdkdir}") |
|||
list(APPEND |
|||
_win_sdk_versanddirs |
|||
"Windows SDK ${_winsdkver}" |
|||
"${_sdkdir}") |
|||
endif() |
|||
endforeach() |
|||
endif() |
|||
if(MSVC_VERSION GREATER 1200) |
|||
foreach(_platformsdkinfo |
|||
"D2FF9F89-8AA2-4373-8A31-C838BF4DBBE1_Microsoft Platform SDK for Windows Server 2003 R2" |
|||
"8F9E5EF3-A9A5-491B-A889-C58EFFECE8B3_Microsoft Platform SDK for Windows Server 2003 SP1") |
|||
string(SUBSTRING "${_platformsdkinfo}" 0 36 _platformsdkguid) |
|||
string(SUBSTRING "${_platformsdkinfo}" 37 -1 _platformsdkname) |
|||
foreach(HIVE HKEY_LOCAL_MACHINE HKEY_CURRENT_USER) |
|||
get_filename_component(_sdkdir |
|||
"[${HIVE}\\SOFTWARE\\Microsoft\\MicrosoftSDK\\InstalledSDKs\\${_platformsdkguid};Install Dir]" |
|||
ABSOLUTE) |
|||
if(EXISTS "${_sdkdir}") |
|||
list(APPEND _win_sdk_dirs "${_sdkdir}") |
|||
list(APPEND _win_sdk_versanddirs "${_platformsdkname}" "${_sdkdir}") |
|||
endif() |
|||
endforeach() |
|||
endforeach() |
|||
endif() |
|||
|
|||
set(_win_sdk_versanddirs |
|||
"${_win_sdk_versanddirs}" |
|||
CACHE |
|||
INTERNAL |
|||
"mapping between windows sdk version locations and names" |
|||
FORCE) |
|||
|
|||
function(windowssdk_name_lookup _dir _outvar) |
|||
list(FIND _win_sdk_versanddirs "${_dir}" _diridx) |
|||
math(EXPR _nameidx "${_diridx} - 1") |
|||
if(${_nameidx} GREATER -1) |
|||
list(GET _win_sdk_versanddirs ${_nameidx} _sdkname) |
|||
else() |
|||
set(_sdkname "NOTFOUND") |
|||
endif() |
|||
set(${_outvar} "${_sdkname}" PARENT_SCOPE) |
|||
endfunction() |
|||
|
|||
if(_win_sdk_dirs) |
|||
# Remove duplicates |
|||
list(REMOVE_DUPLICATES _win_sdk_dirs) |
|||
list(GET _win_sdk_dirs 0 WINDOWSSDK_LATEST_DIR) |
|||
windowssdk_name_lookup("${WINDOWSSDK_LATEST_DIR}" |
|||
WINDOWSSDK_LATEST_NAME) |
|||
set(WINDOWSSDK_DIRS ${_win_sdk_dirs}) |
|||
endif() |
|||
if(_preferred_sdk_dirs) |
|||
list(GET _preferred_sdk_dirs 0 WINDOWSSDK_PREFERRED_DIR) |
|||
windowssdk_name_lookup("${WINDOWSSDK_LATEST_DIR}" |
|||
WINDOWSSDK_PREFERRED_NAME) |
|||
set(WINDOWSSDK_PREFERRED_FIRST_DIRS |
|||
${_preferred_sdk_dirs} |
|||
${_win_sdk_dirs}) |
|||
list(REMOVE_DUPLICATES WINDOWSSDK_PREFERRED_FIRST_DIRS) |
|||
set(WINDOWSSDK_FOUND_PREFERENCE ON) |
|||
|
|||
# In case a preferred dir was found that isn't found otherwise |
|||
#set(WINDOWSSDK_DIRS ${WINDOWSSDK_DIRS} ${WINDOWSSDK_PREFERRED_FIRST_DIRS}) |
|||
#list(REMOVE_DUPLICATES WINDOWSSDK_DIRS) |
|||
else() |
|||
set(WINDOWSSDK_PREFERRED_DIR "${WINDOWSSDK_LATEST_DIR}") |
|||
set(WINDOWSSDK_PREFERRED_NAME "${WINDOWSSDK_LATEST_NAME}") |
|||
set(WINDOWSSDK_PREFERRED_FIRST_DIRS ${WINDOWSSDK_DIRS}) |
|||
set(WINDOWSSDK_FOUND_PREFERENCE OFF) |
|||
endif() |
|||
|
|||
include(FindPackageHandleStandardArgs) |
|||
find_package_handle_standard_args(WindowsSDK |
|||
"No compatible version of the Windows SDK or Platform SDK found." |
|||
WINDOWSSDK_DIRS) |
|||
|
|||
if(WINDOWSSDK_FOUND) |
|||
if(NOT _winsdk_remembered_dirs STREQUAL WINDOWSSDK_DIRS) |
|||
set(_winsdk_remembered_dirs |
|||
"${WINDOWSSDK_DIRS}" |
|||
CACHE |
|||
INTERNAL |
|||
"" |
|||
FORCE) |
|||
if(NOT WindowsSDK_FIND_QUIETLY) |
|||
foreach(_sdkdir ${WINDOWSSDK_DIRS}) |
|||
windowssdk_name_lookup("${_sdkdir}" _sdkname) |
|||
message(STATUS " - Found ${_sdkname} at ${_sdkdir}") |
|||
endforeach() |
|||
endif() |
|||
endif() |
|||
|
|||
# Internal: Architecture-appropriate library directory names. |
|||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "ARM") |
|||
set(_winsdk_archbare /arm) # what the architecture used to be called in oldest SDKs |
|||
set(_winsdk_arch arm) # what the architecture used to be called |
|||
set(_winsdk_arch8 arm) # what the WDK for Win8+ calls this architecture |
|||
else() |
|||
if(CMAKE_SIZEOF_VOID_P MATCHES "8") |
|||
set(_winsdk_archbare /x64) # what the architecture used to be called in oldest SDKs |
|||
set(_winsdk_arch amd64) # what the architecture used to be called |
|||
set(_winsdk_arch8 x64) # what the WDK for Win8+ calls this architecture |
|||
else() |
|||
set(_winsdk_archbare ) # what the architecture used to be called in oldest SDKs |
|||
set(_winsdk_arch i386) # what the architecture used to be called |
|||
set(_winsdk_arch8 x86) # what the WDK for Win8+ calls this architecture |
|||
endif() |
|||
endif() |
|||
|
|||
function(get_windowssdk_from_component _component _var) |
|||
get_filename_component(_component "${_component}" ABSOLUTE) |
|||
file(TO_CMAKE_PATH "${_component}" _component) |
|||
foreach(_sdkdir ${WINDOWSSDK_DIRS}) |
|||
get_filename_component(_sdkdir "${_sdkdir}" ABSOLUTE) |
|||
string(LENGTH "${_sdkdir}" _sdklen) |
|||
file(RELATIVE_PATH _rel "${_sdkdir}" "${_component}") |
|||
# If we don't have any "parent directory" items... |
|||
if(NOT "${_rel}" MATCHES "[.][.]") |
|||
set(${_var} "${_sdkdir}" PARENT_SCOPE) |
|||
return() |
|||
endif() |
|||
endforeach() |
|||
# Fail. |
|||
set(${_var} "NOTFOUND" PARENT_SCOPE) |
|||
endfunction() |
|||
function(get_windowssdk_library_dirs _winsdk_dir _var) |
|||
set(_result) |
|||
foreach(_suffix |
|||
"lib${_winsdk_archbare}" # SDKs like 7.1A |
|||
"lib/w2k/${_winsdk_arch}" # Win2k min requirement |
|||
"lib/wxp/${_winsdk_arch}" # WinXP min requirement |
|||
"lib/wnet/${_winsdk_arch}" # Win Server 2003 min requirement |
|||
"lib/wlh/${_winsdk_arch}" # Win Vista ("Long Horn") min requirement |
|||
"lib/wlh/um/${_winsdk_arch8}" # Win Vista ("Long Horn") min requirement |
|||
"lib/win7/${_winsdk_arch}" # Win 7 min requirement |
|||
"lib/win7/um/${_winsdk_arch8}" # Win 7 min requirement |
|||
"lib/win8/um/${_winsdk_arch8}" # Win 8 min requirement |
|||
"lib/win8/km/${_winsdk_arch8}" # Win 8 min requirement |
|||
"lib/winv6.3/km/${_winsdk_arch8}" # Win 8.1 min requirement |
|||
"lib/winv6.3/um/${_winsdk_arch8}" # Win 8.1 min requirement |
|||
) |
|||
# Check to see if a library actually exists here. |
|||
file(GLOB _libs "${_winsdk_dir}/${_suffix}/*.lib") |
|||
if(_libs) |
|||
list(APPEND _result "${_winsdk_dir}/${_suffix}") |
|||
endif() |
|||
endforeach() |
|||
if(NOT _result) |
|||
set(_result NOTFOUND) |
|||
endif() |
|||
set(${_var} ${_result} PARENT_SCOPE) |
|||
endfunction() |
|||
function(get_windowssdk_include_dirs _winsdk_dir _var) |
|||
set(_result) |
|||
foreach(_suffix |
|||
"Include" |
|||
"Include/shared" |
|||
"Include/um" |
|||
"Include/winrt" |
|||
"Include/km" |
|||
"Include/wdf" |
|||
) |
|||
# Check to see if a header file actually exists here. |
|||
file(GLOB _headers "${_winsdk_dir}/${_suffix}/*.h") |
|||
if(_headers) |
|||
list(APPEND _result "${_winsdk_dir}/${_suffix}") |
|||
endif() |
|||
endforeach() |
|||
if(NOT _result) |
|||
set(_result NOTFOUND) |
|||
endif() |
|||
set(${_var} ${_result} PARENT_SCOPE) |
|||
endfunction() |
|||
endif() |
@ -0,0 +1,17 @@ |
|||
|
|||
if (NOT APP_DMG_EXE) |
|||
message(FATAL_ERROR "Please install appdmg! https://github.com/LinusU/node-appdmg") |
|||
endif() |
|||
|
|||
string(REPLACE "/Contents/MacOS" "" ETH_MIX_APP "${ETH_MIX_APP}") |
|||
string(REPLACE "/Contents/MacOS" "" ETH_ALETHZERO_APP "${ETH_ALETHZERO_APP}") |
|||
|
|||
set(OUTFILE "${ETH_BUILD_DIR}/appdmg.json") |
|||
|
|||
configure_file(${APP_DMG_FILE} ${OUTFILE}) |
|||
|
|||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${APP_DMG_ICON}" "${ETH_BUILD_DIR}/appdmg_icon.icns") |
|||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${APP_DMG_BACKGROUND}" "${ETH_BUILD_DIR}/appdmg_background.png") |
|||
execute_process(COMMAND ${CMAKE_COMMAND} -E remove "${ETH_BUILD_DIR}/Ethereum.dmg") |
|||
execute_process(COMMAND ${APP_DMG_EXE} ${OUTFILE} "${ETH_BUILD_DIR}/Ethereum.dmg") |
|||
|
File diff suppressed because it is too large
@ -0,0 +1,33 @@ |
|||
cmake_policy(SET CMP0015 NEW) |
|||
set(CMAKE_AUTOMOC OFF) |
|||
|
|||
aux_source_directory(. SRC_LIST) |
|||
|
|||
include_directories(BEFORE ..) |
|||
include_directories(${Boost_INCLUDE_DIRS}) |
|||
include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) |
|||
|
|||
if (JSCONSOLE) |
|||
include_directories(${V8_INCLUDE_DIRS}) |
|||
endif() |
|||
|
|||
set(EXECUTABLE ethkey) |
|||
|
|||
file(GLOB HEADERS "*.h") |
|||
|
|||
add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) |
|||
|
|||
add_dependencies(${EXECUTABLE} BuildInfo.h) |
|||
|
|||
target_link_libraries(${EXECUTABLE} devcrypto) |
|||
target_link_libraries(${EXECUTABLE} ethcore) |
|||
|
|||
if (DEFINED WIN32 AND NOT DEFINED CMAKE_COMPILER_IS_MINGW) |
|||
eth_copy_dlls("${EXECUTABLE}" MHD_DLLS) |
|||
endif() |
|||
|
|||
if (APPLE) |
|||
install(TARGETS ${EXECUTABLE} DESTINATION bin) |
|||
else() |
|||
eth_install_executable(${EXECUTABLE}) |
|||
endif() |
@ -0,0 +1,431 @@ |
|||
#pragma once |
|||
|
|||
/*
|
|||
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 KeyAux.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
* CLI module for key management. |
|||
*/ |
|||
|
|||
#include <thread> |
|||
#include <chrono> |
|||
#include <fstream> |
|||
#include <iostream> |
|||
#include <boost/algorithm/string.hpp> |
|||
#include <boost/algorithm/string/trim_all.hpp> |
|||
#include <libdevcore/SHA3.h> |
|||
#include <libdevcore/FileSystem.h> |
|||
#include <libethcore/KeyManager.h> |
|||
#include <libethcore/ICAP.h> |
|||
#include "BuildInfo.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
using namespace boost::algorithm; |
|||
|
|||
#undef RETURN |
|||
|
|||
class BadArgument: public Exception {}; |
|||
|
|||
string getAccountPassword(KeyManager& keyManager, Address const& a) |
|||
{ |
|||
return getPassword("Enter password for address " + keyManager.accountDetails()[a].first + " (" + a.abridged() + "; hint:" + keyManager.accountDetails()[a].second + "): "); |
|||
} |
|||
|
|||
string createPassword(std::string const& _prompt) |
|||
{ |
|||
string ret; |
|||
while (true) |
|||
{ |
|||
ret = getPassword(_prompt); |
|||
string confirm = getPassword("Please confirm the password by entering it again: "); |
|||
if (ret == confirm) |
|||
break; |
|||
cout << "Passwords were different. Try again." << endl; |
|||
} |
|||
return ret; |
|||
// cout << "Enter a hint to help you remember this password: " << flush;
|
|||
// cin >> hint;
|
|||
// return make_pair(ret, hint);
|
|||
} |
|||
|
|||
pair<string, string> createPassword(KeyManager& _keyManager, std::string const& _prompt, std::string const& _pass = std::string(), std::string const& _hint = std::string()) |
|||
{ |
|||
string pass = _pass; |
|||
if (pass.empty()) |
|||
while (true) |
|||
{ |
|||
pass = getPassword(_prompt); |
|||
string confirm = getPassword("Please confirm the password by entering it again: "); |
|||
if (pass == confirm) |
|||
break; |
|||
cout << "Passwords were different. Try again." << endl; |
|||
} |
|||
string hint = _hint; |
|||
if (hint.empty() && !pass.empty() && !_keyManager.haveHint(pass)) |
|||
{ |
|||
cout << "Enter a hint to help you remember this password: " << flush; |
|||
getline(cin, hint); |
|||
} |
|||
return make_pair(pass, hint); |
|||
} |
|||
|
|||
class KeyCLI |
|||
{ |
|||
public: |
|||
enum class OperationMode |
|||
{ |
|||
None, |
|||
ListBare, |
|||
NewBare, |
|||
ImportBare, |
|||
ExportBare, |
|||
RecodeBare, |
|||
KillBare, |
|||
InspectBare, |
|||
CreateWallet, |
|||
List, |
|||
New, |
|||
Import, |
|||
Export, |
|||
Recode, |
|||
Kill |
|||
}; |
|||
|
|||
KeyCLI(OperationMode _mode = OperationMode::None): m_mode(_mode) {} |
|||
|
|||
bool interpretOption(int& i, int argc, char** argv) |
|||
{ |
|||
string arg = argv[i]; |
|||
if (arg == "--wallet-path" && i + 1 < argc) |
|||
m_walletPath = argv[++i]; |
|||
else if (arg == "--secrets-path" && i + 1 < argc) |
|||
m_secretsPath = argv[++i]; |
|||
else if ((arg == "-m" || arg == "--master") && i + 1 < argc) |
|||
m_masterPassword = argv[++i]; |
|||
else if (arg == "--unlock" && i + 1 < argc) |
|||
m_unlocks.push_back(argv[++i]); |
|||
else if (arg == "--lock" && i + 1 < argc) |
|||
m_lock = argv[++i]; |
|||
else if (arg == "--kdf" && i + 1 < argc) |
|||
m_kdf = argv[++i]; |
|||
else if (arg == "--kdf-param" && i + 2 < argc) |
|||
{ |
|||
auto n = argv[++i]; |
|||
auto v = argv[++i]; |
|||
m_kdfParams[n] = v; |
|||
} |
|||
else if (arg == "--new-bare") |
|||
m_mode = OperationMode::NewBare; |
|||
else if (arg == "--import-bare") |
|||
m_mode = OperationMode::ImportBare; |
|||
else if (arg == "--list-bare") |
|||
m_mode = OperationMode::ListBare; |
|||
else if (arg == "--export-bare") |
|||
m_mode = OperationMode::ExportBare; |
|||
else if (arg == "--inspect-bare") |
|||
m_mode = OperationMode::InspectBare; |
|||
else if (arg == "--recode-bare") |
|||
m_mode = OperationMode::RecodeBare; |
|||
else if (arg == "--kill-bare") |
|||
m_mode = OperationMode::KillBare; |
|||
else if (arg == "--create-wallet") |
|||
m_mode = OperationMode::CreateWallet; |
|||
else if (arg == "--list") |
|||
m_mode = OperationMode::List; |
|||
else if ((arg == "-n" || arg == "--new") && i + 1 < argc) |
|||
{ |
|||
m_mode = OperationMode::New; |
|||
m_name = argv[++i]; |
|||
} |
|||
else if ((arg == "-i" || arg == "--import") && i + 2 < argc) |
|||
{ |
|||
m_mode = OperationMode::Import; |
|||
m_inputs = strings(1, argv[++i]); |
|||
m_name = argv[++i]; |
|||
} |
|||
else if (arg == "--export") |
|||
m_mode = OperationMode::Export; |
|||
else if (arg == "--recode") |
|||
m_mode = OperationMode::Recode; |
|||
else if (arg == "--no-icap") |
|||
m_icap = false; |
|||
else if (m_mode == OperationMode::ImportBare || m_mode == OperationMode::InspectBare || m_mode == OperationMode::KillBare || m_mode == OperationMode::Recode || m_mode == OperationMode::Export || m_mode == OperationMode::RecodeBare || m_mode == OperationMode::ExportBare) |
|||
m_inputs.push_back(arg); |
|||
else |
|||
return false; |
|||
return true; |
|||
} |
|||
|
|||
KeyPair makeKey() const |
|||
{ |
|||
KeyPair k(Secret::random()); |
|||
while (m_icap && k.address()[0]) |
|||
k = KeyPair(sha3(k.secret())); |
|||
return k; |
|||
} |
|||
|
|||
void execute() |
|||
{ |
|||
if (m_mode == OperationMode::CreateWallet) |
|||
{ |
|||
KeyManager wallet(m_walletPath, m_secretsPath); |
|||
if (m_masterPassword.empty()) |
|||
m_masterPassword = createPassword("Please enter a MASTER password to protect your key store (make it strong!): "); |
|||
if (m_masterPassword.empty()) |
|||
cerr << "Aborted (empty password not allowed)." << endl; |
|||
else |
|||
wallet.create(m_masterPassword); |
|||
} |
|||
else if (m_mode < OperationMode::CreateWallet) |
|||
{ |
|||
SecretStore store(m_secretsPath); |
|||
switch (m_mode) |
|||
{ |
|||
case OperationMode::ListBare: |
|||
for (h128 const& u: std::set<h128>() + store.keys()) |
|||
cout << toUUID(u) << endl; |
|||
break; |
|||
case OperationMode::NewBare: |
|||
{ |
|||
if (m_lock.empty()) |
|||
m_lock = createPassword("Enter a password with which to secure this account: "); |
|||
auto k = makeKey(); |
|||
h128 u = store.importSecret(k.secret().asBytes(), m_lock); |
|||
cout << "Created key " << toUUID(u) << endl; |
|||
cout << " Address: " << k.address().hex() << endl; |
|||
cout << " ICAP: " << ICAP(k.address()).encoded() << endl; |
|||
break; |
|||
} |
|||
case OperationMode::ImportBare: |
|||
for (string const& i: m_inputs) |
|||
{ |
|||
h128 u; |
|||
bytes b; |
|||
b = fromHex(i); |
|||
if (b.size() != 32) |
|||
{ |
|||
std::string s = contentsString(i); |
|||
b = fromHex(s); |
|||
if (b.size() != 32) |
|||
u = store.importKey(i); |
|||
} |
|||
if (!u && b.size() == 32) |
|||
u = store.importSecret(b, lockPassword(toAddress(Secret(b)).abridged())); |
|||
if (!u) |
|||
{ |
|||
cerr << "Cannot import " << i << " not a file or secret." << endl; |
|||
continue; |
|||
} |
|||
cout << "Successfully imported " << i << " as " << toUUID(u); |
|||
} |
|||
break; |
|||
case OperationMode::InspectBare: |
|||
for (auto const& i: m_inputs) |
|||
if (!contents(i).empty()) |
|||
{ |
|||
h128 u = store.readKey(i, false); |
|||
bytes s = store.secret(u, [&](){ return getPassword("Enter password for key " + i + ": "); }); |
|||
cout << "Key " << i << ":" << endl; |
|||
cout << " UUID: " << toUUID(u) << ":" << endl; |
|||
cout << " Address: " << toAddress(Secret(s)).hex() << endl; |
|||
cout << " Secret: " << Secret(s).abridged() << endl; |
|||
} |
|||
else if (h128 u = fromUUID(i)) |
|||
{ |
|||
bytes s = store.secret(u, [&](){ return getPassword("Enter password for key " + toUUID(u) + ": "); }); |
|||
cout << "Key " << i << ":" << endl; |
|||
cout << " Address: " << toAddress(Secret(s)).hex() << endl; |
|||
cout << " Secret: " << Secret(s).abridged() << endl; |
|||
} |
|||
else |
|||
cerr << "Couldn't inspect " << i << "; not found." << endl; |
|||
break; |
|||
case OperationMode::ExportBare: break; |
|||
case OperationMode::RecodeBare: |
|||
for (auto const& i: m_inputs) |
|||
if (h128 u = fromUUID(i)) |
|||
if (store.recode(u, lockPassword(toUUID(u)), [&](){ return getPassword("Enter password for key " + toUUID(u) + ": "); }, kdf())) |
|||
cerr << "Re-encoded " << toUUID(u) << endl; |
|||
else |
|||
cerr << "Couldn't re-encode " << toUUID(u) << "; key corrupt or incorrect password supplied." << endl; |
|||
else |
|||
cerr << "Couldn't re-encode " << i << "; not found." << endl; |
|||
case OperationMode::KillBare: |
|||
for (auto const& i: m_inputs) |
|||
if (h128 u = fromUUID(i)) |
|||
store.kill(u); |
|||
else |
|||
cerr << "Couldn't kill " << i << "; not found." << endl; |
|||
break; |
|||
default: break; |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
KeyManager wallet(m_walletPath, m_secretsPath); |
|||
if (wallet.exists()) |
|||
while (true) |
|||
{ |
|||
if (wallet.load(m_masterPassword)) |
|||
break; |
|||
if (!m_masterPassword.empty()) |
|||
{ |
|||
cout << "Password invalid. Try again." << endl; |
|||
m_masterPassword.clear(); |
|||
} |
|||
m_masterPassword = getPassword("Please enter your MASTER password: "); |
|||
} |
|||
else |
|||
{ |
|||
cerr << "Couldn't open wallet. Does it exist?" << endl; |
|||
exit(-1); |
|||
} |
|||
switch (m_mode) |
|||
{ |
|||
case OperationMode::New: |
|||
{ |
|||
tie(m_lock, m_lockHint) = createPassword(wallet, "Enter a password with which to secure this account (or nothing to use the master password): ", m_lock, m_lockHint); |
|||
auto k = makeKey(); |
|||
bool usesMaster = m_lock.empty(); |
|||
h128 u = usesMaster ? wallet.import(k.secret(), m_name) : wallet.import(k.secret(), m_name, m_lock, m_lockHint); |
|||
cout << "Created key " << toUUID(u) << endl; |
|||
cout << " Name: " << m_name << endl; |
|||
if (usesMaster) |
|||
cout << " Uses master password." << endl; |
|||
else |
|||
cout << " Password hint: " << m_lockHint << endl; |
|||
cout << " Address: " << k.address().hex() << endl; |
|||
cout << " ICAP: " << ICAP(k.address()).encoded() << endl; |
|||
break; |
|||
} |
|||
case OperationMode::List: |
|||
{ |
|||
vector<u128> bare; |
|||
vector<u128> nonIcap; |
|||
for (auto const& u: wallet.store().keys()) |
|||
if (Address a = wallet.address(u)) |
|||
if (a[0]) |
|||
nonIcap.push_back(u); |
|||
else |
|||
{ |
|||
std::pair<std::string, std::string> info = wallet.accountDetails()[a]; |
|||
cout << toUUID(u) << " " << a.abridged(); |
|||
cout << " " << ICAP(a).encoded(); |
|||
cout << " " << info.first << endl; |
|||
} |
|||
else |
|||
bare.push_back(u); |
|||
for (auto const& u: nonIcap) |
|||
if (Address a = wallet.address(u)) |
|||
{ |
|||
std::pair<std::string, std::string> info = wallet.accountDetails()[a]; |
|||
cout << toUUID(u) << " " << a.abridged(); |
|||
cout << " (Not ICAP) "; |
|||
cout << " " << info.first << endl; |
|||
} |
|||
for (auto const& u: bare) |
|||
cout << toUUID(u) << " (Bare)" << endl; |
|||
} |
|||
default: break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
std::string lockPassword(std::string const& _accountName) |
|||
{ |
|||
return m_lock.empty() ? createPassword("Enter a password with which to secure account " + _accountName + ": ") : m_lock; |
|||
} |
|||
|
|||
static void streamHelp(ostream& _out) |
|||
{ |
|||
_out |
|||
<< "Secret-store (\"bare\") operation modes:" << endl |
|||
<< " --list-bare List all secret available in secret-store." << endl |
|||
<< " --new-bare Generate and output a key without interacting with wallet and dump the JSON." << endl |
|||
<< " --import-bare [ <file>|<secret-hex> , ... ] Import keys from given sources." << endl |
|||
<< " --recode-bare [ <uuid>|<file> , ... ] Decrypt and re-encrypt given keys." << endl |
|||
// << " --export-bare [ <uuid> , ... ] Export given keys." << endl
|
|||
<< " --kill-bare [ <uuid> , ... ] Delete given keys." << endl |
|||
<< "Secret-store configuration:" << endl |
|||
<< " --secrets-path <path> Specify Web3 secret-store path (default: " << SecretStore::defaultPath() << ")" << endl |
|||
<< endl |
|||
<< "Wallet operating modes:" << endl |
|||
<< " -l,--list List all keys available in wallet." << endl |
|||
<< " -n,--new <name> Create a new key with given name and add it in the wallet." << endl |
|||
<< " -i,--import [<uuid>|<file>|<secret-hex>] <name> Import keys from given source and place in wallet." << endl |
|||
<< " -e,--export [ <address>|<uuid> , ... ] Export given keys." << endl |
|||
<< " -r,--recode [ <address>|<uuid>|<file> , ... ] Decrypt and re-encrypt given keys." << endl |
|||
<< "Wallet configuration:" << endl |
|||
<< " --create-wallet Create an Ethereum master wallet." << endl |
|||
<< " --wallet-path <path> Specify Ethereum wallet path (default: " << KeyManager::defaultPath() << ")" << endl |
|||
<< " -m, --master <password> Specify wallet (master) password." << endl |
|||
<< endl |
|||
<< "Encryption configuration:" << endl |
|||
<< " --kdf <kdfname> Specify KDF to use when encrypting (default: sc rypt)" << endl |
|||
<< " --kdf-param <name> <value> Specify a parameter for the KDF." << endl |
|||
// << " --cipher <ciphername> Specify cipher to use when encrypting (default: aes-128-ctr)" << endl
|
|||
// << " --cipher-param <name> <value> Specify a parameter for the cipher." << endl
|
|||
<< " --lock <password> Specify password for when encrypting a (the) key." << endl |
|||
<< " --hint <hint> Specify hint for the --lock password." << endl |
|||
<< endl |
|||
<< "Decryption configuration:" << endl |
|||
<< " --unlock <password> Specify password for a (the) key." << endl |
|||
<< "Key generation configuration:" << endl |
|||
<< " --no-icap Don't bother to make a direct-ICAP capable key." << endl |
|||
; |
|||
} |
|||
|
|||
static bool isTrue(std::string const& _m) |
|||
{ |
|||
return _m == "on" || _m == "yes" || _m == "true" || _m == "1"; |
|||
} |
|||
|
|||
static bool isFalse(std::string const& _m) |
|||
{ |
|||
return _m == "off" || _m == "no" || _m == "false" || _m == "0"; |
|||
} |
|||
|
|||
private: |
|||
KDF kdf() const { return m_kdf == "pbkdf2" ? KDF::PBKDF2_SHA256 : KDF::Scrypt; } |
|||
|
|||
/// Operating mode.
|
|||
OperationMode m_mode; |
|||
|
|||
/// Wallet stuff
|
|||
string m_secretsPath = SecretStore::defaultPath(); |
|||
string m_walletPath = KeyManager::defaultPath(); |
|||
|
|||
/// Wallet password stuff
|
|||
string m_masterPassword; |
|||
strings m_unlocks; |
|||
string m_lock; |
|||
string m_lockHint; |
|||
bool m_icap = true; |
|||
|
|||
/// Creating
|
|||
string m_name; |
|||
|
|||
/// Importing
|
|||
strings m_inputs; |
|||
|
|||
string m_kdf = "scrypt"; |
|||
map<string, string> m_kdfParams; |
|||
// string m_cipher;
|
|||
// map<string, string> m_cipherParams;
|
|||
}; |
@ -0,0 +1,84 @@ |
|||
/*
|
|||
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 main.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
* Ethereum client. |
|||
*/ |
|||
|
|||
#include <thread> |
|||
#include <chrono> |
|||
#include <fstream> |
|||
#include <iostream> |
|||
#include <libdevcore/FileSystem.h> |
|||
#include <libdevcore/Log.h> |
|||
#include <libethcore/KeyManager.h> |
|||
#include "BuildInfo.h" |
|||
#include "KeyAux.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
|
|||
void help() |
|||
{ |
|||
cout |
|||
<< "Usage ethkey [OPTIONS]" << endl |
|||
<< "Options:" << endl << endl; |
|||
KeyCLI::streamHelp(cout); |
|||
cout |
|||
<< "General Options:" << endl |
|||
<< " -v,--verbosity <0 - 9> Set the log verbosity from 0 to 9 (default: 8)." << endl |
|||
<< " -V,--version Show the version and exit." << endl |
|||
<< " -h,--help Show this help message and exit." << endl |
|||
; |
|||
exit(0); |
|||
} |
|||
|
|||
void version() |
|||
{ |
|||
cout << "ethkey version " << dev::Version << endl; |
|||
cout << "Build: " << DEV_QUOTED(ETH_BUILD_PLATFORM) << "/" << DEV_QUOTED(ETH_BUILD_TYPE) << endl; |
|||
exit(0); |
|||
} |
|||
|
|||
int main(int argc, char** argv) |
|||
{ |
|||
KeyCLI m(KeyCLI::OperationMode::ListBare); |
|||
g_logVerbosity = 0; |
|||
|
|||
for (int i = 1; i < argc; ++i) |
|||
{ |
|||
string arg = argv[i]; |
|||
if (m.interpretOption(i, argc, argv)) {} |
|||
else if ((arg == "-v" || arg == "--verbosity") && i + 1 < argc) |
|||
g_logVerbosity = atoi(argv[++i]); |
|||
else if (arg == "-h" || arg == "--help") |
|||
help(); |
|||
else if (arg == "-V" || arg == "--version") |
|||
version(); |
|||
else |
|||
{ |
|||
cerr << "Invalid argument: " << arg << endl; |
|||
exit(-1); |
|||
} |
|||
} |
|||
|
|||
m.execute(); |
|||
|
|||
return 0; |
|||
} |
|||
|
@ -0,0 +1,505 @@ |
|||
#pragma once |
|||
|
|||
/*
|
|||
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 MinerAux.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
* CLI module for mining. |
|||
*/ |
|||
|
|||
#include <thread> |
|||
#include <chrono> |
|||
#include <fstream> |
|||
#include <iostream> |
|||
#include <signal.h> |
|||
|
|||
#include <boost/algorithm/string.hpp> |
|||
#include <boost/algorithm/string/trim_all.hpp> |
|||
|
|||
#include <libdevcore/FileSystem.h> |
|||
#include <libevmcore/Instruction.h> |
|||
#include <libdevcore/StructuredLogger.h> |
|||
#include <libethcore/Exceptions.h> |
|||
#include <libdevcore/SHA3.h> |
|||
#include <libethcore/ProofOfWork.h> |
|||
#include <libethcore/EthashAux.h> |
|||
#include <libethcore/Farm.h> |
|||
#if ETH_JSONRPC || !ETH_TRUE |
|||
#include <libweb3jsonrpc/WebThreeStubServer.h> |
|||
#include <jsonrpccpp/server/connectors/httpserver.h> |
|||
#include <jsonrpccpp/client/connectors/httpclient.h> |
|||
#endif |
|||
#include "BuildInfo.h" |
|||
#if ETH_JSONRPC || !ETH_TRUE |
|||
#include "PhoneHome.h" |
|||
#include "Farm.h" |
|||
#endif |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
using namespace boost::algorithm; |
|||
using dev::eth::Instruction; |
|||
|
|||
#undef RETURN |
|||
|
|||
bool isTrue(std::string const& _m) |
|||
{ |
|||
return _m == "on" || _m == "yes" || _m == "true" || _m == "1"; |
|||
} |
|||
|
|||
bool isFalse(std::string const& _m) |
|||
{ |
|||
return _m == "off" || _m == "no" || _m == "false" || _m == "0"; |
|||
} |
|||
|
|||
inline std::string credits() |
|||
{ |
|||
std::ostringstream out; |
|||
out |
|||
<< "Ethereum (++) " << dev::Version << endl |
|||
<< " Code by Gav Wood et al, (c) 2013, 2014, 2015." << endl; |
|||
return out.str(); |
|||
} |
|||
|
|||
class BadArgument: public Exception {}; |
|||
|
|||
class MinerCLI |
|||
{ |
|||
public: |
|||
enum class OperationMode |
|||
{ |
|||
None, |
|||
DAGInit, |
|||
Benchmark, |
|||
Farm |
|||
}; |
|||
|
|||
MinerCLI(OperationMode _mode = OperationMode::None): mode(_mode) {} |
|||
|
|||
bool interpretOption(int& i, int argc, char** argv) |
|||
{ |
|||
string arg = argv[i]; |
|||
if ((arg == "-F" || arg == "--farm") && i + 1 < argc) |
|||
{ |
|||
mode = OperationMode::Farm; |
|||
farmURL = argv[++i]; |
|||
} |
|||
else if (arg == "--farm-recheck" && i + 1 < argc) |
|||
try { |
|||
farmRecheckPeriod = stol(argv[++i]); |
|||
} |
|||
catch (...) |
|||
{ |
|||
cerr << "Bad " << arg << " option: " << argv[i] << endl; |
|||
throw BadArgument(); |
|||
} |
|||
else if (arg == "--opencl-platform" && i + 1 < argc) |
|||
try { |
|||
openclPlatform = stol(argv[++i]); |
|||
} |
|||
catch (...) |
|||
{ |
|||
cerr << "Bad " << arg << " option: " << argv[i] << endl; |
|||
throw BadArgument(); |
|||
} |
|||
else if (arg == "--opencl-device" && i + 1 < argc) |
|||
try { |
|||
openclDevice = stol(argv[++i]); |
|||
miningThreads = 1; |
|||
} |
|||
catch (...) |
|||
{ |
|||
cerr << "Bad " << arg << " option: " << argv[i] << endl; |
|||
throw BadArgument(); |
|||
} |
|||
else if (arg == "--phone-home" && i + 1 < argc) |
|||
{ |
|||
string m = argv[++i]; |
|||
if (isTrue(m)) |
|||
phoneHome = true; |
|||
else if (isFalse(m)) |
|||
phoneHome = false; |
|||
else |
|||
{ |
|||
cerr << "Bad " << arg << " option: " << m << endl; |
|||
throw BadArgument(); |
|||
} |
|||
} |
|||
else if (arg == "--benchmark-warmup" && i + 1 < argc) |
|||
try { |
|||
benchmarkWarmup = stol(argv[++i]); |
|||
} |
|||
catch (...) |
|||
{ |
|||
cerr << "Bad " << arg << " option: " << argv[i] << endl; |
|||
throw BadArgument(); |
|||
} |
|||
else if (arg == "--benchmark-trial" && i + 1 < argc) |
|||
try { |
|||
benchmarkTrial = stol(argv[++i]); |
|||
} |
|||
catch (...) |
|||
{ |
|||
cerr << "Bad " << arg << " option: " << argv[i] << endl; |
|||
throw BadArgument(); |
|||
} |
|||
else if (arg == "--benchmark-trials" && i + 1 < argc) |
|||
try { |
|||
benchmarkTrials = stol(argv[++i]); |
|||
} |
|||
catch (...) |
|||
{ |
|||
cerr << "Bad " << arg << " option: " << argv[i] << endl; |
|||
throw BadArgument(); |
|||
} |
|||
else if (arg == "-C" || arg == "--cpu") |
|||
m_minerType = MinerType::CPU; |
|||
else if (arg == "-G" || arg == "--opencl") |
|||
{ |
|||
if (!ProofOfWork::GPUMiner::haveSufficientGPUMemory()) |
|||
{ |
|||
cout << "No GPU device with sufficient memory was found. Defaulting to CPU" << endl; |
|||
m_minerType = MinerType::CPU; |
|||
} |
|||
else |
|||
{ |
|||
m_minerType = MinerType::GPU; |
|||
miningThreads = 1; |
|||
} |
|||
} |
|||
else if (arg == "--no-precompute") |
|||
{ |
|||
precompute = false; |
|||
} |
|||
else if ((arg == "-D" || arg == "--create-dag") && i + 1 < argc) |
|||
{ |
|||
string m = boost::to_lower_copy(string(argv[++i])); |
|||
mode = OperationMode::DAGInit; |
|||
try |
|||
{ |
|||
initDAG = stol(m); |
|||
} |
|||
catch (...) |
|||
{ |
|||
cerr << "Bad " << arg << " option: " << m << endl; |
|||
throw BadArgument(); |
|||
} |
|||
} |
|||
else if ((arg == "-w" || arg == "--check-pow") && i + 4 < argc) |
|||
{ |
|||
string m; |
|||
try |
|||
{ |
|||
BlockInfo bi; |
|||
m = boost::to_lower_copy(string(argv[++i])); |
|||
h256 powHash(m); |
|||
m = boost::to_lower_copy(string(argv[++i])); |
|||
h256 seedHash; |
|||
if (m.size() == 64 || m.size() == 66) |
|||
seedHash = h256(m); |
|||
else |
|||
seedHash = EthashAux::seedHash(stol(m)); |
|||
m = boost::to_lower_copy(string(argv[++i])); |
|||
bi.difficulty = u256(m); |
|||
auto boundary = bi.boundary(); |
|||
m = boost::to_lower_copy(string(argv[++i])); |
|||
bi.nonce = h64(m); |
|||
auto r = EthashAux::eval(bi.seedHash(), powHash, bi.nonce); |
|||
bool valid = r.value < boundary; |
|||
cout << (valid ? "VALID :-)" : "INVALID :-(") << endl; |
|||
cout << r.value << (valid ? " < " : " >= ") << boundary << endl; |
|||
cout << " where " << boundary << " = 2^256 / " << bi.difficulty << endl; |
|||
cout << " and " << r.value << " = ethash(" << powHash << ", " << bi.nonce << ")" << endl; |
|||
cout << " with seed as " << seedHash << endl; |
|||
if (valid) |
|||
cout << "(mixHash = " << r.mixHash << ")" << endl; |
|||
cout << "SHA3( light(seed) ) = " << sha3(EthashAux::light(bi.seedHash())->data()) << endl; |
|||
exit(0); |
|||
} |
|||
catch (...) |
|||
{ |
|||
cerr << "Bad " << arg << " option: " << m << endl; |
|||
throw BadArgument(); |
|||
} |
|||
} |
|||
else if (arg == "-M" || arg == "--benchmark") |
|||
mode = OperationMode::Benchmark; |
|||
else if ((arg == "-t" || arg == "--mining-threads") && i + 1 < argc) |
|||
{ |
|||
try { |
|||
miningThreads = stol(argv[++i]); |
|||
} |
|||
catch (...) |
|||
{ |
|||
cerr << "Bad " << arg << " option: " << argv[i] << endl; |
|||
throw BadArgument(); |
|||
} |
|||
} |
|||
else |
|||
return false; |
|||
return true; |
|||
} |
|||
|
|||
void execute() |
|||
{ |
|||
if (m_minerType == MinerType::CPU) |
|||
ProofOfWork::CPUMiner::setNumInstances(miningThreads); |
|||
else if (m_minerType == MinerType::GPU) |
|||
{ |
|||
ProofOfWork::GPUMiner::setDefaultPlatform(openclPlatform); |
|||
ProofOfWork::GPUMiner::setDefaultDevice(openclDevice); |
|||
ProofOfWork::GPUMiner::setNumInstances(miningThreads); |
|||
} |
|||
if (mode == OperationMode::DAGInit) |
|||
doInitDAG(initDAG); |
|||
else if (mode == OperationMode::Benchmark) |
|||
doBenchmark(m_minerType, phoneHome, benchmarkWarmup, benchmarkTrial, benchmarkTrials); |
|||
else if (mode == OperationMode::Farm) |
|||
doFarm(m_minerType, farmURL, farmRecheckPeriod); |
|||
} |
|||
|
|||
static void streamHelp(ostream& _out) |
|||
{ |
|||
_out |
|||
#if ETH_JSONRPC || !ETH_TRUE |
|||
<< "Work farming mode:" << endl |
|||
<< " -F,--farm <url> Put into mining farm mode with the work server at URL (default: http://127.0.0.1:8545)" << endl |
|||
<< " --farm-recheck <n> Leave n ms between checks for changed work (default: 500)." << endl |
|||
<< " --no-precompute Don't precompute the next epoch's DAG." << endl |
|||
#endif |
|||
<< "Ethash verify mode:" << endl |
|||
<< " -w,--check-pow <headerHash> <seedHash> <difficulty> <nonce> Check PoW credentials for validity." << endl |
|||
<< endl |
|||
<< "Benchmarking mode:" << endl |
|||
<< " -M,--benchmark Benchmark for mining and exit; use with --cpu and --opencl." << endl |
|||
<< " --benchmark-warmup <seconds> Set the duration of warmup for the benchmark tests (default: 3)." << endl |
|||
<< " --benchmark-trial <seconds> Set the duration for each trial for the benchmark tests (default: 3)." << endl |
|||
<< " --benchmark-trials <n> Set the duration of warmup for the benchmark tests (default: 5)." << endl |
|||
#if ETH_JSONRPC || !ETH_TRUE |
|||
<< " --phone-home <on/off> When benchmarking, publish results (default: on)" << endl |
|||
#endif |
|||
<< "DAG creation mode:" << endl |
|||
<< " -D,--create-dag <number> Create the DAG in preparation for mining on given block and exit." << endl |
|||
<< "Mining configuration:" << endl |
|||
<< " -C,--cpu When mining, use the CPU." << endl |
|||
<< " -G,--opencl When mining use the GPU via OpenCL." << endl |
|||
<< " --opencl-platform <n> When mining using -G/--opencl use OpenCL platform n (default: 0)." << endl |
|||
<< " --opencl-device <n> When mining using -G/--opencl use OpenCL device n (default: 0)." << endl |
|||
<< " -t, --mining-threads <n> Limit number of CPU/GPU miners to n (default: use everything available on selected platform)" << endl |
|||
; |
|||
} |
|||
|
|||
enum class MinerType |
|||
{ |
|||
CPU, |
|||
GPU |
|||
}; |
|||
|
|||
MinerType minerType() const { return m_minerType; } |
|||
|
|||
private: |
|||
void doInitDAG(unsigned _n) |
|||
{ |
|||
BlockInfo bi; |
|||
bi.number = _n; |
|||
cout << "Initializing DAG for epoch beginning #" << (bi.number / 30000 * 30000) << " (seedhash " << bi.seedHash().abridged() << "). This will take a while." << endl; |
|||
Ethash::prep(bi); |
|||
exit(0); |
|||
} |
|||
|
|||
void doBenchmark(MinerType _m, bool _phoneHome, unsigned _warmupDuration = 15, unsigned _trialDuration = 3, unsigned _trials = 5) |
|||
{ |
|||
BlockInfo genesis; |
|||
genesis.difficulty = 1 << 18; |
|||
cdebug << genesis.boundary(); |
|||
|
|||
GenericFarm<Ethash> f; |
|||
f.onSolutionFound([&](ProofOfWork::Solution) { return false; }); |
|||
|
|||
string platformInfo = _m == MinerType::CPU ? ProofOfWork::CPUMiner::platformInfo() : _m == MinerType::GPU ? ProofOfWork::GPUMiner::platformInfo() : ""; |
|||
cout << "Benchmarking on platform: " << platformInfo << endl; |
|||
|
|||
cout << "Preparing DAG..." << endl; |
|||
Ethash::prep(genesis); |
|||
|
|||
genesis.difficulty = u256(1) << 63; |
|||
genesis.noteDirty(); |
|||
f.setWork(genesis); |
|||
if (_m == MinerType::CPU) |
|||
f.startCPU(); |
|||
else if (_m == MinerType::GPU) |
|||
f.startGPU(); |
|||
|
|||
map<uint64_t, MiningProgress> results; |
|||
uint64_t mean = 0; |
|||
uint64_t innerMean = 0; |
|||
for (unsigned i = 0; i <= _trials; ++i) |
|||
{ |
|||
if (!i) |
|||
cout << "Warming up..." << endl; |
|||
else |
|||
cout << "Trial " << i << "... " << flush; |
|||
this_thread::sleep_for(chrono::seconds(i ? _trialDuration : _warmupDuration)); |
|||
|
|||
auto mp = f.miningProgress(); |
|||
f.resetMiningProgress(); |
|||
if (!i) |
|||
continue; |
|||
auto rate = mp.rate(); |
|||
|
|||
cout << rate << endl; |
|||
results[rate] = mp; |
|||
mean += rate; |
|||
} |
|||
f.stop(); |
|||
int j = -1; |
|||
for (auto const& r: results) |
|||
if (++j > 0 && j < (int)_trials - 1) |
|||
innerMean += r.second.rate(); |
|||
innerMean /= (_trials - 2); |
|||
cout << "min/mean/max: " << results.begin()->second.rate() << "/" << (mean / _trials) << "/" << results.rbegin()->second.rate() << " H/s" << endl; |
|||
cout << "inner mean: " << innerMean << " H/s" << endl; |
|||
|
|||
(void)_phoneHome; |
|||
#if ETH_JSONRPC || !ETH_TRUE |
|||
if (_phoneHome) |
|||
{ |
|||
cout << "Phoning home to find world ranking..." << endl; |
|||
jsonrpc::HttpClient client("http://gav.ethdev.com:3000"); |
|||
PhoneHome rpc(client); |
|||
try |
|||
{ |
|||
unsigned ranking = rpc.report_benchmark(platformInfo, innerMean); |
|||
cout << "Ranked: " << ranking << " of all benchmarks." << endl; |
|||
} |
|||
catch (...) |
|||
{ |
|||
cout << "Error phoning home. ET is sad." << endl; |
|||
} |
|||
} |
|||
#endif |
|||
exit(0); |
|||
} |
|||
|
|||
void doFarm(MinerType _m, string const& _remote, unsigned _recheckPeriod) |
|||
{ |
|||
(void)_m; |
|||
(void)_remote; |
|||
(void)_recheckPeriod; |
|||
#if ETH_JSONRPC || !ETH_TRUE |
|||
jsonrpc::HttpClient client(_remote); |
|||
|
|||
Farm rpc(client); |
|||
GenericFarm<Ethash> f; |
|||
if (_m == MinerType::CPU) |
|||
f.startCPU(); |
|||
else if (_m == MinerType::GPU) |
|||
f.startGPU(); |
|||
|
|||
ProofOfWork::WorkPackage current; |
|||
EthashAux::FullType dag; |
|||
while (true) |
|||
try |
|||
{ |
|||
bool completed = false; |
|||
ProofOfWork::Solution solution; |
|||
f.onSolutionFound([&](ProofOfWork::Solution sol) |
|||
{ |
|||
solution = sol; |
|||
return completed = true; |
|||
}); |
|||
for (unsigned i = 0; !completed; ++i) |
|||
{ |
|||
if (current) |
|||
cnote << "Mining on PoWhash" << current.headerHash << ": " << f.miningProgress(); |
|||
else |
|||
cnote << "Getting work package..."; |
|||
Json::Value v = rpc.eth_getWork(); |
|||
h256 hh(v[0].asString()); |
|||
h256 newSeedHash(v[1].asString()); |
|||
if (current.seedHash != newSeedHash) |
|||
cnote << "Grabbing DAG for" << newSeedHash; |
|||
if (!(dag = EthashAux::full(newSeedHash, true, [&](unsigned _pc){ cout << "\rCreating DAG. " << _pc << "% done..." << flush; return 0; }))) |
|||
BOOST_THROW_EXCEPTION(DAGCreationFailure()); |
|||
if (precompute) |
|||
EthashAux::computeFull(sha3(newSeedHash), true); |
|||
if (hh != current.headerHash) |
|||
{ |
|||
current.headerHash = hh; |
|||
current.seedHash = newSeedHash; |
|||
current.boundary = h256(fromHex(v[2].asString()), h256::AlignRight); |
|||
cnote << "Got work package:"; |
|||
cnote << " Header-hash:" << current.headerHash.hex(); |
|||
cnote << " Seedhash:" << current.seedHash.hex(); |
|||
cnote << " Target: " << h256(current.boundary).hex(); |
|||
f.setWork(current); |
|||
} |
|||
this_thread::sleep_for(chrono::milliseconds(_recheckPeriod)); |
|||
} |
|||
cnote << "Solution found; Submitting to" << _remote << "..."; |
|||
cnote << " Nonce:" << solution.nonce.hex(); |
|||
cnote << " Mixhash:" << solution.mixHash.hex(); |
|||
cnote << " Header-hash:" << current.headerHash.hex(); |
|||
cnote << " Seedhash:" << current.seedHash.hex(); |
|||
cnote << " Target: " << h256(current.boundary).hex(); |
|||
cnote << " Ethash: " << h256(EthashAux::eval(current.seedHash, current.headerHash, solution.nonce).value).hex(); |
|||
if (EthashAux::eval(current.seedHash, current.headerHash, solution.nonce).value < current.boundary) |
|||
{ |
|||
bool ok = rpc.eth_submitWork("0x" + toString(solution.nonce), "0x" + toString(current.headerHash), "0x" + toString(solution.mixHash)); |
|||
if (ok) |
|||
cnote << "B-) Submitted and accepted."; |
|||
else |
|||
cwarn << ":-( Not accepted."; |
|||
} |
|||
else |
|||
cwarn << "FAILURE: GPU gave incorrect result!"; |
|||
current.reset(); |
|||
} |
|||
catch (jsonrpc::JsonRpcException&) |
|||
{ |
|||
for (auto i = 3; --i; this_thread::sleep_for(chrono::seconds(1))) |
|||
cerr << "JSON-RPC problem. Probably couldn't connect. Retrying in " << i << "... \r"; |
|||
cerr << endl; |
|||
} |
|||
#endif |
|||
exit(0); |
|||
} |
|||
|
|||
/// Operating mode.
|
|||
OperationMode mode; |
|||
|
|||
/// Mining options
|
|||
MinerType m_minerType = MinerType::CPU; |
|||
unsigned openclPlatform = 0; |
|||
unsigned openclDevice = 0; |
|||
unsigned miningThreads = UINT_MAX; |
|||
|
|||
/// DAG initialisation param.
|
|||
unsigned initDAG = 0; |
|||
|
|||
/// Benchmarking params
|
|||
bool phoneHome = true; |
|||
unsigned benchmarkWarmup = 3; |
|||
unsigned benchmarkTrial = 3; |
|||
unsigned benchmarkTrials = 5; |
|||
|
|||
/// Farm params
|
|||
string farmURL = "http://127.0.0.1:8545"; |
|||
unsigned farmRecheckPeriod = 500; |
|||
bool precompute = true; |
|||
}; |
@ -0,0 +1,56 @@ |
|||
#pragma once |
|||
|
|||
#include <cstdint> |
|||
#include <functional> |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace evmjit |
|||
{ |
|||
|
|||
struct h256 |
|||
{ |
|||
uint64_t words[4]; |
|||
}; |
|||
|
|||
inline bool operator==(h256 _h1, h256 _h2) |
|||
{ |
|||
return _h1.words[0] == _h2.words[0] && |
|||
_h1.words[1] == _h2.words[1] && |
|||
_h1.words[2] == _h2.words[2] && |
|||
_h1.words[3] == _h2.words[3]; |
|||
} |
|||
|
|||
/// Representation of 256-bit value binary compatible with LLVM i256
|
|||
struct i256 |
|||
{ |
|||
uint64_t a = 0; |
|||
uint64_t b = 0; |
|||
uint64_t c = 0; |
|||
uint64_t d = 0; |
|||
|
|||
i256() = default; |
|||
i256(h256 _h) |
|||
{ |
|||
a = _h.words[0]; |
|||
b = _h.words[1]; |
|||
c = _h.words[2]; |
|||
d = _h.words[3]; |
|||
} |
|||
}; |
|||
|
|||
} |
|||
} |
|||
|
|||
namespace std |
|||
{ |
|||
template<> struct hash<dev::evmjit::h256> |
|||
{ |
|||
size_t operator()(dev::evmjit::h256 const& _h) const |
|||
{ |
|||
/// This implementation expects the argument to be a full 256-bit Keccak hash.
|
|||
/// It does nothing more than returning a slice of the input hash.
|
|||
return static_cast<size_t>(_h.words[0]); |
|||
}; |
|||
}; |
|||
} |
@ -0,0 +1,36 @@ |
|||
#pragma once |
|||
|
|||
#include "evmjit/DataTypes.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace eth |
|||
{ |
|||
namespace jit |
|||
{ |
|||
class ExecutionEngine; |
|||
} |
|||
} |
|||
|
|||
namespace evmjit |
|||
{ |
|||
|
|||
class JIT |
|||
{ |
|||
public: |
|||
|
|||
/// Ask JIT if the EVM code is ready for execution.
|
|||
/// Returns `true` if the EVM code has been compiled and loaded into memory.
|
|||
/// In this case the code can be executed without overhead.
|
|||
/// \param _codeHash The Keccak hash of the EVM code.
|
|||
static bool isCodeReady(h256 _codeHash); |
|||
|
|||
private: |
|||
friend class dev::eth::jit::ExecutionEngine; |
|||
|
|||
static uint64_t getCode(h256 _codeHash); |
|||
static void mapCode(h256 _codeHash, uint64_t _funcAddr); |
|||
}; |
|||
|
|||
} |
|||
} |
@ -0,0 +1,46 @@ |
|||
#include "evmjit/JIT.h" |
|||
|
|||
#include <unordered_map> |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace evmjit |
|||
{ |
|||
namespace |
|||
{ |
|||
|
|||
class JITImpl: JIT |
|||
{ |
|||
public: |
|||
std::unordered_map<h256, uint64_t> codeMap; |
|||
|
|||
static JITImpl& instance() |
|||
{ |
|||
static JITImpl s_instance; |
|||
return s_instance; |
|||
} |
|||
}; |
|||
|
|||
} // anonymous namespace
|
|||
|
|||
bool JIT::isCodeReady(h256 _codeHash) |
|||
{ |
|||
return JITImpl::instance().codeMap.count(_codeHash) != 0; |
|||
} |
|||
|
|||
uint64_t JIT::getCode(h256 _codeHash) |
|||
{ |
|||
auto& codeMap = JITImpl::instance().codeMap; |
|||
auto it = codeMap.find(_codeHash); |
|||
if (it != codeMap.end()) |
|||
return it->second; |
|||
return 0; |
|||
} |
|||
|
|||
void JIT::mapCode(h256 _codeHash, uint64_t _funcAddr) |
|||
{ |
|||
JITImpl::instance().codeMap.insert(std::make_pair(_codeHash, _funcAddr)); |
|||
} |
|||
|
|||
} |
|||
} |
@ -0,0 +1,440 @@ |
|||
/*
|
|||
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 Hash.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#include "Hash.h" |
|||
#include <cstdio> |
|||
#include <cstdlib> |
|||
#include <cstring> |
|||
#include "picosha2.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
|
|||
namespace dev |
|||
{ |
|||
|
|||
h256 sha256(bytesConstRef _input) |
|||
{ |
|||
h256 ret; |
|||
picosha2::hash256(_input.begin(), _input.end(), ret.data(), ret.data() + 32); |
|||
return ret; |
|||
} |
|||
|
|||
namespace rmd160 |
|||
{ |
|||
|
|||
/********************************************************************\
|
|||
* |
|||
* FILE: rmd160.h |
|||
* FILE: rmd160.c |
|||
* |
|||
* CONTENTS: Header file for a sample C-implementation of the |
|||
* RIPEMD-160 hash-function. |
|||
* TARGET: any computer with an ANSI C compiler |
|||
* |
|||
* AUTHOR: Antoon Bosselaers, ESAT-COSIC |
|||
* DATE: 1 March 1996 |
|||
* VERSION: 1.0 |
|||
* |
|||
* Copyright (c) Katholieke Universiteit Leuven |
|||
* 1996, All Rights Reserved |
|||
* |
|||
\********************************************************************/ |
|||
|
|||
// Adapted into "header-only" format by Gav Wood.
|
|||
|
|||
/* macro definitions */ |
|||
|
|||
#define RMDsize 160 |
|||
|
|||
/* collect four bytes into one word: */ |
|||
#define BYTES_TO_DWORD(strptr) \ |
|||
(((uint32_t) *((strptr)+3) << 24) | \ |
|||
((uint32_t) *((strptr)+2) << 16) | \ |
|||
((uint32_t) *((strptr)+1) << 8) | \ |
|||
((uint32_t) *(strptr))) |
|||
|
|||
/* ROL(x, n) cyclically rotates x over n bits to the left */ |
|||
/* x must be of an unsigned 32 bits type and 0 <= n < 32. */ |
|||
#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n)))) |
|||
|
|||
/* the five basic functions F(), G() and H() */ |
|||
#define F(x, y, z) ((x) ^ (y) ^ (z)) |
|||
#define G(x, y, z) (((x) & (y)) | (~(x) & (z))) |
|||
#define H(x, y, z) (((x) | ~(y)) ^ (z)) |
|||
#define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) |
|||
#define J(x, y, z) ((x) ^ ((y) | ~(z))) |
|||
|
|||
/* the ten basic operations FF() through III() */ |
|||
#define FF(a, b, c, d, e, x, s) {\ |
|||
(a) += F((b), (c), (d)) + (x);\ |
|||
(a) = ROL((a), (s)) + (e);\ |
|||
(c) = ROL((c), 10);\ |
|||
} |
|||
#define GG(a, b, c, d, e, x, s) {\ |
|||
(a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ |
|||
(a) = ROL((a), (s)) + (e);\ |
|||
(c) = ROL((c), 10);\ |
|||
} |
|||
#define HH(a, b, c, d, e, x, s) {\ |
|||
(a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ |
|||
(a) = ROL((a), (s)) + (e);\ |
|||
(c) = ROL((c), 10);\ |
|||
} |
|||
#define II(a, b, c, d, e, x, s) {\ |
|||
(a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ |
|||
(a) = ROL((a), (s)) + (e);\ |
|||
(c) = ROL((c), 10);\ |
|||
} |
|||
#define JJ(a, b, c, d, e, x, s) {\ |
|||
(a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\ |
|||
(a) = ROL((a), (s)) + (e);\ |
|||
(c) = ROL((c), 10);\ |
|||
} |
|||
#define FFF(a, b, c, d, e, x, s) {\ |
|||
(a) += F((b), (c), (d)) + (x);\ |
|||
(a) = ROL((a), (s)) + (e);\ |
|||
(c) = ROL((c), 10);\ |
|||
} |
|||
#define GGG(a, b, c, d, e, x, s) {\ |
|||
(a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\ |
|||
(a) = ROL((a), (s)) + (e);\ |
|||
(c) = ROL((c), 10);\ |
|||
} |
|||
#define HHH(a, b, c, d, e, x, s) {\ |
|||
(a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\ |
|||
(a) = ROL((a), (s)) + (e);\ |
|||
(c) = ROL((c), 10);\ |
|||
} |
|||
#define III(a, b, c, d, e, x, s) {\ |
|||
(a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\ |
|||
(a) = ROL((a), (s)) + (e);\ |
|||
(c) = ROL((c), 10);\ |
|||
} |
|||
#define JJJ(a, b, c, d, e, x, s) {\ |
|||
(a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\ |
|||
(a) = ROL((a), (s)) + (e);\ |
|||
(c) = ROL((c), 10);\ |
|||
} |
|||
|
|||
void MDinit(uint32_t *MDbuf) |
|||
{ |
|||
MDbuf[0] = 0x67452301UL; |
|||
MDbuf[1] = 0xefcdab89UL; |
|||
MDbuf[2] = 0x98badcfeUL; |
|||
MDbuf[3] = 0x10325476UL; |
|||
MDbuf[4] = 0xc3d2e1f0UL; |
|||
|
|||
return; |
|||
} |
|||
|
|||
/********************************************************************/ |
|||
|
|||
void MDcompress(uint32_t *MDbuf, uint32_t *X) |
|||
{ |
|||
uint32_t aa = MDbuf[0], bb = MDbuf[1], cc = MDbuf[2], |
|||
dd = MDbuf[3], ee = MDbuf[4]; |
|||
uint32_t aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2], |
|||
ddd = MDbuf[3], eee = MDbuf[4]; |
|||
|
|||
/* round 1 */ |
|||
FF(aa, bb, cc, dd, ee, X[ 0], 11); |
|||
FF(ee, aa, bb, cc, dd, X[ 1], 14); |
|||
FF(dd, ee, aa, bb, cc, X[ 2], 15); |
|||
FF(cc, dd, ee, aa, bb, X[ 3], 12); |
|||
FF(bb, cc, dd, ee, aa, X[ 4], 5); |
|||
FF(aa, bb, cc, dd, ee, X[ 5], 8); |
|||
FF(ee, aa, bb, cc, dd, X[ 6], 7); |
|||
FF(dd, ee, aa, bb, cc, X[ 7], 9); |
|||
FF(cc, dd, ee, aa, bb, X[ 8], 11); |
|||
FF(bb, cc, dd, ee, aa, X[ 9], 13); |
|||
FF(aa, bb, cc, dd, ee, X[10], 14); |
|||
FF(ee, aa, bb, cc, dd, X[11], 15); |
|||
FF(dd, ee, aa, bb, cc, X[12], 6); |
|||
FF(cc, dd, ee, aa, bb, X[13], 7); |
|||
FF(bb, cc, dd, ee, aa, X[14], 9); |
|||
FF(aa, bb, cc, dd, ee, X[15], 8); |
|||
|
|||
/* round 2 */ |
|||
GG(ee, aa, bb, cc, dd, X[ 7], 7); |
|||
GG(dd, ee, aa, bb, cc, X[ 4], 6); |
|||
GG(cc, dd, ee, aa, bb, X[13], 8); |
|||
GG(bb, cc, dd, ee, aa, X[ 1], 13); |
|||
GG(aa, bb, cc, dd, ee, X[10], 11); |
|||
GG(ee, aa, bb, cc, dd, X[ 6], 9); |
|||
GG(dd, ee, aa, bb, cc, X[15], 7); |
|||
GG(cc, dd, ee, aa, bb, X[ 3], 15); |
|||
GG(bb, cc, dd, ee, aa, X[12], 7); |
|||
GG(aa, bb, cc, dd, ee, X[ 0], 12); |
|||
GG(ee, aa, bb, cc, dd, X[ 9], 15); |
|||
GG(dd, ee, aa, bb, cc, X[ 5], 9); |
|||
GG(cc, dd, ee, aa, bb, X[ 2], 11); |
|||
GG(bb, cc, dd, ee, aa, X[14], 7); |
|||
GG(aa, bb, cc, dd, ee, X[11], 13); |
|||
GG(ee, aa, bb, cc, dd, X[ 8], 12); |
|||
|
|||
/* round 3 */ |
|||
HH(dd, ee, aa, bb, cc, X[ 3], 11); |
|||
HH(cc, dd, ee, aa, bb, X[10], 13); |
|||
HH(bb, cc, dd, ee, aa, X[14], 6); |
|||
HH(aa, bb, cc, dd, ee, X[ 4], 7); |
|||
HH(ee, aa, bb, cc, dd, X[ 9], 14); |
|||
HH(dd, ee, aa, bb, cc, X[15], 9); |
|||
HH(cc, dd, ee, aa, bb, X[ 8], 13); |
|||
HH(bb, cc, dd, ee, aa, X[ 1], 15); |
|||
HH(aa, bb, cc, dd, ee, X[ 2], 14); |
|||
HH(ee, aa, bb, cc, dd, X[ 7], 8); |
|||
HH(dd, ee, aa, bb, cc, X[ 0], 13); |
|||
HH(cc, dd, ee, aa, bb, X[ 6], 6); |
|||
HH(bb, cc, dd, ee, aa, X[13], 5); |
|||
HH(aa, bb, cc, dd, ee, X[11], 12); |
|||
HH(ee, aa, bb, cc, dd, X[ 5], 7); |
|||
HH(dd, ee, aa, bb, cc, X[12], 5); |
|||
|
|||
/* round 4 */ |
|||
II(cc, dd, ee, aa, bb, X[ 1], 11); |
|||
II(bb, cc, dd, ee, aa, X[ 9], 12); |
|||
II(aa, bb, cc, dd, ee, X[11], 14); |
|||
II(ee, aa, bb, cc, dd, X[10], 15); |
|||
II(dd, ee, aa, bb, cc, X[ 0], 14); |
|||
II(cc, dd, ee, aa, bb, X[ 8], 15); |
|||
II(bb, cc, dd, ee, aa, X[12], 9); |
|||
II(aa, bb, cc, dd, ee, X[ 4], 8); |
|||
II(ee, aa, bb, cc, dd, X[13], 9); |
|||
II(dd, ee, aa, bb, cc, X[ 3], 14); |
|||
II(cc, dd, ee, aa, bb, X[ 7], 5); |
|||
II(bb, cc, dd, ee, aa, X[15], 6); |
|||
II(aa, bb, cc, dd, ee, X[14], 8); |
|||
II(ee, aa, bb, cc, dd, X[ 5], 6); |
|||
II(dd, ee, aa, bb, cc, X[ 6], 5); |
|||
II(cc, dd, ee, aa, bb, X[ 2], 12); |
|||
|
|||
/* round 5 */ |
|||
JJ(bb, cc, dd, ee, aa, X[ 4], 9); |
|||
JJ(aa, bb, cc, dd, ee, X[ 0], 15); |
|||
JJ(ee, aa, bb, cc, dd, X[ 5], 5); |
|||
JJ(dd, ee, aa, bb, cc, X[ 9], 11); |
|||
JJ(cc, dd, ee, aa, bb, X[ 7], 6); |
|||
JJ(bb, cc, dd, ee, aa, X[12], 8); |
|||
JJ(aa, bb, cc, dd, ee, X[ 2], 13); |
|||
JJ(ee, aa, bb, cc, dd, X[10], 12); |
|||
JJ(dd, ee, aa, bb, cc, X[14], 5); |
|||
JJ(cc, dd, ee, aa, bb, X[ 1], 12); |
|||
JJ(bb, cc, dd, ee, aa, X[ 3], 13); |
|||
JJ(aa, bb, cc, dd, ee, X[ 8], 14); |
|||
JJ(ee, aa, bb, cc, dd, X[11], 11); |
|||
JJ(dd, ee, aa, bb, cc, X[ 6], 8); |
|||
JJ(cc, dd, ee, aa, bb, X[15], 5); |
|||
JJ(bb, cc, dd, ee, aa, X[13], 6); |
|||
|
|||
/* parallel round 1 */ |
|||
JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8); |
|||
JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9); |
|||
JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9); |
|||
JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11); |
|||
JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13); |
|||
JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15); |
|||
JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15); |
|||
JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5); |
|||
JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7); |
|||
JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7); |
|||
JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8); |
|||
JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11); |
|||
JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14); |
|||
JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14); |
|||
JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12); |
|||
JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6); |
|||
|
|||
/* parallel round 2 */ |
|||
III(eee, aaa, bbb, ccc, ddd, X[ 6], 9); |
|||
III(ddd, eee, aaa, bbb, ccc, X[11], 13); |
|||
III(ccc, ddd, eee, aaa, bbb, X[ 3], 15); |
|||
III(bbb, ccc, ddd, eee, aaa, X[ 7], 7); |
|||
III(aaa, bbb, ccc, ddd, eee, X[ 0], 12); |
|||
III(eee, aaa, bbb, ccc, ddd, X[13], 8); |
|||
III(ddd, eee, aaa, bbb, ccc, X[ 5], 9); |
|||
III(ccc, ddd, eee, aaa, bbb, X[10], 11); |
|||
III(bbb, ccc, ddd, eee, aaa, X[14], 7); |
|||
III(aaa, bbb, ccc, ddd, eee, X[15], 7); |
|||
III(eee, aaa, bbb, ccc, ddd, X[ 8], 12); |
|||
III(ddd, eee, aaa, bbb, ccc, X[12], 7); |
|||
III(ccc, ddd, eee, aaa, bbb, X[ 4], 6); |
|||
III(bbb, ccc, ddd, eee, aaa, X[ 9], 15); |
|||
III(aaa, bbb, ccc, ddd, eee, X[ 1], 13); |
|||
III(eee, aaa, bbb, ccc, ddd, X[ 2], 11); |
|||
|
|||
/* parallel round 3 */ |
|||
HHH(ddd, eee, aaa, bbb, ccc, X[15], 9); |
|||
HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7); |
|||
HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15); |
|||
HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11); |
|||
HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8); |
|||
HHH(ddd, eee, aaa, bbb, ccc, X[14], 6); |
|||
HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6); |
|||
HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14); |
|||
HHH(aaa, bbb, ccc, ddd, eee, X[11], 12); |
|||
HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13); |
|||
HHH(ddd, eee, aaa, bbb, ccc, X[12], 5); |
|||
HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14); |
|||
HHH(bbb, ccc, ddd, eee, aaa, X[10], 13); |
|||
HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13); |
|||
HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7); |
|||
HHH(ddd, eee, aaa, bbb, ccc, X[13], 5); |
|||
|
|||
/* parallel round 4 */ |
|||
GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15); |
|||
GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5); |
|||
GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8); |
|||
GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11); |
|||
GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14); |
|||
GGG(ccc, ddd, eee, aaa, bbb, X[11], 14); |
|||
GGG(bbb, ccc, ddd, eee, aaa, X[15], 6); |
|||
GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14); |
|||
GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6); |
|||
GGG(ddd, eee, aaa, bbb, ccc, X[12], 9); |
|||
GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12); |
|||
GGG(bbb, ccc, ddd, eee, aaa, X[13], 9); |
|||
GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12); |
|||
GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5); |
|||
GGG(ddd, eee, aaa, bbb, ccc, X[10], 15); |
|||
GGG(ccc, ddd, eee, aaa, bbb, X[14], 8); |
|||
|
|||
/* parallel round 5 */ |
|||
FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8); |
|||
FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5); |
|||
FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12); |
|||
FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9); |
|||
FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12); |
|||
FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5); |
|||
FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14); |
|||
FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6); |
|||
FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8); |
|||
FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13); |
|||
FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6); |
|||
FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5); |
|||
FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15); |
|||
FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13); |
|||
FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11); |
|||
FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11); |
|||
|
|||
/* combine results */ |
|||
ddd += cc + MDbuf[1]; /* final result for MDbuf[0] */ |
|||
MDbuf[1] = MDbuf[2] + dd + eee; |
|||
MDbuf[2] = MDbuf[3] + ee + aaa; |
|||
MDbuf[3] = MDbuf[4] + aa + bbb; |
|||
MDbuf[4] = MDbuf[0] + bb + ccc; |
|||
MDbuf[0] = ddd; |
|||
|
|||
return; |
|||
} |
|||
|
|||
void MDfinish(uint32_t *MDbuf, byte const *strptr, uint32_t lswlen, uint32_t mswlen) |
|||
{ |
|||
unsigned int i; /* counter */ |
|||
uint32_t X[16]; /* message words */ |
|||
|
|||
memset(X, 0, 16*sizeof(uint32_t)); |
|||
|
|||
/* put bytes from strptr into X */ |
|||
for (i=0; i<(lswlen&63); i++) { |
|||
/* byte i goes into word X[i div 4] at pos. 8*(i mod 4) */ |
|||
X[i>>2] ^= (uint32_t) *strptr++ << (8 * (i&3)); |
|||
} |
|||
|
|||
/* append the bit m_n == 1 */ |
|||
X[(lswlen>>2)&15] ^= (uint32_t)1 << (8*(lswlen&3) + 7); |
|||
|
|||
if ((lswlen & 63) > 55) { |
|||
/* length goes to next block */ |
|||
MDcompress(MDbuf, X); |
|||
memset(X, 0, 16*sizeof(uint32_t)); |
|||
} |
|||
|
|||
/* append length in bits*/ |
|||
X[14] = lswlen << 3; |
|||
X[15] = (lswlen >> 29) | (mswlen << 3); |
|||
MDcompress(MDbuf, X); |
|||
|
|||
return; |
|||
} |
|||
|
|||
#undef ROL |
|||
#undef F |
|||
#undef G |
|||
#undef H |
|||
#undef I |
|||
#undef J |
|||
#undef FF |
|||
#undef GG |
|||
#undef HH |
|||
#undef II |
|||
#undef JJ |
|||
#undef FFF |
|||
#undef GGG |
|||
#undef HHH |
|||
#undef III |
|||
#undef JJJ |
|||
|
|||
} |
|||
|
|||
/*
|
|||
* @returns RMD(_input) |
|||
*/ |
|||
h160 ripemd160(bytesConstRef _input) |
|||
{ |
|||
h160 hashcode; |
|||
uint32_t buffer[RMDsize / 32]; // contains (A, B, C, D(, E))
|
|||
uint32_t current[16]; // current 16-word chunk
|
|||
|
|||
// initialize
|
|||
rmd160::MDinit(buffer); |
|||
byte const* message = _input.data(); |
|||
uint32_t remaining = _input.size(); // # of bytes not yet processed
|
|||
|
|||
// process message in 16x 4-byte chunks
|
|||
for (; remaining >= 64; remaining -= 64) |
|||
{ |
|||
for (unsigned i = 0; i < 16; i++) |
|||
{ |
|||
current[i] = BYTES_TO_DWORD(message); |
|||
message += 4; |
|||
} |
|||
rmd160::MDcompress(buffer, current); |
|||
} |
|||
// length mod 64 bytes left
|
|||
|
|||
// finish:
|
|||
rmd160::MDfinish(buffer, message, _input.size(), 0); |
|||
|
|||
for (unsigned i = 0; i < RMDsize / 8; i += 4) |
|||
{ |
|||
hashcode[i] = buffer[i >> 2]; // implicit cast to byte
|
|||
hashcode[i + 1] = (buffer[i >> 2] >> 8); //extracts the 8 least
|
|||
hashcode[i + 2] = (buffer[i >> 2] >> 16); // significant bits.
|
|||
hashcode[i + 3] = (buffer[i >> 2] >> 24); |
|||
} |
|||
|
|||
return hashcode; |
|||
} |
|||
|
|||
#undef BYTES_TO_DWORD |
|||
#undef RMDsize |
|||
|
|||
} |
@ -0,0 +1,223 @@ |
|||
/*
|
|||
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 SHA3.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#include "SHA3.h" |
|||
#include <cstdint> |
|||
#include <cstdio> |
|||
#include <cstdlib> |
|||
#include <cstring> |
|||
#include <libdevcore/RLP.h> |
|||
#include "picosha2.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
|
|||
namespace dev |
|||
{ |
|||
|
|||
h256 EmptySHA3 = sha3(bytesConstRef()); |
|||
h256 EmptyListSHA3 = sha3(rlpList()); |
|||
|
|||
namespace keccak |
|||
{ |
|||
|
|||
/** libkeccak-tiny
|
|||
* |
|||
* A single-file implementation of SHA-3 and SHAKE. |
|||
* |
|||
* Implementor: David Leon Gil |
|||
* License: CC0, attribution kindly requested. Blame taken too, |
|||
* but not liability. |
|||
*/ |
|||
|
|||
#define decshake(bits) \ |
|||
int shake##bits(uint8_t*, size_t, const uint8_t*, size_t); |
|||
|
|||
#define decsha3(bits) \ |
|||
int sha3_##bits(uint8_t*, size_t, const uint8_t*, size_t); |
|||
|
|||
decshake(128) |
|||
decshake(256) |
|||
decsha3(224) |
|||
decsha3(256) |
|||
decsha3(384) |
|||
decsha3(512) |
|||
|
|||
/******** The Keccak-f[1600] permutation ********/ |
|||
|
|||
/*** Constants. ***/ |
|||
static const uint8_t rho[24] = \ |
|||
{ 1, 3, 6, 10, 15, 21, |
|||
28, 36, 45, 55, 2, 14, |
|||
27, 41, 56, 8, 25, 43, |
|||
62, 18, 39, 61, 20, 44}; |
|||
static const uint8_t pi[24] = \ |
|||
{10, 7, 11, 17, 18, 3, |
|||
5, 16, 8, 21, 24, 4, |
|||
15, 23, 19, 13, 12, 2, |
|||
20, 14, 22, 9, 6, 1}; |
|||
static const uint64_t RC[24] = \ |
|||
{1ULL, 0x8082ULL, 0x800000000000808aULL, 0x8000000080008000ULL, |
|||
0x808bULL, 0x80000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL, |
|||
0x8aULL, 0x88ULL, 0x80008009ULL, 0x8000000aULL, |
|||
0x8000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL, |
|||
0x8000000000008002ULL, 0x8000000000000080ULL, 0x800aULL, 0x800000008000000aULL, |
|||
0x8000000080008081ULL, 0x8000000000008080ULL, 0x80000001ULL, 0x8000000080008008ULL}; |
|||
|
|||
/*** Helper macros to unroll the permutation. ***/ |
|||
#define rol(x, s) (((x) << s) | ((x) >> (64 - s))) |
|||
#define REPEAT6(e) e e e e e e |
|||
#define REPEAT24(e) REPEAT6(e e e e) |
|||
#define REPEAT5(e) e e e e e |
|||
#define FOR5(v, s, e) \ |
|||
v = 0; \ |
|||
REPEAT5(e; v += s;) |
|||
|
|||
/*** Keccak-f[1600] ***/ |
|||
static inline void keccakf(void* state) { |
|||
uint64_t* a = (uint64_t*)state; |
|||
uint64_t b[5] = {0}; |
|||
uint64_t t = 0; |
|||
uint8_t x, y; |
|||
|
|||
for (int i = 0; i < 24; i++) { |
|||
// Theta
|
|||
FOR5(x, 1, |
|||
b[x] = 0; |
|||
FOR5(y, 5, |
|||
b[x] ^= a[x + y]; )) |
|||
FOR5(x, 1, |
|||
FOR5(y, 5, |
|||
a[y + x] ^= b[(x + 4) % 5] ^ rol(b[(x + 1) % 5], 1); )) |
|||
// Rho and pi
|
|||
t = a[1]; |
|||
x = 0; |
|||
REPEAT24(b[0] = a[pi[x]]; |
|||
a[pi[x]] = rol(t, rho[x]); |
|||
t = b[0]; |
|||
x++; ) |
|||
// Chi
|
|||
FOR5(y, |
|||
5, |
|||
FOR5(x, 1, |
|||
b[x] = a[y + x];) |
|||
FOR5(x, 1, |
|||
a[y + x] = b[x] ^ ((~b[(x + 1) % 5]) & b[(x + 2) % 5]); )) |
|||
// Iota
|
|||
a[0] ^= RC[i]; |
|||
} |
|||
} |
|||
|
|||
/******** The FIPS202-defined functions. ********/ |
|||
|
|||
/*** Some helper macros. ***/ |
|||
|
|||
#define _(S) do { S } while (0) |
|||
#define FOR(i, ST, L, S) \ |
|||
_(for (size_t i = 0; i < L; i += ST) { S; }) |
|||
#define mkapply_ds(NAME, S) \ |
|||
static inline void NAME(uint8_t* dst, \ |
|||
const uint8_t* src, \ |
|||
size_t len) { \ |
|||
FOR(i, 1, len, S); \ |
|||
} |
|||
#define mkapply_sd(NAME, S) \ |
|||
static inline void NAME(const uint8_t* src, \ |
|||
uint8_t* dst, \ |
|||
size_t len) { \ |
|||
FOR(i, 1, len, S); \ |
|||
} |
|||
|
|||
mkapply_ds(xorin, dst[i] ^= src[i]) // xorin
|
|||
mkapply_sd(setout, dst[i] = src[i]) // setout
|
|||
|
|||
#define P keccakf |
|||
#define Plen 200 |
|||
|
|||
// Fold P*F over the full blocks of an input.
|
|||
#define foldP(I, L, F) \ |
|||
while (L >= rate) { \ |
|||
F(a, I, rate); \ |
|||
P(a); \ |
|||
I += rate; \ |
|||
L -= rate; \ |
|||
} |
|||
|
|||
/** The sponge-based hash construction. **/ |
|||
static inline int hash(uint8_t* out, size_t outlen, |
|||
const uint8_t* in, size_t inlen, |
|||
size_t rate, uint8_t delim) { |
|||
if ((out == NULL) || ((in == NULL) && inlen != 0) || (rate >= Plen)) { |
|||
return -1; |
|||
} |
|||
uint8_t a[Plen] = {0}; |
|||
// Absorb input.
|
|||
foldP(in, inlen, xorin); |
|||
// Xor in the DS and pad frame.
|
|||
a[inlen] ^= delim; |
|||
a[rate - 1] ^= 0x80; |
|||
// Xor in the last block.
|
|||
xorin(a, in, inlen); |
|||
// Apply P
|
|||
P(a); |
|||
// Squeeze output.
|
|||
foldP(out, outlen, setout); |
|||
setout(a, out, outlen); |
|||
memset(a, 0, 200); |
|||
return 0; |
|||
} |
|||
|
|||
/*** Helper macros to define SHA3 and SHAKE instances. ***/ |
|||
#define defshake(bits) \ |
|||
int shake##bits(uint8_t* out, size_t outlen, \ |
|||
const uint8_t* in, size_t inlen) { \ |
|||
return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x1f); \ |
|||
} |
|||
#define defsha3(bits) \ |
|||
int sha3_##bits(uint8_t* out, size_t outlen, \ |
|||
const uint8_t* in, size_t inlen) { \ |
|||
if (outlen > (bits/8)) { \ |
|||
return -1; \ |
|||
} \ |
|||
return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x01); \ |
|||
} |
|||
|
|||
/*** FIPS202 SHAKE VOFs ***/ |
|||
defshake(128) |
|||
defshake(256) |
|||
|
|||
/*** FIPS202 SHA3 FOFs ***/ |
|||
defsha3(224) |
|||
defsha3(256) |
|||
defsha3(384) |
|||
defsha3(512) |
|||
|
|||
} |
|||
|
|||
h256 sha3(bytesConstRef _input) |
|||
{ |
|||
// FIXME: What with unaligned memory?
|
|||
h256 ret; |
|||
keccak::sha3_256(ret.data(), 32, _input.data(), _input.size()); |
|||
// keccak::keccak(ret.data(), 32, (uint64_t const*)_input.data(), _input.size());
|
|||
return ret; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,46 @@ |
|||
/*
|
|||
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 TrieHash.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <libdevcore/Common.h> |
|||
#include <libdevcore/FixedHash.h> |
|||
|
|||
namespace dev |
|||
{ |
|||
|
|||
bytes rlp256(BytesMap const& _s); |
|||
h256 hash256(BytesMap const& _s); |
|||
|
|||
h256 orderedTrieRoot(std::vector<bytes> const& _data); |
|||
|
|||
template <class T, class U> inline h256 trieRootOver(unsigned _itemCount, T const& _getKey, U const& _getValue) |
|||
{ |
|||
BytesMap m; |
|||
for (unsigned i = 0; i < _itemCount; ++i) |
|||
m[_getKey(i)] = _getValue(i); |
|||
return hash256(m); |
|||
} |
|||
|
|||
h256 orderedTrieRoot(std::vector<bytesConstRef> const& _data); |
|||
h256 orderedTrieRoot(std::vector<bytes> const& _data); |
|||
|
|||
} |
@ -0,0 +1,520 @@ |
|||
|
|||
// This is a copy of boost/multiprecision/detail/number_compare.hpp from boost 1.59 to replace buggy version from 1.58.
|
|||
|
|||
#ifdef BOOST_MP_COMPARE_HPP |
|||
#error This bug workaround header must be included before original boost/multiprecision/detail/number_compare.hpp |
|||
#endif |
|||
|
|||
///////////////////////////////////////////////////////////////////////////////
|
|||
// Copyright 2012 John Maddock. Distributed under the Boost
|
|||
// Software License, Version 1.0. (See accompanying file
|
|||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|||
|
|||
#ifndef BOOST_MP_COMPARE_HPP |
|||
#define BOOST_MP_COMPARE_HPP |
|||
|
|||
// A copy of boost/multiprecision/traits/is_backend.hpp
|
|||
#ifndef BOOST_MP_IS_BACKEND_HPP |
|||
#define BOOST_MP_IS_BACKEND_HPP |
|||
|
|||
#include <boost/mpl/has_xxx.hpp> |
|||
#include <boost/type_traits/conditional.hpp> |
|||
#include <boost/type_traits/is_convertible.hpp> |
|||
#include <boost/multiprecision/detail/number_base.hpp> |
|||
#include <boost/multiprecision/detail/generic_interconvert.hpp> |
|||
|
|||
namespace boost{ namespace multiprecision{ namespace detail{ |
|||
|
|||
BOOST_MPL_HAS_XXX_TRAIT_DEF(signed_types) |
|||
BOOST_MPL_HAS_XXX_TRAIT_DEF(unsigned_types) |
|||
BOOST_MPL_HAS_XXX_TRAIT_DEF(float_types) |
|||
|
|||
template <class T> |
|||
struct is_backend |
|||
{ |
|||
static const bool value = has_signed_types<T>::value && has_unsigned_types<T>::value && has_float_types<T>::value; |
|||
}; |
|||
|
|||
template <class Backend> |
|||
struct other_backend |
|||
{ |
|||
typedef typename boost::conditional< |
|||
boost::is_same<number<Backend>, number<Backend, et_on> >::value, |
|||
number<Backend, et_off>, number<Backend, et_on> >::type type; |
|||
}; |
|||
|
|||
template <class B, class V> |
|||
struct number_from_backend |
|||
{ |
|||
typedef typename boost::conditional < |
|||
boost::is_convertible<V, number<B> >::value, |
|||
number<B>, |
|||
typename other_backend<B>::type > ::type type; |
|||
}; |
|||
|
|||
template <bool b, class T, class U> |
|||
struct is_first_backend_imp{ static const bool value = false; }; |
|||
template <class T, class U> |
|||
struct is_first_backend_imp<true, T, U>{ static const bool value = is_convertible<U, number<T, et_on> >::value || is_convertible<U, number<T, et_off> >::value; }; |
|||
|
|||
template <class T, class U> |
|||
struct is_first_backend : is_first_backend_imp<is_backend<T>::value, T, U> {}; |
|||
|
|||
template <bool b, class T, class U> |
|||
struct is_second_backend_imp{ static const bool value = false; }; |
|||
template <class T, class U> |
|||
struct is_second_backend_imp<true, T, U>{ static const bool value = is_convertible<T, number<U> >::value || is_convertible<T, number<U, et_off> >::value; }; |
|||
|
|||
template <class T, class U> |
|||
struct is_second_backend : is_second_backend_imp<is_backend<U>::value, T, U> {}; |
|||
|
|||
} |
|||
} |
|||
} |
|||
|
|||
#endif // BOOST_MP_IS_BACKEND_HPP
|
|||
|
|||
//
|
|||
// Comparison operators for number.
|
|||
//
|
|||
|
|||
namespace boost{ namespace multiprecision{ |
|||
|
|||
namespace default_ops{ |
|||
|
|||
template <class B> |
|||
inline bool eval_eq(const B& a, const B& b) |
|||
{ |
|||
return a.compare(b) == 0; |
|||
} |
|||
template <class T, class U> |
|||
inline typename enable_if_c<boost::multiprecision::detail::is_first_backend<T, U>::value, bool>::type eval_eq(const T& a, const U& b) |
|||
{ |
|||
typename boost::multiprecision::detail::number_from_backend<T, U>::type t(b); |
|||
return eval_eq(a, t.backend()); |
|||
} |
|||
template <class T, class U> |
|||
inline typename enable_if_c<boost::multiprecision::detail::is_second_backend<T, U>::value, bool>::type eval_eq(const T& a, const U& b) |
|||
{ |
|||
typename boost::multiprecision::detail::number_from_backend<U, T>::type t(a); |
|||
return eval_eq(t.backend(), b); |
|||
} |
|||
|
|||
template <class B> |
|||
inline bool eval_lt(const B& a, const B& b) |
|||
{ |
|||
return a.compare(b) < 0; |
|||
} |
|||
template <class T, class U> |
|||
inline typename enable_if_c<boost::multiprecision::detail::is_first_backend<T, U>::value, bool>::type eval_lt(const T& a, const U& b) |
|||
{ |
|||
typename boost::multiprecision::detail::number_from_backend<T, U>::type t(b); |
|||
return eval_lt(a, t.backend()); |
|||
} |
|||
template <class T, class U> |
|||
inline typename enable_if_c<boost::multiprecision::detail::is_second_backend<T, U>::value, bool>::type eval_lt(const T& a, const U& b) |
|||
{ |
|||
typename boost::multiprecision::detail::number_from_backend<U, T>::type t(a); |
|||
return eval_lt(t.backend(), b); |
|||
} |
|||
|
|||
template <class B> |
|||
inline bool eval_gt(const B& a, const B& b) |
|||
{ |
|||
return a.compare(b) > 0; |
|||
} |
|||
template <class T, class U> |
|||
inline typename enable_if_c<boost::multiprecision::detail::is_first_backend<T, U>::value, bool>::type eval_gt(const T& a, const U& b) |
|||
{ |
|||
typename boost::multiprecision::detail::number_from_backend<T, U>::type t(b); |
|||
return eval_gt(a, t.backend()); |
|||
} |
|||
template <class T, class U> |
|||
inline typename enable_if_c<boost::multiprecision::detail::is_second_backend<T, U>::value, bool>::type eval_gt(const T& a, const U& b) |
|||
{ |
|||
typename boost::multiprecision::detail::number_from_backend<U, T>::type t(a); |
|||
return eval_gt(t.backend(), b); |
|||
} |
|||
|
|||
} // namespace default_ops
|
|||
|
|||
namespace detail{ |
|||
|
|||
template <class Num, class Val> |
|||
struct is_valid_mixed_compare : public mpl::false_ {}; |
|||
|
|||
template <class B, expression_template_option ET, class Val> |
|||
struct is_valid_mixed_compare<number<B, ET>, Val> : public is_convertible<Val, number<B, ET> > {}; |
|||
|
|||
template <class B, expression_template_option ET> |
|||
struct is_valid_mixed_compare<number<B, ET>, number<B, ET> > : public mpl::false_ {}; |
|||
|
|||
template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4> |
|||
struct is_valid_mixed_compare<number<B, ET>, expression<tag, Arg1, Arg2, Arg3, Arg4> > |
|||
: public mpl::bool_<is_convertible<expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::value> {}; |
|||
|
|||
template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> |
|||
struct is_valid_mixed_compare<expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> > |
|||
: public mpl::bool_<is_convertible<expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::value> {}; |
|||
|
|||
template <class Backend, expression_template_option ExpressionTemplates> |
|||
inline BOOST_CONSTEXPR typename boost::enable_if_c<number_category<Backend>::value != number_kind_floating_point, bool>::type is_unordered_value(const number<Backend, ExpressionTemplates>&) |
|||
{ |
|||
return false; |
|||
} |
|||
template <class Backend, expression_template_option ExpressionTemplates> |
|||
inline BOOST_CONSTEXPR typename boost::enable_if_c<number_category<Backend>::value == number_kind_floating_point, bool>::type is_unordered_value(const number<Backend, ExpressionTemplates>& a) |
|||
{ |
|||
using default_ops::eval_fpclassify; |
|||
return eval_fpclassify(a.backend()) == FP_NAN; |
|||
} |
|||
|
|||
template <class Arithmetic> |
|||
inline BOOST_CONSTEXPR typename boost::enable_if_c<number_category<Arithmetic>::value != number_kind_floating_point, bool>::type is_unordered_value(const Arithmetic&) |
|||
{ |
|||
return false; |
|||
} |
|||
template <class Arithmetic> |
|||
inline BOOST_CONSTEXPR typename boost::enable_if_c<number_category<Arithmetic>::value == number_kind_floating_point, bool>::type is_unordered_value(const Arithmetic& a) |
|||
{ |
|||
return (boost::math::isnan)(a); |
|||
} |
|||
|
|||
template <class T, class U> |
|||
inline BOOST_CONSTEXPR bool is_unordered_comparison(const T& a, const U& b) |
|||
{ |
|||
return is_unordered_value(a) || is_unordered_value(b); |
|||
} |
|||
|
|||
} |
|||
|
|||
template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2> |
|||
inline bool operator == (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) |
|||
{ |
|||
using default_ops::eval_eq; |
|||
if(detail::is_unordered_comparison(a, b)) return false; |
|||
return eval_eq(a.backend(), b.backend()); |
|||
} |
|||
template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic> |
|||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type |
|||
operator == (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) |
|||
{ |
|||
using default_ops::eval_eq; |
|||
if(detail::is_unordered_comparison(a, b)) return false; |
|||
return eval_eq(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b)); |
|||
} |
|||
template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates> |
|||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type |
|||
operator == (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) |
|||
{ |
|||
using default_ops::eval_eq; |
|||
if(detail::is_unordered_comparison(a, b)) return false; |
|||
return eval_eq(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a)); |
|||
} |
|||
template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4> |
|||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type |
|||
operator == (const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b) |
|||
{ |
|||
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type; |
|||
using default_ops::eval_eq; |
|||
result_type t(b); |
|||
if(detail::is_unordered_comparison(a, t)) return false; |
|||
return eval_eq(t.backend(), result_type::canonical_value(a)); |
|||
} |
|||
template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic> |
|||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type |
|||
operator == (const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b) |
|||
{ |
|||
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type; |
|||
using default_ops::eval_eq; |
|||
result_type t(a); |
|||
if(detail::is_unordered_comparison(t, b)) return false; |
|||
return eval_eq(t.backend(), result_type::canonical_value(b)); |
|||
} |
|||
template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b> |
|||
inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type |
|||
operator == (const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b) |
|||
{ |
|||
using default_ops::eval_eq; |
|||
typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a); |
|||
typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b); |
|||
if(detail::is_unordered_comparison(t, t2)) return false; |
|||
return eval_eq(t.backend(), t2.backend()); |
|||
} |
|||
|
|||
template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2> |
|||
inline bool operator != (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) |
|||
{ |
|||
using default_ops::eval_eq; |
|||
if(detail::is_unordered_comparison(a, b)) return true; |
|||
return !eval_eq(a.backend(), b.backend()); |
|||
} |
|||
template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic> |
|||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type |
|||
operator != (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) |
|||
{ |
|||
using default_ops::eval_eq; |
|||
if(detail::is_unordered_comparison(a, b)) return true; |
|||
return !eval_eq(a.backend(), number<Backend, et_on>::canonical_value(b)); |
|||
} |
|||
template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates> |
|||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type |
|||
operator != (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) |
|||
{ |
|||
using default_ops::eval_eq; |
|||
if(detail::is_unordered_comparison(a, b)) return true; |
|||
return !eval_eq(b.backend(), number<Backend, et_on>::canonical_value(a)); |
|||
} |
|||
template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4> |
|||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type |
|||
operator != (const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b) |
|||
{ |
|||
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type; |
|||
using default_ops::eval_eq; |
|||
result_type t(b); |
|||
if(detail::is_unordered_comparison(a, t)) return true; |
|||
return !eval_eq(t.backend(), result_type::canonical_value(a)); |
|||
} |
|||
template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic> |
|||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type |
|||
operator != (const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b) |
|||
{ |
|||
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type; |
|||
using default_ops::eval_eq; |
|||
result_type t(a); |
|||
if(detail::is_unordered_comparison(t, b)) return true; |
|||
return !eval_eq(t.backend(), result_type::canonical_value(b)); |
|||
} |
|||
template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b> |
|||
inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type |
|||
operator != (const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b) |
|||
{ |
|||
using default_ops::eval_eq; |
|||
typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a); |
|||
typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b); |
|||
if(detail::is_unordered_comparison(t, t2)) return true; |
|||
return !eval_eq(t.backend(), t2.backend()); |
|||
} |
|||
|
|||
template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2> |
|||
inline bool operator < (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) |
|||
{ |
|||
using default_ops::eval_lt; |
|||
if(detail::is_unordered_comparison(a, b)) return false; |
|||
return eval_lt(a.backend(), b.backend()); |
|||
} |
|||
template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic> |
|||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type |
|||
operator < (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) |
|||
{ |
|||
using default_ops::eval_lt; |
|||
if(detail::is_unordered_comparison(a, b)) return false; |
|||
return eval_lt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b)); |
|||
} |
|||
template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates> |
|||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type |
|||
operator < (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) |
|||
{ |
|||
using default_ops::eval_gt; |
|||
if(detail::is_unordered_comparison(a, b)) return false; |
|||
return eval_gt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a)); |
|||
} |
|||
template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4> |
|||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type |
|||
operator < (const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b) |
|||
{ |
|||
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type; |
|||
using default_ops::eval_gt; |
|||
result_type t(b); |
|||
if(detail::is_unordered_comparison(a, t)) return false; |
|||
return eval_gt(t.backend(), result_type::canonical_value(a)); |
|||
} |
|||
template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic> |
|||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type |
|||
operator < (const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b) |
|||
{ |
|||
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type; |
|||
using default_ops::eval_lt; |
|||
result_type t(a); |
|||
if(detail::is_unordered_comparison(t, b)) return false; |
|||
return eval_lt(t.backend(), result_type::canonical_value(b)); |
|||
} |
|||
template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b> |
|||
inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type |
|||
operator < (const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b) |
|||
{ |
|||
using default_ops::eval_lt; |
|||
typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a); |
|||
typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b); |
|||
if(detail::is_unordered_comparison(t, t2)) return false; |
|||
return eval_lt(t.backend(), t2.backend()); |
|||
} |
|||
|
|||
template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2> |
|||
inline bool operator > (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) |
|||
{ |
|||
using default_ops::eval_gt; |
|||
if(detail::is_unordered_comparison(a, b)) return false; |
|||
return eval_gt(a.backend(), b.backend()); |
|||
} |
|||
template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic> |
|||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type |
|||
operator > (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) |
|||
{ |
|||
using default_ops::eval_gt; |
|||
if(detail::is_unordered_comparison(a, b)) return false; |
|||
return eval_gt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b)); |
|||
} |
|||
template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates> |
|||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type |
|||
operator > (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) |
|||
{ |
|||
using default_ops::eval_lt; |
|||
if(detail::is_unordered_comparison(a, b)) return false; |
|||
return eval_lt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a)); |
|||
} |
|||
template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4> |
|||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type |
|||
operator > (const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b) |
|||
{ |
|||
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type; |
|||
using default_ops::eval_lt; |
|||
result_type t(b); |
|||
if(detail::is_unordered_comparison(a, t)) return false; |
|||
return a > t; |
|||
} |
|||
template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic> |
|||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type |
|||
operator > (const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b) |
|||
{ |
|||
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type; |
|||
using default_ops::eval_gt; |
|||
result_type t(a); |
|||
if(detail::is_unordered_comparison(t, b)) return false; |
|||
return t > b; |
|||
} |
|||
template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b> |
|||
inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type |
|||
operator > (const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b) |
|||
{ |
|||
using default_ops::eval_gt; |
|||
typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a); |
|||
typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b); |
|||
if(detail::is_unordered_comparison(t, t2)) return false; |
|||
return t > t2; |
|||
} |
|||
|
|||
template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2> |
|||
inline bool operator <= (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) |
|||
{ |
|||
using default_ops::eval_gt; |
|||
if(detail::is_unordered_comparison(a, b)) return false; |
|||
return !eval_gt(a.backend(), b.backend()); |
|||
} |
|||
template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic> |
|||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type |
|||
operator <= (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) |
|||
{ |
|||
using default_ops::eval_gt; |
|||
if(detail::is_unordered_comparison(a, b)) return false; |
|||
return !eval_gt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b)); |
|||
} |
|||
template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates> |
|||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type |
|||
operator <= (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) |
|||
{ |
|||
using default_ops::eval_lt; |
|||
if(detail::is_unordered_comparison(a, b)) return false; |
|||
return !eval_lt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a)); |
|||
} |
|||
template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4> |
|||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type |
|||
operator <= (const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b) |
|||
{ |
|||
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type; |
|||
using default_ops::eval_lt; |
|||
if(detail::is_unordered_value(a) || detail::is_unordered_value(b)) |
|||
return false; |
|||
result_type t(b); |
|||
if(detail::is_unordered_comparison(a, t)) return false; |
|||
return !eval_lt(t.backend(), result_type::canonical_value(a)); |
|||
} |
|||
template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic> |
|||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type |
|||
operator <= (const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b) |
|||
{ |
|||
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type; |
|||
using default_ops::eval_gt; |
|||
result_type t(a); |
|||
if(detail::is_unordered_comparison(t, b)) return false; |
|||
return !eval_gt(t.backend(), result_type::canonical_value(b)); |
|||
} |
|||
template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b> |
|||
inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type |
|||
operator <= (const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b) |
|||
{ |
|||
using default_ops::eval_gt; |
|||
typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a); |
|||
typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b); |
|||
if(detail::is_unordered_comparison(t, t2)) return false; |
|||
return !eval_gt(t.backend(), t2.backend()); |
|||
} |
|||
|
|||
template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2> |
|||
inline bool operator >= (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) |
|||
{ |
|||
using default_ops::eval_lt; |
|||
if(detail::is_unordered_comparison(a, b)) return false; |
|||
return !eval_lt(a.backend(), b.backend()); |
|||
} |
|||
template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic> |
|||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type |
|||
operator >= (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) |
|||
{ |
|||
using default_ops::eval_lt; |
|||
if(detail::is_unordered_comparison(a, b)) return false; |
|||
return !eval_lt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b)); |
|||
} |
|||
template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates> |
|||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type |
|||
operator >= (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) |
|||
{ |
|||
using default_ops::eval_gt; |
|||
if(detail::is_unordered_comparison(a, b)) return false; |
|||
return !eval_gt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a)); |
|||
} |
|||
template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4> |
|||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type |
|||
operator >= (const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b) |
|||
{ |
|||
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type; |
|||
using default_ops::eval_gt; |
|||
result_type t(b); |
|||
if(detail::is_unordered_comparison(a, t)) return false; |
|||
return !eval_gt(t.backend(), result_type::canonical_value(a)); |
|||
} |
|||
template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic> |
|||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type |
|||
operator >= (const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b) |
|||
{ |
|||
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type; |
|||
using default_ops::eval_lt; |
|||
result_type t(a); |
|||
if(detail::is_unordered_comparison(t, b)) return false; |
|||
return !eval_lt(t.backend(), result_type::canonical_value(b)); |
|||
} |
|||
template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b> |
|||
inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type |
|||
operator >= (const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b) |
|||
{ |
|||
using default_ops::eval_lt; |
|||
typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a); |
|||
typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b); |
|||
if(detail::is_unordered_comparison(t, t2)) return false; |
|||
return !eval_lt(t.backend(), t2.backend()); |
|||
} |
|||
|
|||
|
|||
}} // namespaces
|
|||
|
|||
#endif // BOOST_MP_COMPARE_HPP
|
@ -0,0 +1,360 @@ |
|||
/*
|
|||
The MIT License (MIT) |
|||
|
|||
Copyright (C) 2014 okdshin |
|||
|
|||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
of this software and associated documentation files (the "Software"), to deal |
|||
in the Software without restriction, including without limitation the rights |
|||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|||
copies of the Software, and to permit persons to whom the Software is |
|||
furnished to do so, subject to the following conditions: |
|||
|
|||
The above copyright notice and this permission notice shall be included in |
|||
all copies or substantial portions of the Software. |
|||
|
|||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|||
THE SOFTWARE. |
|||
*/ |
|||
#ifndef PICOSHA2_H |
|||
#define PICOSHA2_H |
|||
//picosha2:20140213
|
|||
#include <cstdint> |
|||
#include <iostream> |
|||
#include <vector> |
|||
#include <iterator> |
|||
#include <cassert> |
|||
#include <sstream> |
|||
#include <algorithm> |
|||
|
|||
namespace picosha2 |
|||
{ |
|||
|
|||
namespace detail |
|||
{ |
|||
|
|||
inline uint8_t mask_8bit(uint8_t x){ |
|||
return x&0xff; |
|||
} |
|||
|
|||
inline uint32_t mask_32bit(uint32_t x){ |
|||
return x&0xffffffff; |
|||
} |
|||
|
|||
static const uint32_t add_constant[64] = { |
|||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, |
|||
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, |
|||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, |
|||
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, |
|||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, |
|||
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, |
|||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, |
|||
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, |
|||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, |
|||
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, |
|||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, |
|||
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, |
|||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, |
|||
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, |
|||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, |
|||
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 |
|||
}; |
|||
|
|||
static const uint32_t initial_message_digest[8] = { |
|||
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, |
|||
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 |
|||
}; |
|||
|
|||
inline uint32_t ch(uint32_t x, uint32_t y, uint32_t z){ |
|||
return (x&y)^((~x)&z); |
|||
} |
|||
|
|||
inline uint32_t maj(uint32_t x, uint32_t y, uint32_t z){ |
|||
return (x&y)^(x&z)^(y&z); |
|||
} |
|||
|
|||
inline uint32_t rotr(uint32_t x, std::size_t n){ |
|||
assert(n < 32); |
|||
return mask_32bit((x>>n)|(x<<(32-n))); |
|||
} |
|||
|
|||
inline uint32_t bsig0(uint32_t x){ |
|||
return rotr(x, 2)^rotr(x, 13)^rotr(x, 22); |
|||
} |
|||
|
|||
inline uint32_t bsig1(uint32_t x){ |
|||
return rotr(x, 6)^rotr(x, 11)^rotr(x, 25); |
|||
} |
|||
|
|||
inline uint32_t shr(uint32_t x, std::size_t n){ |
|||
assert(n < 32); |
|||
return x >> n; |
|||
} |
|||
|
|||
inline uint32_t ssig0(uint32_t x){ |
|||
return rotr(x, 7)^rotr(x, 18)^shr(x, 3); |
|||
} |
|||
|
|||
inline uint32_t ssig1(uint32_t x){ |
|||
return rotr(x, 17)^rotr(x, 19)^shr(x, 10); |
|||
} |
|||
|
|||
template<typename RaIter1, typename RaIter2> |
|||
void hash256_block(RaIter1 message_digest, RaIter2 first, RaIter2 last){ |
|||
(void)last; // FIXME: check this is valid
|
|||
uint32_t w[64]; |
|||
std::fill(w, w+64, 0); |
|||
for(std::size_t i = 0; i < 16; ++i){ |
|||
w[i] = (static_cast<uint32_t>(mask_8bit(*(first+i*4)))<<24) |
|||
|(static_cast<uint32_t>(mask_8bit(*(first+i*4+1)))<<16) |
|||
|(static_cast<uint32_t>(mask_8bit(*(first+i*4+2)))<<8) |
|||
|(static_cast<uint32_t>(mask_8bit(*(first+i*4+3)))); |
|||
} |
|||
for(std::size_t i = 16; i < 64; ++i){ |
|||
w[i] = mask_32bit(ssig1(w[i-2])+w[i-7]+ssig0(w[i-15])+w[i-16]); |
|||
} |
|||
|
|||
uint32_t a = *message_digest; |
|||
uint32_t b = *(message_digest+1); |
|||
uint32_t c = *(message_digest+2); |
|||
uint32_t d = *(message_digest+3); |
|||
uint32_t e = *(message_digest+4); |
|||
uint32_t f = *(message_digest+5); |
|||
uint32_t g = *(message_digest+6); |
|||
uint32_t h = *(message_digest+7); |
|||
|
|||
for(std::size_t i = 0; i < 64; ++i){ |
|||
uint32_t temp1 = h+bsig1(e)+ch(e,f,g)+add_constant[i]+w[i]; |
|||
uint32_t temp2 = bsig0(a)+maj(a,b,c); |
|||
h = g; |
|||
g = f; |
|||
f = e; |
|||
e = mask_32bit(d+temp1); |
|||
d = c; |
|||
c = b; |
|||
b = a; |
|||
a = mask_32bit(temp1+temp2); |
|||
} |
|||
*message_digest += a; |
|||
*(message_digest+1) += b; |
|||
*(message_digest+2) += c; |
|||
*(message_digest+3) += d; |
|||
*(message_digest+4) += e; |
|||
*(message_digest+5) += f; |
|||
*(message_digest+6) += g; |
|||
*(message_digest+7) += h; |
|||
for(std::size_t i = 0; i < 8; ++i){ |
|||
*(message_digest+i) = mask_32bit(*(message_digest+i)); |
|||
} |
|||
} |
|||
|
|||
}//namespace detail
|
|||
|
|||
template<typename InIter> |
|||
void output_hex(InIter first, InIter last, std::ostream& os){ |
|||
os.setf(std::ios::hex, std::ios::basefield); |
|||
while(first != last){ |
|||
os.width(2); |
|||
os.fill('0'); |
|||
os << static_cast<unsigned int>(*first); |
|||
++first; |
|||
} |
|||
os.setf(std::ios::dec, std::ios::basefield); |
|||
} |
|||
|
|||
template<typename InIter> |
|||
void bytes_to_hex_string(InIter first, InIter last, std::string& hex_str){ |
|||
std::ostringstream oss; |
|||
output_hex(first, last, oss); |
|||
hex_str.assign(oss.str()); |
|||
} |
|||
|
|||
template<typename InContainer> |
|||
void bytes_to_hex_string(const InContainer& bytes, std::string& hex_str){ |
|||
bytes_to_hex_string(bytes.begin(), bytes.end(), hex_str); |
|||
} |
|||
|
|||
template<typename InIter> |
|||
std::string bytes_to_hex_string(InIter first, InIter last){ |
|||
std::string hex_str; |
|||
bytes_to_hex_string(first, last, hex_str); |
|||
return hex_str; |
|||
} |
|||
|
|||
template<typename InContainer> |
|||
std::string bytes_to_hex_string(const InContainer& bytes){ |
|||
std::string hex_str; |
|||
bytes_to_hex_string(bytes, hex_str); |
|||
return hex_str; |
|||
} |
|||
|
|||
class hash256_one_by_one { |
|||
public: |
|||
hash256_one_by_one(){ |
|||
init(); |
|||
} |
|||
|
|||
void init(){ |
|||
buffer_.clear(); |
|||
std::fill(data_length_digits_, data_length_digits_+4, 0); |
|||
std::copy(detail::initial_message_digest, detail::initial_message_digest+8, h_); |
|||
} |
|||
|
|||
template<typename RaIter> |
|||
void process(RaIter first, RaIter last){ |
|||
add_to_data_length(std::distance(first, last)); |
|||
std::copy(first, last, std::back_inserter(buffer_)); |
|||
std::size_t i = 0; |
|||
for(;i+64 <= buffer_.size(); i+=64){ |
|||
detail::hash256_block(h_, buffer_.begin()+i, buffer_.begin()+i+64); |
|||
} |
|||
buffer_.erase(buffer_.begin(), buffer_.begin()+i); |
|||
} |
|||
|
|||
void finish(){ |
|||
uint8_t temp[64]; |
|||
std::fill(temp, temp+64, 0); |
|||
std::size_t remains = buffer_.size(); |
|||
std::copy(buffer_.begin(), buffer_.end(), temp); |
|||
temp[remains] = 0x80; |
|||
|
|||
if(remains > 55){ |
|||
std::fill(temp+remains+1, temp+64, 0); |
|||
detail::hash256_block(h_, temp, temp+64); |
|||
std::fill(temp, temp+64-4, 0); |
|||
} |
|||
else { |
|||
std::fill(temp+remains+1, temp+64-4, 0); |
|||
} |
|||
|
|||
write_data_bit_length(&(temp[56])); |
|||
detail::hash256_block(h_, temp, temp+64); |
|||
} |
|||
|
|||
template<typename OutIter> |
|||
void get_hash_bytes(OutIter first, OutIter last)const{ |
|||
for(const uint32_t* iter = h_; iter != h_+8; ++iter){ |
|||
for(std::size_t i = 0; i < 4 && first != last; ++i){ |
|||
*(first++) = detail::mask_8bit(static_cast<uint8_t>((*iter >> (24-8*i)))); |
|||
} |
|||
} |
|||
} |
|||
|
|||
private: |
|||
void add_to_data_length(uint32_t n) { |
|||
uint32_t carry = 0; |
|||
data_length_digits_[0] += n; |
|||
for(std::size_t i = 0; i < 4; ++i) { |
|||
data_length_digits_[i] += carry; |
|||
if(data_length_digits_[i] >= 65536u) { |
|||
data_length_digits_[i] -= 65536u; |
|||
carry = 1; |
|||
} |
|||
else { |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
void write_data_bit_length(uint8_t* begin) { |
|||
uint32_t data_bit_length_digits[4]; |
|||
std::copy( |
|||
data_length_digits_, data_length_digits_+4, |
|||
data_bit_length_digits |
|||
); |
|||
|
|||
// convert byte length to bit length (multiply 8 or shift 3 times left)
|
|||
uint32_t carry = 0; |
|||
for(std::size_t i = 0; i < 4; ++i) { |
|||
uint32_t before_val = data_bit_length_digits[i]; |
|||
data_bit_length_digits[i] <<= 3; |
|||
data_bit_length_digits[i] |= carry; |
|||
data_bit_length_digits[i] &= 65535u; |
|||
carry = (before_val >> (16-3)) & 65535u; |
|||
} |
|||
|
|||
// write data_bit_length
|
|||
for(int i = 3; i >= 0; --i) { |
|||
(*begin++) = static_cast<uint8_t>(data_bit_length_digits[i] >> 8); |
|||
(*begin++) = static_cast<uint8_t>(data_bit_length_digits[i]); |
|||
} |
|||
} |
|||
std::vector<uint8_t> buffer_; |
|||
uint32_t data_length_digits_[4]; //as 64bit integer (16bit x 4 integer)
|
|||
uint32_t h_[8]; |
|||
}; |
|||
|
|||
inline void get_hash_hex_string(const hash256_one_by_one& hasher, std::string& hex_str){ |
|||
uint8_t hash[32]; |
|||
hasher.get_hash_bytes(hash, hash+32); |
|||
return bytes_to_hex_string(hash, hash+32, hex_str); |
|||
} |
|||
|
|||
inline std::string get_hash_hex_string(const hash256_one_by_one& hasher){ |
|||
std::string hex_str; |
|||
get_hash_hex_string(hasher, hex_str); |
|||
return hex_str; |
|||
} |
|||
|
|||
template<typename RaIter, typename OutIter> |
|||
void hash256(RaIter first, RaIter last, OutIter first2, OutIter last2){ |
|||
hash256_one_by_one hasher; |
|||
//hasher.init();
|
|||
hasher.process(first, last); |
|||
hasher.finish(); |
|||
hasher.get_hash_bytes(first2, last2); |
|||
} |
|||
|
|||
template<typename RaIter, typename OutContainer> |
|||
void hash256(RaIter first, RaIter last, OutContainer& dst){ |
|||
hash256(first, last, dst.begin(), dst.end()); |
|||
} |
|||
|
|||
template<typename RaContainer, typename OutIter> |
|||
void hash256(const RaContainer& src, OutIter first, OutIter last){ |
|||
hash256(src.begin(), src.end(), first, last); |
|||
} |
|||
|
|||
template<typename RaContainer, typename OutContainer> |
|||
void hash256(const RaContainer& src, OutContainer& dst){ |
|||
hash256(src.begin(), src.end(), dst.begin(), dst.end()); |
|||
} |
|||
|
|||
|
|||
template<typename RaIter> |
|||
void hash256_hex_string(RaIter first, RaIter last, std::string& hex_str){ |
|||
uint8_t hashed[32]; |
|||
hash256(first, last, hashed, hashed+32); |
|||
std::ostringstream oss; |
|||
output_hex(hashed, hashed+32, oss); |
|||
hex_str.assign(oss.str()); |
|||
} |
|||
|
|||
template<typename RaIter> |
|||
std::string hash256_hex_string(RaIter first, RaIter last){ |
|||
std::string hex_str; |
|||
hash256_hex_string(first, last, hex_str); |
|||
return hex_str; |
|||
} |
|||
|
|||
inline void hash256_hex_string(const std::string& src, std::string& hex_str){ |
|||
hash256_hex_string(src.begin(), src.end(), hex_str); |
|||
} |
|||
|
|||
template<typename RaContainer> |
|||
void hash256_hex_string(const RaContainer& src, std::string& hex_str){ |
|||
hash256_hex_string(src.begin(), src.end(), hex_str); |
|||
} |
|||
|
|||
template<typename RaContainer> |
|||
std::string hash256_hex_string(const RaContainer& src){ |
|||
return hash256_hex_string(src.begin(), src.end()); |
|||
} |
|||
|
|||
}//namespace picosha2
|
|||
|
|||
#endif //PICOSHA2_H
|
@ -1,129 +0,0 @@ |
|||
/*
|
|||
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 SHA3.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#include "SHA3.h" |
|||
|
|||
#include <libdevcore/RLP.h> |
|||
#include "CryptoPP.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
|
|||
namespace dev |
|||
{ |
|||
|
|||
h256 EmptySHA3 = sha3(bytesConstRef()); |
|||
h256 EmptyListSHA3 = sha3(rlpList()); |
|||
|
|||
std::string sha3(std::string const& _input, bool _hex) |
|||
{ |
|||
if (!_hex) |
|||
{ |
|||
string ret(32, '\0'); |
|||
sha3(bytesConstRef((byte const*)_input.data(), _input.size()), bytesRef((byte*)ret.data(), 32)); |
|||
return ret; |
|||
} |
|||
|
|||
uint8_t buf[32]; |
|||
sha3(bytesConstRef((byte const*)_input.data(), _input.size()), bytesRef((byte*)&(buf[0]), 32)); |
|||
std::string ret(64, '\0'); |
|||
for (unsigned int i = 0; i < 32; i++) |
|||
sprintf((char*)(ret.data())+i*2, "%02x", buf[i]); |
|||
return ret; |
|||
} |
|||
|
|||
void sha3(bytesConstRef _input, bytesRef _output) |
|||
{ |
|||
CryptoPP::SHA3_256 ctx; |
|||
ctx.Update((byte*)_input.data(), _input.size()); |
|||
assert(_output.size() >= 32); |
|||
ctx.Final(_output.data()); |
|||
} |
|||
|
|||
void ripemd160(bytesConstRef _input, bytesRef _output) |
|||
{ |
|||
CryptoPP::RIPEMD160 ctx; |
|||
ctx.Update((byte*)_input.data(), _input.size()); |
|||
assert(_output.size() >= 32); |
|||
ctx.Final(_output.data()); |
|||
} |
|||
|
|||
void sha256(bytesConstRef _input, bytesRef _output) |
|||
{ |
|||
CryptoPP::SHA256 ctx; |
|||
ctx.Update((byte*)_input.data(), _input.size()); |
|||
assert(_output.size() >= 32); |
|||
ctx.Final(_output.data()); |
|||
} |
|||
|
|||
bytes sha3Bytes(bytesConstRef _input) |
|||
{ |
|||
bytes ret(32); |
|||
sha3(_input, &ret); |
|||
return ret; |
|||
} |
|||
|
|||
h256 sha3(bytesConstRef _input) |
|||
{ |
|||
h256 ret; |
|||
sha3(_input, bytesRef(&ret[0], 32)); |
|||
return ret; |
|||
} |
|||
|
|||
void sha3mac(bytesConstRef _secret, bytesConstRef _plain, bytesRef _output) |
|||
{ |
|||
CryptoPP::SHA3_256 ctx; |
|||
assert(_secret.size() > 0); |
|||
ctx.Update((byte*)_secret.data(), _secret.size()); |
|||
ctx.Update((byte*)_plain.data(), _plain.size()); |
|||
assert(_output.size() >= 32); |
|||
ctx.Final(_output.data()); |
|||
} |
|||
|
|||
bytes aesDecrypt(bytesConstRef _ivCipher, std::string const& _password, unsigned _rounds, bytesConstRef _salt) |
|||
{ |
|||
bytes pw = asBytes(_password); |
|||
|
|||
if (!_salt.size()) |
|||
_salt = &pw; |
|||
|
|||
bytes target(64); |
|||
CryptoPP::PKCS5_PBKDF2_HMAC<CryptoPP::SHA256>().DeriveKey(target.data(), target.size(), 0, pw.data(), pw.size(), _salt.data(), _salt.size(), _rounds); |
|||
|
|||
try |
|||
{ |
|||
CryptoPP::AES::Decryption aesDecryption(target.data(), 16); |
|||
auto cipher = _ivCipher.cropped(16); |
|||
auto iv = _ivCipher.cropped(0, 16); |
|||
CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption(aesDecryption, iv.data()); |
|||
std::string decrypted; |
|||
CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink(decrypted)); |
|||
stfDecryptor.Put(cipher.data(), cipher.size()); |
|||
stfDecryptor.MessageEnd(); |
|||
return asBytes(decrypted); |
|||
} |
|||
catch (exception const& e) |
|||
{ |
|||
cerr << e.what() << endl; |
|||
return bytes(); |
|||
} |
|||
} |
|||
|
|||
} |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue