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(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
} |
|
File diff suppressed because it is too large
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue