Skip to content
Permalink
Browse files

Introducing Chukwa: TurtleCoin's Argon2id PoW

- Argon2 Implementation from: https://github.com/WOnder93/argon2
  - Updated CPU feature detection
- Chukwa - Argon2id Properties: 512KB, 1 parallelism, 3 iterations.
- Hard Fork @ block 1,800,000
- Difficulty reset at block 1,800,000
  • Loading branch information...
brandonlehmann committed Jul 28, 2019
1 parent 26e395f commit 50493df83d1c4ec92912a854e8e4b30571596c1e
Showing with 8,395 additions and 20 deletions.
  1. +1 −1 CMakeLists.txt
  2. +3 −2 external/CMakeLists.txt
  3. +2 −0 external/argon2/.gitattributes
  4. +69 −0 external/argon2/.gitignore
  5. +23 −0 external/argon2/.travis.yml
  6. +91 −0 external/argon2/CMakeLists.txt
  7. +21 −0 external/argon2/LICENSE
  8. +125 −0 external/argon2/Makefile.am
  9. +58 −0 external/argon2/README.md
  10. +20 −0 external/argon2/arch/generic/lib/argon2-arch.c
  11. +38 −0 external/argon2/arch/x86_64/lib/argon2-arch.c
  12. +342 −0 external/argon2/arch/x86_64/lib/argon2-avx2.c
  13. +11 −0 external/argon2/arch/x86_64/lib/argon2-avx2.h
  14. +327 −0 external/argon2/arch/x86_64/lib/argon2-avx512f.c
  15. +11 −0 external/argon2/arch/x86_64/lib/argon2-avx512f.h
  16. +125 −0 external/argon2/arch/x86_64/lib/argon2-sse2.c
  17. +11 −0 external/argon2/arch/x86_64/lib/argon2-sse2.h
  18. +137 −0 external/argon2/arch/x86_64/lib/argon2-sse3.c
  19. +11 −0 external/argon2/arch/x86_64/lib/argon2-sse3.h
  20. +134 −0 external/argon2/arch/x86_64/lib/argon2-ssse3.c
  21. +11 −0 external/argon2/arch/x86_64/lib/argon2-ssse3.h
  22. +164 −0 external/argon2/arch/x86_64/lib/argon2-template-128.h
  23. +123 −0 external/argon2/arch/x86_64/lib/argon2-xop.c
  24. +11 −0 external/argon2/arch/x86_64/lib/argon2-xop.h
  25. +13 −0 external/argon2/arch/x86_64/lib/sse_shim.h
  26. +205 −0 external/argon2/cmake/AddCompilerFlag.cmake
  27. +73 −0 external/argon2/cmake/CheckCCompilerFlag.cmake
  28. +73 −0 external/argon2/cmake/CheckCXXCompilerFlag.cmake
  29. +101 −0 external/argon2/cmake/CheckMicCCompilerFlag.cmake
  30. +101 −0 external/argon2/cmake/CheckMicCXXCompilerFlag.cmake
  31. +607 −0 external/argon2/cmake/OptimizeForArchitecture.cmake
  32. +108 −0 external/argon2/configure.ac
  33. +478 −0 external/argon2/include/argon2.h
  34. +193 −0 external/argon2/lib/argon2-template-64.h
  35. +476 −0 external/argon2/lib/argon2.c
  36. +90 −0 external/argon2/lib/blake2/blake2-impl.h
  37. +225 −0 external/argon2/lib/blake2/blake2.c
  38. +30 −0 external/argon2/lib/blake2/blake2.h
  39. +633 −0 external/argon2/lib/core.c
  40. +226 −0 external/argon2/lib/core.h
  41. +432 −0 external/argon2/lib/encoding.c
  42. +40 −0 external/argon2/lib/encoding.h
  43. +117 −0 external/argon2/lib/genkat.c
  44. +47 −0 external/argon2/lib/genkat.h
  45. +120 −0 external/argon2/lib/impl-select.c
  46. +23 −0 external/argon2/lib/impl-select.h
  47. +36 −0 external/argon2/lib/thread.c
  48. +47 −0 external/argon2/lib/thread.h
  49. +74 −0 external/argon2/m4/ax_check_compile_flag.m4
  50. +485 −0 external/argon2/m4/ax_pthread.m4
  51. +3 −0 external/argon2/qmake/arch/arch.pro
  52. +1 −0 external/argon2/qmake/arch/generic/generic.pro
  53. +23 −0 external/argon2/qmake/arch/x86_64/libargon2-avx2/libargon2-avx2.pro
  54. +23 −0 external/argon2/qmake/arch/x86_64/libargon2-avx512f/libargon2-avx512f.pro
  55. +24 −0 external/argon2/qmake/arch/x86_64/libargon2-sse2/libargon2-sse2.pro
  56. +24 −0 external/argon2/qmake/arch/x86_64/libargon2-ssse3/libargon2-ssse3.pro
  57. +24 −0 external/argon2/qmake/arch/x86_64/libargon2-xop/libargon2-xop.pro
  58. +8 −0 external/argon2/qmake/arch/x86_64/x86_64.pro
  59. +19 −0 external/argon2/qmake/argon2-bench2/argon2-bench2.pro
  60. +16 −0 external/argon2/qmake/argon2-genkat/argon2-genkat.pro
  61. +16 −0 external/argon2/qmake/argon2-test/argon2-test.pro
  62. +9 −0 external/argon2/qmake/argon2.pro
  63. +18 −0 external/argon2/qmake/argon2/argon2.pro
  64. +119 −0 external/argon2/qmake/libargon2/libargon2.pro
  65. +12 −0 external/argon2/scripts/metacentrum/start-all-benchmarks.sh
  66. +75 −0 external/argon2/scripts/metacentrum/start-benchmark.sh
  67. +40 −0 external/argon2/scripts/run-benchmark.sh
  68. +179 −0 external/argon2/src/bench2.c
  69. +90 −0 external/argon2/src/genkat.c
  70. +315 −0 external/argon2/src/run.c
  71. +41 −0 external/argon2/src/timing.h
  72. +239 −0 external/argon2/tests/test.c
  73. +2 −0 src/CMakeLists.txt
  74. +22 −5 src/config/CryptoNoteConfig.h
  75. +32 −0 src/crypto/hash.h
  76. +1 −0 src/cryptonotecore/BlockchainCache.cpp
  77. +1 −0 src/cryptonotecore/Core.cpp
  78. +21 −9 src/cryptonotecore/Currency.cpp
  79. +8 −0 src/cryptonotecore/Currency.h
  80. +1 −0 src/cryptonotecore/DatabaseBlockchainCache.cpp
  81. +49 −1 src/cryptonotecore/Difficulty.cpp
  82. +8 −0 src/cryptonotecore/Difficulty.h
  83. +8 −0 src/cryptotest/main.cpp
  84. +1 −1 src/serialization/CryptoNoteSerialization.cpp
  85. +1 −1 src/utilities/FormatTools.cpp
@@ -169,7 +169,7 @@ if (NOT MSVC)
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
set(WARNINGS "${WARNINGS} -Wno-error=odr")
endif ()
set(C_WARNINGS "-Waggregate-return -Wnested-externs -Wold-style-definition -Wstrict-prototypes")
set(C_WARNINGS "-Waggregate-return -Wnested-externs -Wold-style-definition -Wstrict-prototypes -Wno-implicit-fallthrough")
set(CXX_WARNINGS "-Wno-reorder -Wno-missing-field-initializers")

if (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64" OR "${LABEL}" STREQUAL "aarch64")
@@ -7,12 +7,13 @@ add_subdirectory(miniupnpc)
add_subdirectory(cryptopp)
add_subdirectory(sqlite3)
add_subdirectory(lz4)
add_subdirectory(argon2)

if (MSVC)
add_subdirectory(rocksDB EXCLUDE_FROM_ALL)
set_property(TARGET upnpc-static cryptopp-static rocksdb sqlite3 lz4 PROPERTY FOLDER "external")
set_property(TARGET upnpc-static cryptopp-static rocksdb sqlite3 lz4 argon2 PROPERTY FOLDER "external")
elseif (NOT MSVC)
set_property(TARGET upnpc-static cryptopp-static sqlite3 lz4 PROPERTY FOLDER "external")
set_property(TARGET upnpc-static cryptopp-static sqlite3 lz4 argon2 PROPERTY FOLDER "external")
add_custom_target(
rocksdb
COMMAND $(MAKE) rocksdb
@@ -0,0 +1,2 @@
*.h linguist-language=C
*.pro linguist-language=QMake
@@ -0,0 +1,69 @@
# Compiled Object files
*.slo
*.lo
*.o
*.obj

# Precompiled Headers
*.gch
*.pch

# Compiled Dynamic libraries
*.so
*.dylib
*.dll

# Fortran module files
*.mod

# Compiled Static libraries
*.lai
*.la
*.a
*.lib

# Executables
*.exe
*.out
*.app

# Autotools + Libtool
/aclocal.m4
/config.status
/config
/install-sh
**/Makefile
**/Makefile.in
/autom4te.cache/
/compile
/config.guess
/config.log
/config.sub
/configure
/depcomp
/libtool
/ltmain.sh
/m4/libtool.m4
/m4/lt*.m4
/missing
/test-driver
**/.deps/
**/.dirstamp
**/.libs/

# Qt Creator
**/*.user
**/*.user.*
**/build-*/

# KDE
**/.directory

# Vim
*.swp

# CMake
CMakeFiles/
CMakeCache.txt
Makefile

@@ -0,0 +1,23 @@
language: c

dist: trusty
sudo: false

compiler:
- clang
- gcc

env:
- BUILD=cmake BUILD_TYPE=Debug
- BUILD=cmake BUILD_TYPE=Release
- BUILD=autotools

script: |
case $BUILD in
cmake)
cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE . && make && make test
;;
autotools)
autoreconf -i && ./configure && make && make check
;;
esac
@@ -0,0 +1,91 @@
cmake_minimum_required(VERSION 2.6)

find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
message(STATUS "-- Argon2: Found ccache package... Activating...")
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
endif()

project(Argon2 C)

set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})

set(ARGON2_VERSION 1.0)
set(CMAKE_C_STANDARD 90)
set(CMAKE_C_STANDARD_REQUIRED ON)

include(CheckCSourceCompiles)
find_package(Threads REQUIRED)

add_library(argon2-interface INTERFACE)
target_include_directories(argon2-interface INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)

add_library(argon2-internal INTERFACE)
target_include_directories(argon2-internal INTERFACE lib lib/blake2)
target_link_libraries(argon2-internal INTERFACE argon2-interface)

set(ARGON2_SRC
lib/argon2.c
lib/core.c
lib/encoding.c
lib/genkat.c
lib/impl-select.c
lib/thread.c
lib/blake2/blake2.c
)

message("-- Argon2: Processor: ${CMAKE_SYSTEM_PROCESSOR}")
message("-- Argon2: Build Type: ${ARCH}")

if(NOT "${ARCH}" STREQUAL "default")
include(OptimizeForArchitecture)
OptimizeForArchitecture()

if (MSVC)
# Needed by MSVC, but not added by OptimizeForArchitexture()
add_definitions(-D__SSE__)
endif()
endif()

foreach(flag ${Vc_ARCHITECTURE_FLAGS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
endforeach()

message(STATUS "-- Argon2: Build Flags: ${CMAKE_CXX_FLAGS}")

if(USE_AVX512F OR USE_AVX2 OR USE_SSE3 OR USE_SSE2 OR USE_XOP)
list(APPEND ARGON2_SRC
arch/x86_64/lib/argon2-sse2.c
arch/x86_64/lib/argon2-sse3.c
arch/x86_64/lib/argon2-xop.c
arch/x86_64/lib/argon2-avx2.c
arch/x86_64/lib/argon2-avx512f.c
arch/x86_64/lib/argon2-arch.c
)
else()
list(APPEND ARGON2_SRC
arch/generic/lib/argon2-arch.c
)
endif()

add_library(argon2 STATIC ${ARGON2_SRC})

target_compile_definitions(argon2
PUBLIC "A2_VISCTL"
)

target_link_libraries(argon2
PUBLIC argon2-interface ${CMAKE_THREAD_LIBS_INIT}
PRIVATE argon2-internal
)

set_property(TARGET argon2 PROPERTY C_STANDARD 90)
set_property(TARGET argon2 PROPERTY VERSION ${Upstream_VERSION})
set_property(TARGET argon2 PROPERTY SOVERSION 1)
set_property(TARGET argon2 PROPERTY INTERFACE_ARGON2_MAJOR_VERSION 1)
set_property(TARGET argon2 APPEND PROPERTY
COMPATIBLE_INTERFACE_STRING ARGON2_MAJOR_VERSION
)
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2016 Ondrej Mosnáček

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.
@@ -0,0 +1,125 @@
ACLOCAL_AMFLAGS = -I m4

include_HEADERS = include/argon2.h
lib_LTLIBRARIES = libargon2.la
noinst_LTLIBRARIES =

bin_PROGRAMS = argon2
noinst_PROGRAMS = argon2-genkat argon2-bench2 argon2-test

TESTS = argon2-test

AM_CPPFLAGS = \
-I$(srcdir)/include \
-I$(srcdir)/lib \
-I$(srcdir)/arch/@ARCH@/include \
-I$(srcdir)/arch/@ARCH@/lib

libargon2_la_CFLAGS = @PTHREAD_CFLAGS@
libargon2_la_LIBADD = @PTHREAD_LIBS@
libargon2_la_SOURCES = \
lib/argon2.c \
lib/core.c \
lib/encoding.c \
lib/genkat.c \
lib/impl-select.c \
lib/thread.c \
lib/blake2/blake2.c \
lib/argon2-template-64.h \
lib/core.h \
lib/encoding.h \
lib/genkat.h \
lib/impl-select.h \
lib/thread.h \
lib/blake2/blake2.h \
lib/blake2/blake2-impl.h

if ARCH_X86_64
noinst_LTLIBRARIES += \
libargon2-sse2.la \
libargon2-ssse3.la \
libargon2-xop.la \
libargon2-avx2.la \
libargon2-avx512f.la
libargon2_la_LIBADD += \
libargon2-sse2.la \
libargon2-ssse3.la \
libargon2-xop.la \
libargon2-avx2.la \
libargon2-avx512f.la

libargon2_sse2_la_SOURCES = \
arch/@ARCH@/lib/argon2-sse2.c \
arch/@ARCH@/lib/argon2-sse2.h \
arch/@ARCH@/lib/argon2-template-128.h
libargon2_sse2_la_CPPFLAGS = $(AM_CPPFLAGS)
libargon2_sse2_la_CFLAGS = $(AM_CFLAGS)
if HAVE_SSE2
libargon2_sse2_la_CPPFLAGS += -DHAVE_SSE2
libargon2_sse2_la_CFLAGS += -msse2
endif # HAVE_SSE2

libargon2_ssse3_la_SOURCES = \
arch/@ARCH@/lib/argon2-ssse3.c \
arch/@ARCH@/lib/argon2-ssse3.h \
arch/@ARCH@/lib/argon2-template-128.h
libargon2_ssse3_la_CPPFLAGS = $(AM_CPPFLAGS)
libargon2_ssse3_la_CFLAGS = $(AM_CFLAGS)
if HAVE_SSSE3
libargon2_ssse3_la_CPPFLAGS += -DHAVE_SSSE3
libargon2_ssse3_la_CFLAGS += -mssse3
endif # HAVE_SSSE3

libargon2_xop_la_SOURCES = \
arch/@ARCH@/lib/argon2-xop.c \
arch/@ARCH@/lib/argon2-xop.h \
arch/@ARCH@/lib/argon2-template-128.h
libargon2_xop_la_CPPFLAGS = $(AM_CPPFLAGS)
libargon2_xop_la_CFLAGS = $(AM_CFLAGS)
if HAVE_XOP
libargon2_xop_la_CPPFLAGS += -DHAVE_XOP
libargon2_xop_la_CFLAGS += -mxop
endif # HAVE_XOP

libargon2_avx2_la_SOURCES = \
arch/@ARCH@/lib/argon2-avx2.c \
arch/@ARCH@/lib/argon2-avx2.h
libargon2_avx2_la_CPPFLAGS = $(AM_CPPFLAGS)
libargon2_avx2_la_CFLAGS = $(AM_CFLAGS)
if HAVE_AVX2
libargon2_avx2_la_CPPFLAGS += -DHAVE_AVX2
libargon2_avx2_la_CFLAGS += -mavx2
endif # HAVE_AVX2

libargon2_avx512f_la_SOURCES = \
arch/@ARCH@/lib/argon2-avx512f.c \
arch/@ARCH@/lib/argon2-avx512f.h
libargon2_avx512f_la_CPPFLAGS = $(AM_CPPFLAGS)
libargon2_avx512f_la_CFLAGS = $(AM_CFLAGS)
if HAVE_AVX512F
libargon2_avx512f_la_CPPFLAGS += -DHAVE_AVX512F
libargon2_avx512f_la_CFLAGS += -mavx512f
endif # HAVE_AVX512F

libargon2_la_SOURCES += \
arch/@ARCH@/lib/argon2-arch.c \
arch/@ARCH@/lib/cpu-flags.c \
arch/@ARCH@/lib/cpu-flags.h
endif # ARCH_X86_64

if ARCH_GENERIC
libargon2_la_SOURCES += \
arch/@ARCH@/lib/argon2-arch.c
endif # ARCH_GENERIC

argon2_LDADD = libargon2.la
argon2_SOURCES = src/run.c lib/core.h

argon2_genkat_LDADD = libargon2.la
argon2_genkat_SOURCES = src/genkat.c

argon2_bench2_LDADD = libargon2.la -lrt
argon2_bench2_SOURCES = src/bench2.c src/timing.h

argon2_test_LDADD = libargon2.la
argon2_test_SOURCES = tests/test.c

4 comments on commit 50493df

@bobbieltd

This comment has been minimized.

Copy link

replied Aug 8, 2019

Hi !
If I'm not wrong, the difficulty reset codes seems wrong. It will drown the difficulty to 0 very quickly.
let count = 1;
for (i=0;i<60;++i) {count = count*(0.9*i/60+0.1)}
the result of count is 1/1^20
current turtlecoin network difficulty is 1^10
so network diffculty will tumble to zero halfway and difficulty overhead.

@brandonlehmann

This comment has been minimized.

Copy link
Collaborator Author

replied Aug 8, 2019

if (blockIndex >= CryptoNote::parameters::DIFFICULTY_RESET_HEIGHT_V1 (1800000) 
  && blockIndex < CryptoNote::parameters::DIFFICULTY_RESET_HEIGHT_V1 + 
  CryptoNote::parameters::DIFFICULTY_RESET_WINDOW_V1 (1800000 + 61) )

It's important to understand what's going on here

calculateDifficultyResetMultiplier(blockIndex, DIFFICULTY_RESET_HEIGHT_V1 (1800000), 
  DIFFICULTY_RESET_WINDOW_V1 (60 + 1 = 61),
  DIFFICULTY_RESET_MULTIPLIER_V1 (0.1)

currentDifficultyResetDepth = blockIndex - DIFFICULTY_RESET_HEIGHT_V1
currentDifficultyResetDepthPercent = currentDifficultyResetDepth / DIFFICULTY_RESET_WINDOW_V1
currentDifficultyReduction = 1 - DIFFICULTY_RESET_MULTIPLIER_V1
currentDifficultyMultiplier = (currentDifficultyResetDepthPercent * currentDifficultyReduction) 
  + DIFFICULTY_RESET_MULTIPLIER_V1

newDiff = (nextDifficulty * currentDifficultyMultiplier)

So let's plug in some numbers

Assuming current difficulty: 11,332,392,328

At block 1800000:

currentDifficultyResetDepth = 1800000 - 1800000 = 0
currentDifficultyResetDepthPercent = 0 / 61 = 0
currentDifficultyReduction = 1 - 0.1 = 0.9
currentDifficultyMultiplier = (0 * 0.9) + 0.1 = 0.1

newDiff = 11,332,392,328 * 0.1 = 1,133,239,232.8 (90% reduction)

At block 1800010:

currentDifficultyResetDepth = 1800010 - 1800000 = 10
currentDifficultyResetDepthPercent = 10 / 61 = 0.1639
currentDifficultyReduction = 1 - 0.1 = 0.9
currentDifficultyMultiplier = (0.1639 * 0.9) + 0.1 = 0.24751

newDiff = 11,332,392,328 * 0.24751 = 2,804,880,425.1

At block 1800030:

currentDifficultyResetDepth = 1800030 - 1800000 = 30
currentDifficultyResetDepthPercent = 30 / 61 = 0.4918
currentDifficultyReduction = 1 - 0.1 = 0.9
currentDifficultyMultiplier = (0.4918 * 0.9) + 0.1 = 0.5426

newDiff = 11,332,392,328 * 0.5426 = 6,148,956,077.1

Difficulty actually climbs back up as designed.

The important piece that you may not realize is that difficulty is not calculated based on the past difficulty (as shown in your example of shadowing count). It's calculated based upon the delta in time between the last WINDOW blocks (60 in our case). We aren't changing how difficulty is calculated (it's still LWMA2) -- we're just using a % of LWMA2's calculation over the difficulty window (60 blocks) to allow the network to handle the drop in hashrate and then come back to 100% of what LWMA2 calculates.

@brandonlehmann

This comment has been minimized.

Copy link
Collaborator Author

replied Aug 8, 2019

In any event, even if LWMA2 drops difficulty down to 10K 1/2 way through the window -- we'd still be only adjusting it by ~ 50%. And we always take at LEAST 10% of what LWMA2 recommends.

Thus, we may run up to 60 fast blocks -- but at least we won't be mining for a week waiting for the next block. If; however, we didn't always add 0.1 to the multiplier then we'd be having an entirely different conversation :)

@bobbieltd

This comment has been minimized.

Copy link

replied Aug 8, 2019

Wow. Thanks for very detail explanation.

Please sign in to comment.
You can’t perform that action at this time.