├── .clang-format ├── .gitignore ├── .gitmodules ├── .travis.yml ├── CMakeLists.txt ├── LICENSE ├── README.md ├── ccurl.pc.in ├── scripts ├── aws-ubuntU1604-gpu-setup.bash └── ccurl_pow ├── src ├── cli │ ├── CMakeLists.txt │ ├── README.md │ ├── ccurl-digest.c │ ├── ccurl.c │ ├── ccurl.h │ ├── ccurld.c │ ├── long-to-trytes.c │ ├── trytes-to-long.c │ └── trytes-to-trits.c └── lib │ ├── bct_curl.h │ ├── ccurl.h │ ├── cl │ └── pearl.cl │ ├── claccess │ ├── CMakeLists.txt │ ├── clcontext.c │ └── clcontext.h │ ├── constants.h │ ├── curl.c │ ├── curl.h │ ├── exports.c │ ├── exports_cl.c │ ├── hash.h │ ├── pearcldiver.c │ ├── pearcldiver.h │ ├── pearl_diver.c │ ├── pearl_diver.h │ ├── transaction.h │ └── util │ ├── CMakeLists.txt │ ├── converter.c │ └── converter.h └── test ├── CMakeLists.txt ├── cunit_include.c ├── cunit_include.h ├── random_trits.c ├── random_trits.h ├── test_curl.c ├── test_pearcldiver.c └── test_pearldiver.c /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | # We'll use defaults from the LLVM style, but with 4 columns indentation. 3 | BasedOnStyle: LLVM 4 | IndentWidth: 2 5 | --- 6 | Language: Cpp 7 | # Force pointers to the type for C++. 8 | DerivePointerAlignment: false 9 | PointerAlignment: Left 10 | --- 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Makefile 2 | cmake_install.cmake 3 | CTestTestfile.cmake 4 | Testing 5 | bin 6 | CMakeFiles 7 | CMakeCache.txt 8 | .ninja* 9 | *ninja* 10 | *.swp 11 | vgcore* 12 | tags/ 13 | build 14 | scripts/node_modules/ 15 | scripts/nines 16 | .ycm* 17 | libold/ 18 | *.cl.swp.h 19 | *.cl.h 20 | *.h.h 21 | scripts/libccurl.so 22 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "deps/libopencl-stub"] 2 | path = deps/libopencl-stub 3 | url = https://github.com/iotaledger/libopencl-stub.git 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | 3 | compiler: clang 4 | matrix: 5 | include: 6 | # works on Precise and Trusty 7 | - os: linux 8 | addons: 9 | addons: 10 | apt: 11 | sources: 12 | - george-edison55-precise-backports 13 | packages: 14 | - cmake-data 15 | - cmake 16 | - os: osx 17 | osx_image: xcode8 18 | 19 | #before_script: 20 | before_install: 21 | - eval "${MATRIX_EVAL}" 22 | - cmake . 23 | 24 | script: 25 | - cmake --build . 26 | 27 | deploy: 28 | - provider: releases 29 | api_key: 30 | secure: "XJczJol6PDf2cr2rYIX2gnW2LLoWxwimTtdGRgVF6D7aUD1OczYnxqhKodSnykjWwmLZ7pBB/Yp9VaJlhR225lyBRKSa+z7LbcV3hBiPZjlHfBFEGJQPzK0NAKxKMcFeNLjp/MwkgxOJUtuiH2wiBP3lke0AXViMe1PoGT0R8X+PWtkSGKV7YSjsFrbFycii3tFGE840e9ErZHnOTLNwER7y+twYBujXqUZTvKBbTBr46XJ4m3VFDkfvXWDIHRWt8K/hNMwxZegTaQruKC112EeV9wwyO8xfl7I6xjEMg1H34rWqKWlFQc+RxP+Eu/O0/1P88KhiK1bUQz7pzsRPuR/+Iilqh12Z75QZejo0zYVXaYk4XWdRpeVl7iORe4FXq/bCxUoZ4T+RpE8pwG8bEY+1UDwW3soQiIJCBX0kbCbqlqBH2dVo/3gcPZom8q6NqBPL5H74PPt+/b9xx7Wnr504F7uM05j1qv5BybGfAR30p1dZZFirGnfA0SLp4xXrQZMZFYjiiZCgTUQH8gfAdpbyFhb0enbbcIGuw2bX2+x7m/bYqvTsh9iG7cVd7G2bJ5R98p9VicYtrIBVyzB9Nro0QSkdp97kg157aKITWKgDf/sWV+TGquoys29ur4nIC90pMRJ1567JkPtiqJbBDZ3EeLjE0GNEyVG9UXyumOg=" 31 | file_glob: true 32 | file: lib/* 33 | skip_cleanup: true 34 | on: 35 | tags: true 36 | repo: iotaledger/ccurl 37 | branch: master 38 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.2) 2 | enable_language (C) 3 | #find_package (OpenCL) 4 | if (WIN32 AND NOT MINGW) 5 | else() 6 | find_package (Threads) 7 | endif() 8 | include(InstallRequiredSystemLibraries) 9 | project (ccurl) 10 | 11 | set(CMAKE_INSTALL_PREFIX "/usr") 12 | set (LIBRARY_NAME ccurl) 13 | #set (OPENCL_LIBRARIES ${CMAKE_SOURCE_DIR}/deps/libopencl-stub/build/lib/libOpenCL.a) 14 | set (CL_LIBRARY_NAME OpenCL) 15 | set (OPENCL_LIBRARIES ${CL_LIBRARY_NAME}) 16 | add_subdirectory (deps/libopencl-stub) 17 | 18 | #set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread -Wall -g -O0") 19 | if (WIN32 AND NOT MINGW) 20 | set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall ") 21 | else() 22 | set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread -Wall -O3") 23 | #set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread -Wall -O0") 24 | endif() 25 | 26 | SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) 27 | SET (CTEST_BUILD_TARGET "RELEASE") 28 | 29 | 30 | #### OPENCL FILES 31 | 32 | SET(RESOURCE_COMPILER xxd) 33 | FILE(GLOB COMPILED_RESOURCES "src/lib/cl/*") 34 | FOREACH(INPUT_FILE ${COMPILED_RESOURCES}) 35 | get_filename_component(INPUT_NAME ${INPUT_FILE} NAME) 36 | get_filename_component(INPUT_PATH ${INPUT_FILE} DIRECTORY) 37 | SET(OUTPUT_FILE ${INPUT_PATH}/../${INPUT_NAME}.h) 38 | ADD_CUSTOM_COMMAND( 39 | OUTPUT ${OUTPUT_FILE} 40 | COMMAND ${RESOURCE_COMPILER} -i ${INPUT_NAME} ${OUTPUT_FILE} 41 | WORKING_DIRECTORY ${INPUT_PATH} 42 | ) 43 | LIST(APPEND COMPILED_RESOURCES ${OUTPUT_FILE}) 44 | ENDFOREACH() 45 | 46 | #### LIBCCURL 47 | file(GLOB SRC src/lib/*.c src/lib/claccess/*.c src/lib/util/*.c) 48 | set (SOURCES ${SRC}) 49 | 50 | include_directories (${CMAKE_SOURCE_DIR}/deps/libopencl-stub/include) 51 | add_library (${LIBRARY_NAME} SHARED ${SOURCES} ${COMPILED_RESOURCES}) 52 | add_library (${LIBRARY_NAME}static STATIC ${SOURCES} ${COMPILED_RESOURCES}) 53 | if (WIN32 AND NOT MINGW) 54 | target_link_libraries(${LIBRARY_NAME} ${OPENCL_LIBRARIES} ) 55 | target_link_libraries(${LIBRARY_NAME}static ${OPENCL_LIBRARIES}) 56 | else() 57 | #target_link_libraries(${LIBRARY_NAME} dl ${OPENCL_LIBRARIES}) 58 | target_link_libraries(${LIBRARY_NAME} dl ${OPENCL_LIBRARIES}) 59 | target_link_libraries(${LIBRARY_NAME}static dl ${OPENCL_LIBRARIES}) 60 | endif() 61 | 62 | 63 | if (WIN32 AND NOT MINGW) 64 | set_target_properties (${LIBRARY_NAME} PROPERTIES 65 | LIBRARY_OUTPUT_DIRECTORY lib 66 | ) 67 | set_target_properties(${LIBRARY_NAME}static PROPERTIES 68 | LIBRARY_OUTPUT_DIRECTORY lib 69 | OUTPUT_NAME ${LIBRARY_NAME} 70 | ) 71 | else() 72 | set_target_properties (${LIBRARY_NAME} PROPERTIES 73 | LIBRARY_OUTPUT_DIRECTORY lib 74 | LINK_FLAGS -lpthread 75 | ) 76 | set_target_properties(${LIBRARY_NAME}static PROPERTIES 77 | LIBRARY_OUTPUT_DIRECTORY lib 78 | OUTPUT_NAME ${LIBRARY_NAME} 79 | LINK_FLAGS -lpthread 80 | ) 81 | endif() 82 | 83 | install(TARGETS ${LIBRARY_NAME} ${LIBRARY_NAME}static 84 | LIBRARY DESTINATION lib 85 | ARCHIVE DESTINATION lib 86 | RUNTIME DESTINATION bin) 87 | 88 | set(PACKAGE_NAME "CCurl") 89 | set(PACKAGE_VENDOR "IOTA Foundation") 90 | set(PACKAGE_DESCRIPTION "CCurl - IOTA POW Accelerator") 91 | set(PACKAGE_VERSION "0.2.0") 92 | configure_file ("ccurl.pc.in" "${PROJECT_BINARY_DIR}/ccurl.pc" @ONLY) 93 | install (FILES "${PROJECT_BINARY_DIR}/ccurl.pc" DESTINATION lib/pkgconfig) 94 | 95 | # Install library headers 96 | FILE(GLOB HEADERS "src/lib/*.h") 97 | install(FILES ${HEADERS} DESTINATION include/ccurl) 98 | FILE(GLOB HEADERSUTIL "src/lib/util/*.h") 99 | install(FILES ${HEADERSUTIL} DESTINATION include/ccurl/util) 100 | 101 | ### TESTING 102 | #enable_testing () 103 | #add_subdirectory (test) 104 | add_subdirectory (src/cli) 105 | 106 | set(CPACK_PACKAGE_NAME "CCurl") 107 | set(CPACK_PACKAGE_VENDOR "IOTA Foundation") 108 | set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "CCurl - IOTA POW Accelerator") 109 | #set(CPACK_PACKAGE_VERSION "0.2.1") 110 | set(CPACK_PACKAGE_VERSION_MAJOR "0") 111 | set(CPACK_PACKAGE_VERSION_MINOR "2") 112 | set(CPACK_PACKAGE_VERSION_PATCH "1") 113 | set(CPACK_PACKAGE_INSTALL_DIRECTORY "CCurl") 114 | set(CPACK_PACKAGE_CONTACT "Paul Handy (iota@pauldhandy.com)") 115 | set(CPACK_NSIS_MODIFY_PATH "ON") 116 | include(CPack) 117 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 IOTA AS, IOTA Foundation & Developers (https://iotatoken.com) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ccurl 2 | 3 | C port of the Curl library 4 | 5 | ## Usage 6 | 7 | Don't forget to grab submodules! use `git submodule update --init --recursive` 8 | when cloning, and `git submodule update --recursive` when pulling from this 9 | repository. 10 | 11 | ### To Compile 12 | 13 | CMake is a build dependency. If you are testing, you must also 14 | install CUnit (BCUnit). 15 | 16 | #### Unix-based (linux, mac, etc.) 17 | 18 | `mkdir build && cd build && cmake .. && cmake --build . && cd ..` 19 | 20 | #### Windows 21 | 22 | You may build using mingw or cygwin, but if you build with Visual C++, it is 23 | highly recommended that you also install the 24 | [LLVM compiler](http://releases.llvm.org/download.html), and Microsoft's [Build Tools](https://www.microsoft.com/en-us/download/details.aspx?id=48159). 25 | 26 | 27 | ``` 28 | mkdir build 29 | cd build 30 | cmake -G "Visual Studio 14 2015" -A x64 -T LLVM-vs2014 .. 31 | cmake --build . --config Release 32 | cd .. 33 | ``` 34 | 35 | In Windows, the libraries would be located in the build\Release directory. 36 | 37 | ### Command-line programs 38 | 39 | There are two included command-line programs, ccurl-cli, and ccurl-digest. Usage 40 | is as follows: 41 | 42 | `% ccurl-digest $(ccurl-cli )` 43 | 44 | where `` is replaced with, for example, 18, and 45 | `` is replaced with your 2673-length transaction. 46 | 47 | #### Tricks 48 | 49 | If using GPU acceleration, you may tune the loop length with 50 | `ccurl_pow_set_loop_count(my_loop_count);` with the library, or 51 | setting an environment variable to, for example, `CCURL_LOOP_COUNT=64`, when 52 | using ccurl-cli. 53 | -------------------------------------------------------------------------------- /ccurl.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | exec_prefix=${prefix} 3 | libdir=${exec_prefix}/lib 4 | includedir=${prefix}/include 5 | 6 | Name: @PACKAGE_NAME@ 7 | Version: @PACKAGE_VERSION@ 8 | Description: @PACKAGE_DESCRIPTION@ 9 | Vendor: @PACKAGE_VENDOR@ 10 | Libs: -L${libdir} -lccurl 11 | Cflags: -I${includedir}/ccurl 12 | -------------------------------------------------------------------------------- /scripts/aws-ubuntU1604-gpu-setup.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | sudo apt-get update 3 | sudo apt-get -y install gcc 4 | wget http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/cuda-repo-ubuntu1604_8.0.61-1_amd64.deb 5 | sudo dpkg -i cuda-repo-ubuntu1604_8.0.61-1_amd64.deb 6 | sudo apt-get update 7 | sudo apt-get -y install cuda 8 | export PATH=/usr/local/cuda/bin:$PATH 9 | export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH 10 | sudo apt-get -y install opencl-headers 11 | -------------------------------------------------------------------------------- /scripts/ccurl_pow: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | var ffi = require('ffi') 3 | 4 | var libccurl = ffi.Library('../build/lib/libccurl', { 5 | ccurl_pow : [ 'string', [ 'string', 'int'] ] 6 | }) 7 | 8 | if (process.argv.length < 3) { 9 | console.log('Arguments: ' + process.argv[0] + ' ' + process.argv[1] + ' ') 10 | process.exit() 11 | } 12 | 13 | var mwm = parseInt(process.argv[2]); 14 | var trytes = process.argv[3]; 15 | 16 | console.log('Your trytes: ' + trytes.length); 17 | var output = libccurl.ccurl_pow(trytes, mwm); 18 | 19 | console.log('Your output: ' + output) 20 | -------------------------------------------------------------------------------- /src/cli/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project (ccurl-cli) 2 | if (WIN32 AND NOT MINGW) 3 | set(ws2_LIBRARY_PATH Ws2_32) 4 | elseif (MINGW) 5 | set(ws2_LIBRARY_PATH ws2_32) 6 | endif() 7 | set (CLI_SOURCES ccurl.c) 8 | set (CCD_SOURCES ccurld.c) 9 | set (DIGEST_SOURCE ccurl-digest.c) 10 | set (LONG_SOURCE trytes-to-long.c) 11 | set (TRITS_SOURCE trytes-to-trits.c) 12 | 13 | set (CLI_NAME ccurl-cli) 14 | set (CCD_NAME ccurld) 15 | set (DIGEST_NAME ccurl-digest) 16 | set (LONG_NAME trytes-to-long) 17 | set (TRITS_NAME trytes-to-trits) 18 | 19 | #add_executable (${CLI_NAME} ${CLI_SOURCES} ../lib/PearlDiver.c ../lib/pearcldiver.c ../lib/exports.c) 20 | #add_executable (${CLI_NAME} ${CLI_SOURCES} ${SOURCES}) 21 | add_executable (${CLI_NAME} ${CLI_SOURCES}) 22 | add_executable (${CCD_NAME} ${CCD_SOURCES}) 23 | add_executable (${DIGEST_NAME} ${DIGEST_SOURCE}) 24 | add_executable (${LONG_NAME} ${LONG_SOURCE}) 25 | add_executable (${TRITS_NAME} ${TRITS_SOURCE}) 26 | if (WIN32 AND NOT MINGW) 27 | set_target_properties (${CLI_NAME} PROPERTIES 28 | BINARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin 29 | ) 30 | set_target_properties (${DIGEST_NAME} PROPERTIES 31 | BINARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin 32 | ) 33 | else() 34 | set_target_properties (${TRITS_NAME} PROPERTIES 35 | LINK_FLAGS -Wl,-lpthread 36 | BINARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin 37 | ) 38 | set_target_properties (${LONG_NAME} PROPERTIES 39 | LINK_FLAGS -Wl,-lpthread 40 | BINARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin 41 | ) 42 | set_target_properties (${DIGEST_NAME} PROPERTIES 43 | LINK_FLAGS -Wl,-lpthread 44 | BINARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin 45 | ) 46 | set_target_properties (${CLI_NAME} PROPERTIES 47 | LINK_FLAGS -Wl,-lpthread 48 | BINARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin 49 | ) 50 | set_target_properties (${CCD_NAME} PROPERTIES 51 | LINK_FLAGS -Wl,-lpthread 52 | BINARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin 53 | ) 54 | endif() 55 | #target_link_libraries(${CLI_NAME} ${OPENCL_LIBRARIES} ) 56 | target_link_libraries(${CLI_NAME} ${ws2_LIBRARY_PATH} ${LIBRARY_NAME}static) 57 | target_link_libraries(${CCD_NAME} ${ws2_LIBRARY_PATH} ${LIBRARY_NAME}static) 58 | target_link_libraries(${DIGEST_NAME} ${ws2_LIBRARY_PATH} ${LIBRARY_NAME}static) 59 | target_link_libraries(${LONG_NAME} ${ws2_LIBRARY_PATH} ${LIBRARY_NAME}static) 60 | target_link_libraries(${TRITS_NAME} ${ws2_LIBRARY_PATH} ${LIBRARY_NAME}static) 61 | 62 | install(TARGETS ${TRITS_NAME} 63 | RUNTIME DESTINATION bin) 64 | install(TARGETS ${LONG_NAME} 65 | RUNTIME DESTINATION bin) 66 | install(TARGETS ${DIGEST_NAME} 67 | RUNTIME DESTINATION bin) 68 | install(TARGETS ${CLI_NAME} 69 | RUNTIME DESTINATION bin) 70 | install(TARGETS ${CCD_NAME} 71 | RUNTIME DESTINATION bin) 72 | -------------------------------------------------------------------------------- /src/cli/README.md: -------------------------------------------------------------------------------- 1 | # ccurl-cli 2 | Command-line interface to libcurl 3 | 4 | This requires iotaledger/ccurl to be built and in the library path. 5 | 6 | ## install 7 | 8 | ``` 9 | cmake . 10 | make 11 | make install 12 | ``` 13 | 14 | ## Running 15 | 16 | ``` 17 | ccurl [TRYTES] 18 | ``` 19 | or 20 | ``` 21 | echo [TRYTES] | ccurl 22 | ``` 23 | -------------------------------------------------------------------------------- /src/cli/ccurl-digest.c: -------------------------------------------------------------------------------- 1 | #include "../lib/ccurl.h" 2 | #include "../lib/hash.h" 3 | #include "../lib/pearl_diver.h" 4 | #include "../lib/util/converter.h" 5 | #include 6 | #include 7 | #include 8 | 9 | #define TRYTE_LENGTH 2673 10 | 11 | #define HINTS \ 12 | "### CCURL DIGEST ###\nUsage:\n\tccurl-cli [TRYTES (length: %d)] \n\techo " \ 13 | "TRYTES | ccurl-cli \n" 14 | 15 | int main(int argc, char* argv[]) { 16 | char* buf; 17 | 18 | if (argc > 1) { 19 | buf = argv[1]; 20 | // memcpy(buf, argv[1], sizeof(char)*TRYTE_LENGTH); 21 | } else { 22 | fprintf(stderr, HINTS, TRYTE_LENGTH); 23 | return 1; 24 | } 25 | fputs(ccurl_digest_transaction(buf), stdout); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /src/cli/ccurl.c: -------------------------------------------------------------------------------- 1 | #include "../lib/ccurl.h" 2 | #include "../lib/hash.h" 3 | #include "../lib/pearl_diver.h" 4 | #include 5 | #include 6 | #include 7 | 8 | /* 9 | #include "Windows.h" 10 | #include "Winsock2.h" 11 | #pragma comment(lib, "Ws2_32.lib") 12 | */ 13 | #ifndef _WIN32 14 | #include 15 | #else 16 | #define STDIN_FILENO 0 17 | #endif 18 | 19 | #define TRYTE_LENGTH 2673 20 | 21 | #define HINTS \ 22 | "### CCURL ###\nUsage:\n\tccurl-cli [TRYTES (length: " \ 23 | "%d)] \n\techo TRYTES | ccurl-cli \n" 24 | 25 | int get_stdin(char* str, int len) { 26 | 27 | int i = 0; 28 | char chr; 29 | struct timeval timeout; 30 | fd_set readfds, savefds; 31 | FD_ZERO(&readfds); 32 | FD_SET(STDIN_FILENO, &readfds); 33 | 34 | savefds = readfds; 35 | 36 | timeout.tv_sec = 0; 37 | timeout.tv_usec = 0; 38 | 39 | if (select(1, &readfds, NULL, NULL, &timeout)) { 40 | while ((chr = getchar()) != EOF) { 41 | if (i > len) 42 | return -1; 43 | str[i++] = chr; 44 | } 45 | } 46 | readfds = savefds; 47 | // str[i] = 0; 48 | return i; 49 | } 50 | 51 | int main(int argc, char* argv[]) { 52 | char *buf, *out = NULL, *str; 53 | buf = (char*)calloc((TRYTE_LENGTH + 1) + 1, sizeof(char)); 54 | long minWeightMagnitude; 55 | 56 | if (argc < 2) { 57 | fprintf(stderr, HINTS, TRYTE_LENGTH); 58 | return 1; 59 | } 60 | 61 | if (argc > 2) { 62 | if (strlen(argv[2]) >= TRYTE_LENGTH) { 63 | memcpy(buf, argv[2], sizeof(char) * strlen(argv[2])); 64 | } else { 65 | fprintf(stderr, HINTS, TRYTE_LENGTH); 66 | return 1; 67 | } 68 | } 69 | minWeightMagnitude = atol(argv[1]); 70 | if (minWeightMagnitude == 0) { 71 | fprintf(stderr, HINTS, TRYTE_LENGTH); 72 | return 1; 73 | } 74 | if ((str = getenv("CCURL_LOOP_COUNT"))) { 75 | ccurl_pow_set_loop_count(atol(str)); 76 | } 77 | ccurl_pow_init(); 78 | out = ccurl_pow(buf, minWeightMagnitude); 79 | if (out != NULL) { 80 | fputs(out, stdout); 81 | } 82 | free(out); 83 | free(buf); 84 | ccurl_pow_finalize(); 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /src/cli/ccurl.h: -------------------------------------------------------------------------------- 1 | 2 | #include "../lib/hash.h" 3 | #include 4 | 5 | static const trit_t iotacurl_tryte2trits_tbl[27][3] = { 6 | {0, 0, 0}, {1, 0, 0}, {-1, 1, 0}, {0, 1, 0}, {1, 1, 0}, {-1, -1, 1}, 7 | {0, -1, 1}, {1, -1, 1}, {-1, 0, 1}, {0, 0, 1}, {1, 0, 1}, {-1, 1, 1}, 8 | {0, 1, 1}, {1, 1, 1}, {-1, -1, -1}, {0, -1, -1}, {1, -1, -1}, {-1, 0, -1}, 9 | {0, 0, -1}, {1, 0, -1}, {-1, 1, -1}, {0, 1, -1}, {1, 1, -1}, {-1, -1, 0}, 10 | {0, -1, 0}, {1, -1, 0}, {-1, 0, 0}, 11 | }; 12 | -------------------------------------------------------------------------------- /src/cli/ccurld.c: -------------------------------------------------------------------------------- 1 | #include "../lib/ccurl.h" 2 | #include "../lib/hash.h" 3 | #include "../lib/pearl_diver.h" 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #ifndef _WIN32 18 | #include 19 | #else 20 | #define STDIN_FILENO 0 21 | #endif 22 | 23 | #define TRYTE_LENGTH 2673 24 | 25 | #define HINTS \ 26 | "### CCURL DAEMON ###\nUsage:\n\tccurld \n" 27 | static volatile bool running = true; 28 | static void shutdown(); 29 | static char* defaultPath = "/tmp/pow"; 30 | static char* path; 31 | 32 | int main(int argc, char* argv[]) { 33 | char *out = NULL, *str, *digest = NULL; 34 | long min_weight_magnitude; 35 | int fd; 36 | 37 | signal(SIGINT, shutdown); 38 | if (argc < 2) { 39 | fprintf(stderr, HINTS); 40 | return 1; 41 | } 42 | 43 | if (argc > 2) { 44 | fprintf(stderr, "Copying!.\n"); 45 | path = (char*)malloc(sizeof(char) * strlen(argv[2])); 46 | memcpy(path, argv[2], sizeof(char) * strlen(argv[2])); 47 | } else { 48 | path = defaultPath; 49 | } 50 | 51 | int result = mkfifo(path, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH); 52 | if (result != -1) { 53 | fprintf(stderr, "Pipe opened.\n"); 54 | } else { 55 | fprintf(stderr, "Could not open pipe."); 56 | fprintf(stderr, " %s\n", strerror(errno)); 57 | exit(EXIT_FAILURE); 58 | } 59 | min_weight_magnitude = atol(argv[1]); 60 | 61 | if (min_weight_magnitude == 0) { 62 | fprintf(stderr, HINTS); 63 | exit(EXIT_FAILURE); 64 | } 65 | 66 | if ((str = getenv("CCURL_LOOP_COUNT"))) { 67 | ccurl_pow_set_loop_count(atol(str)); 68 | } 69 | if ((str = getenv("CCURL_OFFSET"))) { 70 | ccurl_pow_set_offset(atol(str)); 71 | } 72 | fprintf(stderr, "ccurl starting\n"); 73 | ccurl_pow_init(); 74 | while (running) { 75 | fd = open(path, O_RDONLY); 76 | if (fd < 0) { 77 | fprintf(stderr, "Error opening FIFO.\n"); 78 | exit(EXIT_FAILURE); 79 | } 80 | char buf[TRYTE_LENGTH + 1] = {0}; 81 | 82 | read(fd, buf, sizeof(buf)); 83 | close(fd); 84 | if (running) { 85 | time_t start, end; 86 | start = time(0); 87 | out = ccurl_pow(buf, min_weight_magnitude); 88 | end = time(0); 89 | if (out != NULL) { 90 | fd = open(path, O_WRONLY); 91 | write(fd, out, strlen(out)); 92 | close(fd); 93 | digest = ccurl_digest_transaction(out); 94 | fprintf(stderr, "%s: %f s\n", digest, difftime(end, start)); 95 | 96 | free((void*) digest); 97 | free((void*) out); 98 | } 99 | } 100 | } 101 | if (unlink(path) < 0) { 102 | printf("Error erasing file.\n"); 103 | } else { 104 | printf("%s erased.\n", path); 105 | } 106 | ccurl_pow_finalize(); 107 | 108 | return 0; 109 | } 110 | 111 | static void shutdown() { 112 | fprintf(stderr, "\nCaught SIGINT. Shutting down... \n"); 113 | running = false; 114 | ccurl_pow_interrupt(); 115 | pid_t childPID; 116 | if ((childPID = fork()) < 0) { 117 | exit(EXIT_FAILURE); 118 | } 119 | if (!childPID) { 120 | int fd = open(path, O_WRONLY); 121 | char null[TRYTE_LENGTH] = {0}; 122 | write(fd, null, strlen(null)); 123 | close(fd); 124 | } 125 | 126 | if(path != defaultPath) { 127 | free((void*) path); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/cli/long-to-trytes.c: -------------------------------------------------------------------------------- 1 | #include "../lib/util/converter.h" 2 | #include 3 | #include 4 | #include 5 | 6 | #define HINTS \ 7 | "### TRYTES TO LONG ###\nUsage:\n\t trytes-to-long " \ 8 | "\n" 9 | 10 | int get_stdin(char* str, int len) { 11 | 12 | int i = 0; 13 | char chr; 14 | struct timeval timeout; 15 | fd_set readfds, savefds; 16 | FD_ZERO(&readfds); 17 | FD_SET(STDIN_FILENO, &readfds); 18 | 19 | savefds = readfds; 20 | 21 | timeout.tv_sec = 0; 22 | timeout.tv_usec = 0; 23 | 24 | if (select(1, &readfds, NULL, NULL, &timeout)) { 25 | while ((chr = getchar()) != EOF) { 26 | if (i > len) 27 | return -1; 28 | str[i++] = chr; 29 | } 30 | } 31 | readfds = savefds; 32 | // str[i] = 0; 33 | return i; 34 | } 35 | 36 | int main(int argc, char* argv[]) { 37 | char* buf; 38 | 39 | if (argc > 1) { 40 | buf = argv[1]; 41 | } else { 42 | buf = malloc(27 * sizeof(char)); 43 | if (get_stdin(buf, 27) != 0) { 44 | fprintf(stderr, HINTS); 45 | return 1; 46 | } 47 | } 48 | init_converter(); 49 | size_t length = strlen(buf); 50 | char* input = trits_from_trytes(buf, length); 51 | char value = long_value(input, 0, length * 3); 52 | fprintf(stdout, "%hhd", value); 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /src/cli/trytes-to-long.c: -------------------------------------------------------------------------------- 1 | #include "../lib/util/converter.h" 2 | #include 3 | #include 4 | #include 5 | 6 | #define HINTS \ 7 | "### TRYTES TO LONG ###\nUsage:\n\t trytes-to-long " \ 8 | "\n" 9 | 10 | int get_stdin(char* str, int len) { 11 | 12 | int i = 0; 13 | char chr; 14 | struct timeval timeout; 15 | fd_set readfds, savefds; 16 | FD_ZERO(&readfds); 17 | FD_SET(STDIN_FILENO, &readfds); 18 | 19 | savefds = readfds; 20 | 21 | timeout.tv_sec = 0; 22 | timeout.tv_usec = 0; 23 | 24 | if (select(1, &readfds, NULL, NULL, &timeout)) { 25 | while ((chr = getchar()) != EOF) { 26 | if (i > len) 27 | return -1; 28 | str[i++] = chr; 29 | } 30 | } 31 | readfds = savefds; 32 | // str[i] = 0; 33 | return i; 34 | } 35 | 36 | int main(int argc, char* argv[]) { 37 | char* buf; 38 | 39 | if (argc > 1) { 40 | buf = argv[1]; 41 | } else { 42 | buf = malloc(27 * sizeof(char)); 43 | if (get_stdin(buf, 27) != 0) { 44 | fprintf(stderr, HINTS); 45 | return 1; 46 | } 47 | } 48 | size_t length = strlen(buf); 49 | char* input = trits_from_trytes(buf, length); 50 | char value = long_value(input, 0, length * 3); 51 | fprintf(stdout, "%hhd", value); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /src/cli/trytes-to-trits.c: -------------------------------------------------------------------------------- 1 | #include "../lib/util/converter.h" 2 | #include 3 | #include 4 | #include 5 | 6 | #define HINTS \ 7 | "### TRYTES TO TRITS ###\nUsage:\n\t trytes-to-long " \ 8 | "\n" 9 | 10 | int get_stdin(char* str, int len) { 11 | 12 | int i = 0; 13 | char chr; 14 | struct timeval timeout; 15 | fd_set readfds, savefds; 16 | FD_ZERO(&readfds); 17 | FD_SET(STDIN_FILENO, &readfds); 18 | 19 | savefds = readfds; 20 | 21 | timeout.tv_sec = 0; 22 | timeout.tv_usec = 0; 23 | 24 | if (select(1, &readfds, NULL, NULL, &timeout)) { 25 | while ((chr = getchar()) != EOF) { 26 | if (i > len) 27 | return -1; 28 | str[i++] = chr; 29 | } 30 | } 31 | readfds = savefds; 32 | // str[i] = 0; 33 | return i; 34 | } 35 | 36 | int main(int argc, char* argv[]) { 37 | char* buf; 38 | 39 | if (argc > 1) { 40 | buf = argv[1]; 41 | } else { 42 | buf = malloc(27 * sizeof(char)); 43 | if (get_stdin(buf, 27) != 0) { 44 | fprintf(stderr, HINTS); 45 | return 1; 46 | } 47 | } 48 | size_t length = strlen(buf); 49 | char* input = trits_from_trytes(buf, length); 50 | int i = 0; 51 | for(i = 0; i < length * 3; i++ ) { 52 | switch(input[i]) { 53 | case 1: { 54 | fprintf(stdout, "+"); 55 | }break; 56 | case -1: { 57 | fprintf(stdout, "-"); 58 | } break; 59 | default: { 60 | fprintf(stdout, "0"); 61 | } 62 | } 63 | } 64 | return 0; 65 | } 66 | 67 | -------------------------------------------------------------------------------- /src/lib/bct_curl.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef BCT_CURL_H 4 | #define BCT_CURL_H 5 | #include "hash.h" 6 | 7 | typedef struct { 8 | bc_trit_t low[STATE_LENGTH]; 9 | bc_trit_t hi[STATE_LENGTH]; 10 | } bct_curl_t; 11 | 12 | /* 13 | EXPORT void init_bct_curl(bct_curl_t* ctx); 14 | EXPORT void absorb_bct(bct_curl_t* ctx, bc_trit_t* const trits, int length); 15 | EXPORT void squeeze_bct(bct_curl_t* ctx, bc_trit_t* const trits, int length); 16 | EXPORT void transform_bct(bct_curl_t* ctx); 17 | EXPORT void reset_bct(bct_curl_t* ctx); 18 | */ 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/lib/ccurl.h: -------------------------------------------------------------------------------- 1 | #ifndef _CCURL_H_ 2 | #define _CCURL_H_ 3 | 4 | #ifndef EXPORT 5 | #if defined(_WIN32) && !defined(__MINGW32__) 6 | #define EXPORT __declspec(dllexport) 7 | #else 8 | #define EXPORT 9 | #endif 10 | #endif 11 | #if defined(_WIN32) && !defined(__MINGW32__) 12 | #else 13 | #include 14 | #endif 15 | 16 | EXPORT int ccurl_pow_init(); 17 | EXPORT void ccurl_pow_interrupt(); 18 | EXPORT void ccurl_pow_finalize(); 19 | EXPORT void ccurl_pow_set_loop_count(size_t c); 20 | EXPORT void ccurl_pow_set_offset(size_t o); 21 | EXPORT char* ccurl_pow(char* trytes, int min_weight_magnitude); 22 | EXPORT char* ccurl_digest_transaction(char* trytes); 23 | 24 | #endif /* _CCURL_H_ */ 25 | -------------------------------------------------------------------------------- /src/lib/cl/pearl.cl: -------------------------------------------------------------------------------- 1 | #define HASH_LENGTH 243 2 | #define OFFSET_LENGTH 4 3 | #define NONCE_LENGTH HASH_LENGTH / 3 4 | #define INT_LENGTH NONCE_LENGTH / 3 5 | #define NONCE_START HASH_LENGTH - NONCE_LENGTH 6 | #define NONCE_INIT_START NONCE_START + OFFSET_LENGTH 7 | #define NONCE_INCREMENT_START NONCE_INIT_START + INT_LENGTH 8 | #define NUMBER_OF_ROUNDS 81 9 | #define STATE_LENGTH 3 * HASH_LENGTH 10 | #define HALF_LENGTH 364 11 | #define HIGH_BITS 0xFFFFFFFFFFFFFFFF 12 | #define LOW_BITS 0x0000000000000000 13 | //#define HIGH_BITS 14 | //0b1111111111111111111111111111111111111111111111111111111111111111L 15 | //#define LOW_BITS 16 | //0b0000000000000000000000000000000000000000000000000000000000000000L 17 | /** 18 | * t1 = j == 0? 0:(((j - 1)%2)+1)*HALF_LENGTH - ((j-1)>>1); 19 | */ 20 | __constant size_t INDEX[STATE_LENGTH + 1] = { 21 | 0, 364, 728, 363, 727, 362, 726, 361, 725, 360, 724, 359, 723, 358, 722, 22 | 357, 721, 356, 720, 355, 719, 354, 718, 353, 717, 352, 716, 351, 715, 350, 23 | 714, 349, 713, 348, 712, 347, 711, 346, 710, 345, 709, 344, 708, 343, 707, 24 | 342, 706, 341, 705, 340, 704, 339, 703, 338, 702, 337, 701, 336, 700, 335, 25 | 699, 334, 698, 333, 697, 332, 696, 331, 695, 330, 694, 329, 693, 328, 692, 26 | 327, 691, 326, 690, 325, 689, 324, 688, 323, 687, 322, 686, 321, 685, 320, 27 | 684, 319, 683, 318, 682, 317, 681, 316, 680, 315, 679, 314, 678, 313, 677, 28 | 312, 676, 311, 675, 310, 674, 309, 673, 308, 672, 307, 671, 306, 670, 305, 29 | 669, 304, 668, 303, 667, 302, 666, 301, 665, 300, 664, 299, 663, 298, 662, 30 | 297, 661, 296, 660, 295, 659, 294, 658, 293, 657, 292, 656, 291, 655, 290, 31 | 654, 289, 653, 288, 652, 287, 651, 286, 650, 285, 649, 284, 648, 283, 647, 32 | 282, 646, 281, 645, 280, 644, 279, 643, 278, 642, 277, 641, 276, 640, 275, 33 | 639, 274, 638, 273, 637, 272, 636, 271, 635, 270, 634, 269, 633, 268, 632, 34 | 267, 631, 266, 630, 265, 629, 264, 628, 263, 627, 262, 626, 261, 625, 260, 35 | 624, 259, 623, 258, 622, 257, 621, 256, 620, 255, 619, 254, 618, 253, 617, 36 | 252, 616, 251, 615, 250, 614, 249, 613, 248, 612, 247, 611, 246, 610, 245, 37 | 609, 244, 608, 243, 607, 242, 606, 241, 605, 240, 604, 239, 603, 238, 602, 38 | 237, 601, 236, 600, 235, 599, 234, 598, 233, 597, 232, 596, 231, 595, 230, 39 | 594, 229, 593, 228, 592, 227, 591, 226, 590, 225, 589, 224, 588, 223, 587, 40 | 222, 586, 221, 585, 220, 584, 219, 583, 218, 582, 217, 581, 216, 580, 215, 41 | 579, 214, 578, 213, 577, 212, 576, 211, 575, 210, 574, 209, 573, 208, 572, 42 | 207, 571, 206, 570, 205, 569, 204, 568, 203, 567, 202, 566, 201, 565, 200, 43 | 564, 199, 563, 198, 562, 197, 561, 196, 560, 195, 559, 194, 558, 193, 557, 44 | 192, 556, 191, 555, 190, 554, 189, 553, 188, 552, 187, 551, 186, 550, 185, 45 | 549, 184, 548, 183, 547, 182, 546, 181, 545, 180, 544, 179, 543, 178, 542, 46 | 177, 541, 176, 540, 175, 539, 174, 538, 173, 537, 172, 536, 171, 535, 170, 47 | 534, 169, 533, 168, 532, 167, 531, 166, 530, 165, 529, 164, 528, 163, 527, 48 | 162, 526, 161, 525, 160, 524, 159, 523, 158, 522, 157, 521, 156, 520, 155, 49 | 519, 154, 518, 153, 517, 152, 516, 151, 515, 150, 514, 149, 513, 148, 512, 50 | 147, 511, 146, 510, 145, 509, 144, 508, 143, 507, 142, 506, 141, 505, 140, 51 | 504, 139, 503, 138, 502, 137, 501, 136, 500, 135, 499, 134, 498, 133, 497, 52 | 132, 496, 131, 495, 130, 494, 129, 493, 128, 492, 127, 491, 126, 490, 125, 53 | 489, 124, 488, 123, 487, 122, 486, 121, 485, 120, 484, 119, 483, 118, 482, 54 | 117, 481, 116, 480, 115, 479, 114, 478, 113, 477, 112, 476, 111, 475, 110, 55 | 474, 109, 473, 108, 472, 107, 471, 106, 470, 105, 469, 104, 468, 103, 467, 56 | 102, 466, 101, 465, 100, 464, 99, 463, 98, 462, 97, 461, 96, 460, 95, 57 | 459, 94, 458, 93, 457, 92, 456, 91, 455, 90, 454, 89, 453, 88, 452, 58 | 87, 451, 86, 450, 85, 449, 84, 448, 83, 447, 82, 446, 81, 445, 80, 59 | 444, 79, 443, 78, 442, 77, 441, 76, 440, 75, 439, 74, 438, 73, 437, 60 | 72, 436, 71, 435, 70, 434, 69, 433, 68, 432, 67, 431, 66, 430, 65, 61 | 429, 64, 428, 63, 427, 62, 426, 61, 425, 60, 424, 59, 423, 58, 422, 62 | 57, 421, 56, 420, 55, 419, 54, 418, 53, 417, 52, 416, 51, 415, 50, 63 | 414, 49, 413, 48, 412, 47, 411, 46, 410, 45, 409, 44, 408, 43, 407, 64 | 42, 406, 41, 405, 40, 404, 39, 403, 38, 402, 37, 401, 36, 400, 35, 65 | 399, 34, 398, 33, 397, 32, 396, 31, 395, 30, 394, 29, 393, 28, 392, 66 | 27, 391, 26, 390, 25, 389, 24, 388, 23, 387, 22, 386, 21, 385, 20, 67 | 384, 19, 383, 18, 382, 17, 381, 16, 380, 15, 379, 14, 378, 13, 377, 68 | 12, 376, 11, 375, 10, 374, 9, 373, 8, 372, 7, 371, 6, 370, 5, 69 | 369, 4, 368, 3, 367, 2, 366, 1, 365, 0}; 70 | 71 | /** 72 | * t2 = ((j%2)+1)*HALF_LENGTH - ((j)>>1); 73 | */ 74 | 75 | typedef long bc_trit_t; 76 | 77 | void increment(__global bc_trit_t* mid_low, __global bc_trit_t* mid_high, 78 | __private size_t from_index, __private size_t to_index); 79 | void copy_mid_to_state(__global bc_trit_t* mid_low, __global bc_trit_t* mid_high, 80 | __global bc_trit_t* state_low, __global bc_trit_t* state_high, 81 | __private size_t id, __private size_t l_size, 82 | __private size_t l_trits); 83 | void transform(__global bc_trit_t* state_low, __global bc_trit_t* state_high, 84 | __private size_t id, __private size_t l_size, 85 | __private size_t l_trits); 86 | void check(__global bc_trit_t* state_low, __global bc_trit_t* state_high, 87 | __global volatile char* found, 88 | __constant size_t* min_weight_magnitude, 89 | __global bc_trit_t* nonce_probe, __private size_t gr_id); 90 | void setup_ids(__private size_t* id, __private size_t* gid, 91 | __private size_t* gr_id, __private size_t* l_size, 92 | __private size_t* n_trits); 93 | 94 | void increment(__global bc_trit_t* mid_low, __global bc_trit_t* mid_high, 95 | __private size_t from_index, __private size_t to_index) { 96 | size_t i; 97 | bc_trit_t carry = 1; 98 | bc_trit_t low, hi; 99 | for (i = from_index; i < to_index && carry != 0; i++) { 100 | low = mid_low[i]; 101 | hi = mid_high[i]; 102 | mid_low[i] = hi ^ low; 103 | mid_high[i] = low; 104 | carry = hi & (~low); 105 | } 106 | } 107 | 108 | void copy_mid_to_state(__global bc_trit_t* mid_low, __global bc_trit_t* mid_high, 109 | __global bc_trit_t* state_low, __global bc_trit_t* state_high, 110 | __private size_t id, __private size_t l_size, 111 | __private size_t n_trits) { 112 | size_t i, j; 113 | for (i = 0; i < n_trits; i++) { 114 | j = id + i * l_size; 115 | state_low[j] = mid_low[j]; 116 | state_high[j] = mid_high[j]; 117 | } 118 | } 119 | 120 | void transform(__global bc_trit_t* state_low, __global bc_trit_t* state_high, 121 | __private size_t id, __private size_t l_size, 122 | __private size_t n_trits) { 123 | __private size_t round, i, j, k; 124 | __private bc_trit_t alpha, beta, gamma, delta, sp_low[3], sp_high[3]; 125 | for (round = 0; round < NUMBER_OF_ROUNDS; round++) { 126 | for (i = 0; i < n_trits; i++) { 127 | j = id + i * l_size; 128 | k = j+1; 129 | alpha = state_low[INDEX[j]]; 130 | beta = state_high[INDEX[j]]; 131 | gamma = state_high[INDEX[k]]; 132 | delta = (alpha | (~gamma)) & (state_low[INDEX[k]] ^ beta); 133 | 134 | sp_low[i] = ~delta; 135 | sp_high[i] = (alpha ^ gamma) | delta; 136 | } 137 | barrier(CLK_LOCAL_MEM_FENCE); 138 | for (i = 0; i < n_trits; i++) { 139 | j = id + i * l_size; 140 | state_low[j] = sp_low[i]; 141 | state_high[j] = sp_high[i]; 142 | } 143 | barrier(CLK_LOCAL_MEM_FENCE); 144 | } 145 | } 146 | 147 | void check(__global bc_trit_t* state_low, __global bc_trit_t* state_high, 148 | __global volatile char* found, 149 | __constant size_t* min_weight_magnitude, 150 | __global bc_trit_t* nonce_probe, __private size_t gr_id) { 151 | int i; 152 | *nonce_probe = HIGH_BITS; 153 | for (i = HASH_LENGTH - *min_weight_magnitude; i < HASH_LENGTH; i++) { 154 | *nonce_probe &= ~(state_low[i] ^ state_high[i]); 155 | if (*nonce_probe == 0) 156 | return; 157 | } 158 | if (*nonce_probe != 0) { 159 | //*nonce_probe = 1 << __builtin_ctzl(*nonce_probe); 160 | *found = gr_id + 1; 161 | } 162 | } 163 | 164 | void setup_ids(__private size_t* id, __private size_t* gid, 165 | __private size_t* gr_id, __private size_t* l_size, 166 | __private size_t* n_trits) { 167 | __private size_t l_rem; 168 | *id = get_local_id(0); 169 | *l_size = get_local_size(0); 170 | *gr_id = get_global_id(0) / *l_size; 171 | *gid = *gr_id * STATE_LENGTH; 172 | l_rem = STATE_LENGTH % *l_size; 173 | *n_trits = STATE_LENGTH / *l_size; 174 | *n_trits += l_rem == 0 ? 0 : 1; 175 | *n_trits -= (*n_trits) * (*id) < STATE_LENGTH ? 0 : 1; 176 | } 177 | 178 | __kernel void init(__global char* trit_hash, __global bc_trit_t* mid_low, 179 | __global bc_trit_t* mid_high, __global bc_trit_t* state_low, 180 | __global bc_trit_t* state_high, 181 | __constant size_t* min_weight_magnitude, 182 | __global volatile char* found, __global bc_trit_t* nonce_probe, 183 | __constant size_t* loop_count) { 184 | __private size_t i, j, id, gid, gr_id, gl_off, l_size, n_trits; 185 | setup_ids(&id, &gid, &gr_id, &l_size, &n_trits); 186 | gl_off = get_global_offset(0); 187 | 188 | if (id == 0 && gr_id == 0) { 189 | *found = 0; 190 | } 191 | 192 | if (gr_id == 0) 193 | return; 194 | 195 | for (i = 0; i < n_trits; i++) { 196 | j = id + i * l_size; 197 | mid_low[gid + j] = mid_low[j]; 198 | mid_high[gid + j] = mid_high[j]; 199 | } 200 | 201 | if (id == 0) { 202 | for (i = 0; i < gr_id + gl_off; i++) { 203 | increment(&(mid_low[gid]), &(mid_high[gid]), NONCE_INIT_START, 204 | NONCE_INCREMENT_START); 205 | } 206 | } 207 | } 208 | 209 | __kernel void search(__global char* trit_hash, __global bc_trit_t* mid_low, 210 | __global bc_trit_t* mid_high, __global bc_trit_t* state_low, 211 | __global bc_trit_t* state_high, 212 | __constant size_t* min_weight_magnitude, 213 | __global volatile char* found, 214 | __global bc_trit_t* nonce_probe, 215 | __constant size_t* loop_count) { 216 | __private size_t i, id, gid, gr_id, l_size, n_trits; 217 | setup_ids(&id, &gid, &gr_id, &l_size, &n_trits); 218 | 219 | for (i = 0; i < *loop_count; i++) { 220 | if (id == 0) 221 | increment(&(mid_low[gid]), &(mid_high[gid]), NONCE_INCREMENT_START, 222 | HASH_LENGTH); 223 | 224 | barrier(CLK_LOCAL_MEM_FENCE); 225 | copy_mid_to_state(&(mid_low[gid]), &(mid_high[gid]), &(state_low[gid]), 226 | &(state_high[gid]), id, l_size, n_trits); 227 | 228 | barrier(CLK_LOCAL_MEM_FENCE); 229 | transform(&(state_low[gid]), &(state_high[gid]), id, l_size, n_trits); 230 | 231 | barrier(CLK_LOCAL_MEM_FENCE); 232 | if (id == 0) 233 | check(&(state_low[gid]), &(state_high[gid]), found, min_weight_magnitude, 234 | &(nonce_probe[gr_id]), gr_id); 235 | 236 | barrier(CLK_LOCAL_MEM_FENCE); 237 | if (*found != 0) 238 | break; 239 | } 240 | } 241 | 242 | __kernel void finalize(__global char* trit_hash, __global bc_trit_t* mid_low, 243 | __global bc_trit_t* mid_high, __global bc_trit_t* state_low, 244 | __global bc_trit_t* state_high, 245 | __constant size_t* min_weight_magnitude, 246 | __global volatile char* found, 247 | __global bc_trit_t* nonce_probe, 248 | __constant size_t* loop_count) { 249 | __private size_t i, j, id, gid, gr_id, l_size, n_trits; 250 | setup_ids(&id, &gid, &gr_id, &l_size, &n_trits); 251 | 252 | if (gr_id == (size_t)(*found - 1) && nonce_probe[gr_id] != 0) { 253 | for (i = 0; i < n_trits; i++) { 254 | j = id + i * l_size; 255 | if (j < HASH_LENGTH) { 256 | trit_hash[j] = 257 | (mid_low[gid + j] & nonce_probe[gr_id]) == 0 258 | ? 1 259 | : (mid_high[gid + j] & nonce_probe[gr_id]) == 0 ? -1 : 0; 260 | } 261 | } 262 | } 263 | } 264 | -------------------------------------------------------------------------------- /src/lib/claccess/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) enable_language(C) find_package(Threads) 2 | find_library(OPENCL_LIBRARIES OpenCL) project(clcontext) 3 | 4 | set(CMAKE_INSTALL_PREFIX "/usr") 5 | 6 | file(GLOB SRC*.c) set(SOURCES ${SRC}) 7 | 8 | set(LIBRARY_NAME clcontext) 9 | 10 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread -Wall") 11 | 12 | SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR} / 13 | bin) SET(CTEST_BUILD_TARGET "DEVELOPMENT") 14 | 15 | add_library(${LIBRARY_NAME} SHARED ${SRC}) 16 | 17 | set_target_properties( 18 | ${LIBRARY_NAME} PROPERTIES 19 | LIBRARY_OUTPUT_DIRECTORY ${ 20 | PROJECT_BINARY_DIR} / 21 | lib LINK_FLAGS - 22 | lpthread) 23 | #target_include_directories(curl PUBLIC ${CMAKE_CURRENT_SOURCE_DIR }) 24 | 25 | install(TARGETS ${ 26 | LIBRARY_NAME} LIBRARY DESTINATION lib 27 | ARCHIVE DESTINATION lib RUNTIME 28 | DESTINATION bin) 29 | 30 | #Install library headers 31 | file(GLOB HEADERS*.h) install(FILES ${ 32 | HEADERS} DESTINATION include) 33 | 34 | #enable_testing() 35 | #add_subdirectory(test) 36 | -------------------------------------------------------------------------------- /src/lib/claccess/clcontext.c: -------------------------------------------------------------------------------- 1 | #include "clcontext.h" 2 | #include 3 | #include 4 | 5 | //#define _CL_ALL_ 6 | #ifndef DEBUG 7 | #define DEBUG 8 | #endif 9 | 10 | static void CL_CALLBACK pfn_notify(const char* errinfo, 11 | const void* private_info, size_t cb, 12 | void* user_data) { 13 | fprintf(stderr, "W: ocl_pfn_notify error: %s\n", errinfo); 14 | } 15 | static void CL_CALLBACK bfn_notify(cl_program prog, void* user_data) { 16 | // fprintf(stderr, "W: build error: \n"); 17 | } 18 | 19 | /* 20 | int check_clerror(cl_int err, char *comment, ...) { 21 | if(err == CL_SUCCESS) { 22 | return 0; 23 | } 24 | printf("E: OpenCL implementation returned an error: %d\n", err); 25 | va_list args; 26 | vprintf(comment, args); 27 | printf("\n\n"); 28 | return 1; 29 | } 30 | */ 31 | 32 | void free_platforms(cl_platform_id* platforms, cl_uint num_platforms) { 33 | cl_uint i = 0; 34 | for (i = 0; i < num_platforms; i++) { 35 | clUnloadPlatformCompiler(platforms[i]); 36 | } 37 | free(platforms); 38 | } 39 | 40 | static int get_devices(CLContext* ctx, unsigned char** src, size_t* size) { 41 | /* List devices for each platforms.*/ 42 | size_t i; 43 | cl_uint num_platforms = 0; 44 | cl_int errno; 45 | ctx->num_devices = 0; 46 | cl_platform_id* platforms; 47 | // cl_device_id devices[CLCONTEXT_MAX_DEVICES]; 48 | 49 | #ifdef DEBUG 50 | fprintf(stderr, "Getting platforms... \n"); 51 | #endif 52 | errno = clGetPlatformIDs(0, NULL, &num_platforms); 53 | if (errno != CL_SUCCESS) { 54 | #ifdef DEBUG 55 | fprintf(stderr, 56 | "Cannot get the number of OpenCL platforms available. E:%d\n", 57 | errno); 58 | #endif 59 | return 1; 60 | } 61 | // cl_platform_id platforms[num_platforms]; 62 | platforms = malloc(num_platforms * sizeof(cl_platform_id)); 63 | clGetPlatformIDs(num_platforms, platforms, NULL); 64 | for (i = 0; i < num_platforms; i++) { 65 | cl_uint pf_num_devices; 66 | #ifdef _CL_ALL_ 67 | if (clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, 68 | #else 69 | if (clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_GPU, 70 | #endif 71 | CLCONTEXT_MAX_DEVICES - ctx->num_devices, 72 | &(ctx->device[ctx->num_devices]), 73 | &pf_num_devices) != CL_SUCCESS) { 74 | #ifdef DEBUG 75 | fprintf(stderr, "W: Failed to get Opencl Device IDs for platform %zu.\n", 76 | i); 77 | #endif 78 | continue; 79 | } 80 | if (pf_num_devices > CLCONTEXT_MAX_DEVICES - ctx->num_devices) { 81 | /* 82 | fprintf(stderr, "W: The number of devices available on your system 83 | \ 84 | exceeds CLCONTEXT_MAX_DEVICES. Consider increasing 85 | \ 86 | CLCONTEXT_MAX_DEVICES.\n"); 87 | */ 88 | pf_num_devices = CLCONTEXT_MAX_DEVICES - ctx->num_devices; 89 | } 90 | ctx->num_devices += pf_num_devices; 91 | } 92 | if (ctx->num_devices == 0) { 93 | free_platforms(platforms, num_platforms); 94 | return 1; 95 | } 96 | 97 | /* Create OpenCL context. */ 98 | for (i = 0; i < ctx->num_devices; i++) { 99 | ctx->clctx[i] = (cl_context)clCreateContext(NULL, 1, &(ctx->device[i]), 100 | pfn_notify, NULL, &errno); 101 | if (errno != CL_SUCCESS) { 102 | #ifdef DEBUG 103 | fprintf(stderr, "Failed to execute clCreateContext, %d\n", errno); 104 | #endif 105 | free_platforms(platforms, num_platforms); 106 | return 1; 107 | } 108 | } 109 | /* Get Device info */ 110 | for (i = 0; i < ctx->num_devices; i++) { 111 | if (CL_SUCCESS != 112 | clGetDeviceInfo(ctx->device[i], CL_DEVICE_MAX_COMPUTE_UNITS, 113 | sizeof(cl_uint), &(ctx->num_cores[i]), NULL)) { 114 | #ifdef DEBUG 115 | fprintf(stderr, "Failed to execute clGetDeviceInfo for %zu", i); 116 | #endif 117 | } 118 | 119 | if (CL_SUCCESS != 120 | clGetDeviceInfo(ctx->device[i], CL_DEVICE_MAX_MEM_ALLOC_SIZE, 121 | sizeof(cl_ulong), &(ctx->max_memory[i]), NULL)) { 122 | #ifdef DEBUG 123 | fprintf(stderr, "Failed to execute clGetDeviceInfo for %zu", i); 124 | #endif 125 | } 126 | 127 | if (clGetDeviceInfo(ctx->device[i], CL_DEVICE_MAX_WORK_GROUP_SIZE, 128 | sizeof(size_t), &(ctx->num_multiple[i]), 129 | NULL) != CL_SUCCESS) { 130 | ctx->num_multiple[i] = 1; 131 | } 132 | } 133 | /* Create command queue */ 134 | for (i = 0; i < ctx->num_devices; i++) { 135 | ctx->clcmdq[i] = 136 | clCreateCommandQueue(ctx->clctx[i], ctx->device[i], 0, &errno); 137 | if (errno != CL_SUCCESS) { 138 | #ifdef DEBUG 139 | fprintf(stderr, "Failed to execute clCreateCommandQueue.\n"); 140 | #endif 141 | free_platforms(platforms, num_platforms); 142 | return 1; 143 | } 144 | } 145 | 146 | if (ctx->kernel.num_src == 0) { 147 | free_platforms(platforms, num_platforms); 148 | return 1; 149 | } 150 | for (i = 0; i < ctx->num_devices; i++) { 151 | ctx->programs[i] = clCreateProgramWithSource( 152 | ctx->clctx[i], ctx->kernel.num_src, (const char**)src, size, &errno); 153 | if (CL_SUCCESS != errno) { 154 | #ifdef DEBUG 155 | fprintf(stderr, "Failed to execute clCreateProgramWithSource\n"); 156 | #endif 157 | free_platforms(platforms, num_platforms); 158 | return 1; 159 | } 160 | } 161 | 162 | for (i = 0; i < ctx->num_devices; i++) { 163 | // memset(&(ctx->programs[i]), 0, sizeof(cl_program)); 164 | errno = clBuildProgram(ctx->programs[i], 1, &(ctx->device[i]), "-Werror", 165 | bfn_notify, NULL); 166 | char* build_log = malloc(0xFFFF); 167 | size_t log_size; 168 | clGetProgramBuildInfo(ctx->programs[i], ctx->device[i], 169 | CL_PROGRAM_BUILD_LOG, 0xFFFF, build_log, &log_size); 170 | #ifdef DEBUG 171 | fputs(build_log, stderr); 172 | #endif 173 | free(build_log); 174 | if (CL_SUCCESS != errno) { 175 | #ifdef DEBUG 176 | fprintf(stderr, "Failed to execute clBuildProgram\n"); 177 | #endif 178 | free_platforms(platforms, num_platforms); 179 | return 1; 180 | } 181 | } 182 | return 0; 183 | } 184 | 185 | static int create_kernel(CLContext* ctx, char** names) { 186 | // Create kernel. 187 | cl_int errno; 188 | size_t i, j; 189 | for (i = 0; i < ctx->num_devices; i++) { 190 | for (j = 0; j < ctx->kernel.num_kernels; j++) { 191 | ctx->clkernel[i][j] = clCreateKernel(ctx->programs[i], names[j], &errno); 192 | if (errno != CL_SUCCESS) { 193 | return 1; 194 | } 195 | } 196 | } 197 | return 0; 198 | } 199 | 200 | int kernel_init_buffers(CLContext* ctx) { 201 | int i, j, k; 202 | cl_ulong memsize; 203 | cl_int errno; 204 | cl_ulong maxmemsize; 205 | for (i = 0; i < ctx->num_devices; i++) { 206 | maxmemsize = 0; 207 | for (j = 0; j < ctx->kernel.num_buffers; j++) { 208 | memsize = ctx->kernel.buffer[j].size; 209 | if (ctx->kernel.buffer[j].init_flag & 2) { 210 | memsize *= ctx->num_cores[i] * ctx->num_multiple[i]; 211 | if (memsize > ctx->max_memory[i]) { 212 | k = ctx->max_memory[i] / ctx->kernel.buffer[j].size; 213 | ctx->num_cores[i] = k; 214 | memsize = k * ctx->kernel.buffer[j].size; 215 | // fprintf(stderr, "resizing number of cores to %d...\n", k); // 216 | // ctx->max_memory[i]); 217 | } 218 | // fprintf(stderr, "size found: %ld, size allowed, %ld...\n", memsize, 219 | // ctx->max_memory[i]); 220 | } 221 | maxmemsize += memsize; 222 | if (maxmemsize >= ctx->max_memory[i]) { 223 | #ifdef DEBUG 224 | fprintf(stderr, "E: max memory passed! \n"); 225 | #endif 226 | return 1; 227 | } 228 | 229 | ctx->buffers[i][j] = clCreateBuffer( 230 | ctx->clctx[i], ctx->kernel.buffer[j].flags, memsize, NULL, &errno); 231 | if (CL_SUCCESS != errno) { 232 | #ifdef DEBUG 233 | fprintf(stderr, "Failed to execute clCreateBuffer for %d:%d", i, j); 234 | #endif 235 | return 1; 236 | } 237 | for (k = 0; k < ctx->kernel.num_kernels; k++) { 238 | if ((ctx->kernel.buffer[j].init_flag & 1) != 0) { 239 | if (clSetKernelArg(ctx->clkernel[i][k], j, sizeof(cl_mem), NULL) != 240 | CL_SUCCESS) { 241 | // fprintf(stderr, "Failed to execute clSetKernelArg for local 242 | // %d:%d", (int)i, (int)j); 243 | return 1; 244 | } 245 | } else { 246 | if (clSetKernelArg(ctx->clkernel[i][k], j, sizeof(cl_mem), 247 | (void*)&(ctx->buffers[i][j])) != CL_SUCCESS) { 248 | // fprintf(stderr, "Failed to execute clSetKernelArg for %d:%d", 249 | // (int)i,(int)j); 250 | return 1; 251 | } 252 | } 253 | } 254 | } 255 | } 256 | return 0; 257 | } 258 | 259 | int init_kernel(CLContext* ctx, char** names) { 260 | return create_kernel(ctx, names); 261 | } 262 | 263 | int pd_init_cl(CLContext* ctx, unsigned char** src, size_t* size, 264 | char** names) { 265 | if (!ctx) { 266 | ctx = malloc(sizeof(CLContext)); 267 | } 268 | if (get_devices(ctx, src, size) != 0) { 269 | return 1; 270 | } 271 | return init_kernel(ctx, names); 272 | } 273 | 274 | void destroy_cl(CLContext* ctx) { 275 | size_t i; 276 | for (i = 0; i < ctx->num_devices; i++) { 277 | clFlush(ctx->clcmdq[i]); 278 | clFinish(ctx->clcmdq[i]); 279 | } 280 | } 281 | 282 | void finalize_cl(CLContext* ctx) { 283 | size_t i, j; 284 | destroy_cl(ctx); 285 | for (i = 0; i < ctx->num_devices; i++) { 286 | if (&(ctx->kernel) != NULL) { 287 | for (j = 0; j < ctx->kernel.num_kernels; j++) { 288 | clReleaseKernel(ctx->clkernel[i][j]); 289 | } 290 | if (ctx->kernel.num_src > 0) 291 | clReleaseProgram(ctx->programs[i]); 292 | for (j = 0; j < ctx->kernel.num_buffers; j++) { 293 | clReleaseMemObject(ctx->buffers[i][j]); 294 | } 295 | } 296 | clReleaseCommandQueue(ctx->clcmdq[i]); 297 | clReleaseContext(ctx->clctx[i]); 298 | clReleaseDevice(ctx->device[i]); 299 | } 300 | stubOpenclReset(); 301 | } 302 | -------------------------------------------------------------------------------- /src/lib/claccess/clcontext.h: -------------------------------------------------------------------------------- 1 | #ifndef CLCONTEXT_H 2 | #define CLCONTEXT_H 3 | 4 | /* 5 | #ifdef __APPLE__ 6 | #include 7 | #else 8 | #include 9 | #endif 10 | */ 11 | #include "libopencl.h" 12 | 13 | #define CLCONTEXT_MAX_DEVICES (16) 14 | #define MAX_PLATFORMS (8) 15 | #define MAX_KERNELS (18) 16 | //#define MAX_PROGRAMS (18) 17 | #define MAX_BUFFERS (18) 18 | #define INIT_FLAG_COUNT (2) 19 | 20 | enum cl_flag_t { CLCURL_SUCCESS, CLCURL_FAIL }; 21 | 22 | typedef struct { 23 | size_t size; 24 | cl_mem_flags flags; 25 | size_t init_flag; 26 | } BufferInfo; 27 | 28 | typedef struct { 29 | BufferInfo buffer[MAX_BUFFERS]; 30 | size_t num_buffers; 31 | size_t num_kernels; 32 | size_t num_src; 33 | } KernelInfo; 34 | 35 | typedef struct { 36 | cl_uint num_devices; 37 | cl_device_id device[CLCONTEXT_MAX_DEVICES]; 38 | cl_command_queue clcmdq[CLCONTEXT_MAX_DEVICES]; 39 | cl_mem buffers[CLCONTEXT_MAX_DEVICES][MAX_BUFFERS]; 40 | cl_kernel clkernel[CLCONTEXT_MAX_DEVICES][MAX_KERNELS]; 41 | cl_program programs[CLCONTEXT_MAX_DEVICES]; 42 | cl_context clctx[CLCONTEXT_MAX_DEVICES]; 43 | cl_uint num_cores[CLCONTEXT_MAX_DEVICES]; 44 | size_t num_multiple[CLCONTEXT_MAX_DEVICES]; 45 | cl_ulong max_memory[CLCONTEXT_MAX_DEVICES]; 46 | KernelInfo kernel; 47 | } CLContext; 48 | 49 | int kernel_init_buffers(CLContext* ctx); 50 | void init_cl(CLContext* ctx); 51 | // void pd_init_cl(CLContext *ctx, unsigned char *const *src, size_t *size,const 52 | // char **names); 53 | int pd_init_cl(CLContext* ctx, unsigned char** src, size_t* size, char** names); 54 | void destroy_cl(CLContext* ctx); 55 | void finalize_cl(CLContext* ctx); 56 | // int check_clerror(cl_int err, char *comment, ...); 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/lib/constants.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONST_H__ 2 | #define __CONST_H__ 3 | 4 | #define HASH_LENGTH 243 5 | #define NONCE_LENGTH HASH_LENGTH / 3 6 | #define MESSAGE_LENGTH 6561 7 | #define INT_LENGTH NONCE_LENGTH / 3 8 | #define VALUE_LENGTH 81 9 | #define VALUE_USABLE_LENGTH 33 10 | #define NUMBER_OF_ROUNDS 81 11 | 12 | #endif //__CONST_H__ 13 | 14 | -------------------------------------------------------------------------------- /src/lib/curl.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2016 Paul Handy, based on code from come-from-beyond 3 | */ 4 | 5 | #include "curl.h" 6 | #include "hash.h" 7 | #include "constants.h" 8 | #include 9 | #include 10 | #include 11 | 12 | #define __TRUTH_TABLE 1, 0, -1, 2, 1, -1, 0, 2, -1, 1, 0 13 | 14 | #define __INDEX_TABLE \ 15 | 0, 364, 728, 363, 727, 362, 726, 361, 725, 360, 724, 359, 723, 358, 722,\ 16 | 357, 721, 356, 720, 355, 719, 354, 718, 353, 717, 352, 716, 351, 715, 350,\ 17 | 714, 349, 713, 348, 712, 347, 711, 346, 710, 345, 709, 344, 708, 343, 707,\ 18 | 342, 706, 341, 705, 340, 704, 339, 703, 338, 702, 337, 701, 336, 700, 335,\ 19 | 699, 334, 698, 333, 697, 332, 696, 331, 695, 330, 694, 329, 693, 328, 692,\ 20 | 327, 691, 326, 690, 325, 689, 324, 688, 323, 687, 322, 686, 321, 685, 320,\ 21 | 684, 319, 683, 318, 682, 317, 681, 316, 680, 315, 679, 314, 678, 313, 677,\ 22 | 312, 676, 311, 675, 310, 674, 309, 673, 308, 672, 307, 671, 306, 670, 305,\ 23 | 669, 304, 668, 303, 667, 302, 666, 301, 665, 300, 664, 299, 663, 298, 662,\ 24 | 297, 661, 296, 660, 295, 659, 294, 658, 293, 657, 292, 656, 291, 655, 290,\ 25 | 654, 289, 653, 288, 652, 287, 651, 286, 650, 285, 649, 284, 648, 283, 647,\ 26 | 282, 646, 281, 645, 280, 644, 279, 643, 278, 642, 277, 641, 276, 640, 275,\ 27 | 639, 274, 638, 273, 637, 272, 636, 271, 635, 270, 634, 269, 633, 268, 632,\ 28 | 267, 631, 266, 630, 265, 629, 264, 628, 263, 627, 262, 626, 261, 625, 260,\ 29 | 624, 259, 623, 258, 622, 257, 621, 256, 620, 255, 619, 254, 618, 253, 617,\ 30 | 252, 616, 251, 615, 250, 614, 249, 613, 248, 612, 247, 611, 246, 610, 245,\ 31 | 609, 244, 608, 243, 607, 242, 606, 241, 605, 240, 604, 239, 603, 238, 602,\ 32 | 237, 601, 236, 600, 235, 599, 234, 598, 233, 597, 232, 596, 231, 595, 230,\ 33 | 594, 229, 593, 228, 592, 227, 591, 226, 590, 225, 589, 224, 588, 223, 587,\ 34 | 222, 586, 221, 585, 220, 584, 219, 583, 218, 582, 217, 581, 216, 580, 215,\ 35 | 579, 214, 578, 213, 577, 212, 576, 211, 575, 210, 574, 209, 573, 208, 572,\ 36 | 207, 571, 206, 570, 205, 569, 204, 568, 203, 567, 202, 566, 201, 565, 200,\ 37 | 564, 199, 563, 198, 562, 197, 561, 196, 560, 195, 559, 194, 558, 193, 557,\ 38 | 192, 556, 191, 555, 190, 554, 189, 553, 188, 552, 187, 551, 186, 550, 185,\ 39 | 549, 184, 548, 183, 547, 182, 546, 181, 545, 180, 544, 179, 543, 178, 542,\ 40 | 177, 541, 176, 540, 175, 539, 174, 538, 173, 537, 172, 536, 171, 535, 170,\ 41 | 534, 169, 533, 168, 532, 167, 531, 166, 530, 165, 529, 164, 528, 163, 527,\ 42 | 162, 526, 161, 525, 160, 524, 159, 523, 158, 522, 157, 521, 156, 520, 155,\ 43 | 519, 154, 518, 153, 517, 152, 516, 151, 515, 150, 514, 149, 513, 148, 512,\ 44 | 147, 511, 146, 510, 145, 509, 144, 508, 143, 507, 142, 506, 141, 505, 140,\ 45 | 504, 139, 503, 138, 502, 137, 501, 136, 500, 135, 499, 134, 498, 133, 497,\ 46 | 132, 496, 131, 495, 130, 494, 129, 493, 128, 492, 127, 491, 126, 490, 125,\ 47 | 489, 124, 488, 123, 487, 122, 486, 121, 485, 120, 484, 119, 483, 118, 482,\ 48 | 117, 481, 116, 480, 115, 479, 114, 478, 113, 477, 112, 476, 111, 475, 110,\ 49 | 474, 109, 473, 108, 472, 107, 471, 106, 470, 105, 469, 104, 468, 103, 467,\ 50 | 102, 466, 101, 465, 100, 464, 99, 463, 98, 462, 97, 461, 96, 460, 95,\ 51 | 459, 94, 458, 93, 457, 92, 456, 91, 455, 90, 454, 89, 453, 88, 452,\ 52 | 87, 451, 86, 450, 85, 449, 84, 448, 83, 447, 82, 446, 81, 445, 80,\ 53 | 444, 79, 443, 78, 442, 77, 441, 76, 440, 75, 439, 74, 438, 73, 437,\ 54 | 72, 436, 71, 435, 70, 434, 69, 433, 68, 432, 67, 431, 66, 430, 65,\ 55 | 429, 64, 428, 63, 427, 62, 426, 61, 425, 60, 424, 59, 423, 58, 422,\ 56 | 57, 421, 56, 420, 55, 419, 54, 418, 53, 417, 52, 416, 51, 415, 50,\ 57 | 414, 49, 413, 48, 412, 47, 411, 46, 410, 45, 409, 44, 408, 43, 407,\ 58 | 42, 406, 41, 405, 40, 404, 39, 403, 38, 402, 37, 401, 36, 400, 35,\ 59 | 399, 34, 398, 33, 397, 32, 396, 31, 395, 30, 394, 29, 393, 28, 392,\ 60 | 27, 391, 26, 390, 25, 389, 24, 388, 23, 387, 22, 386, 21, 385, 20,\ 61 | 384, 19, 383, 18, 382, 17, 381, 16, 380, 15, 379, 14, 378, 13, 377,\ 62 | 12, 376, 11, 375, 10, 374, 9, 373, 8, 372, 7, 371, 6, 370, 5,\ 63 | 369, 4, 368, 3, 367, 2, 366, 1, 365, 0 64 | 65 | 66 | static const size_t TRUTH_TABLE[11] = {__TRUTH_TABLE}; 67 | static const size_t INDEX[STATE_LENGTH+1] = {__INDEX_TABLE}; 68 | 69 | void transform(curl_t* ctx); 70 | 71 | void init_curl(curl_t* ctx) { 72 | memset(ctx->state, 0, STATE_LENGTH * sizeof(char)); 73 | } 74 | int i = 0; 75 | void absorb(curl_t* ctx, char* const trits, int length) { 76 | int offset = 0; 77 | do { 78 | memcpy(ctx->state, trits + offset, 79 | (length < HASH_LENGTH ? length : HASH_LENGTH) * sizeof(char)); 80 | transform(ctx); 81 | offset += HASH_LENGTH; 82 | } while ((length -= HASH_LENGTH) > 0); 83 | } 84 | 85 | void squeeze(curl_t* ctx, char* trits, int length) { 86 | int offset = 0; 87 | do { 88 | // memcpy(trits+offset, ctx->state, (length < HASH_LENGTH? length: 89 | // HASH_LENGTH) * sizeof(char)); 90 | memcpy(&(trits[offset]), ctx->state, 91 | (length < HASH_LENGTH ? length : HASH_LENGTH) * sizeof(char)); 92 | transform(ctx); 93 | offset += HASH_LENGTH; 94 | } while ((length -= HASH_LENGTH) > 0); 95 | } 96 | 97 | void transform(curl_t* ctx) { 98 | int round, stateIndex; 99 | char scratchpad[STATE_LENGTH]; 100 | for (round = 0; round < NUMBER_OF_ROUNDS; round++) { 101 | memcpy(scratchpad, ctx->state, STATE_LENGTH * sizeof(char)); 102 | for (stateIndex = 0; stateIndex < STATE_LENGTH; stateIndex++) { 103 | ctx->state[stateIndex] = TRUTH_TABLE[scratchpad[INDEX[stateIndex]] + 104 | (scratchpad[INDEX[stateIndex+1]]<<2) +5 ]; 105 | } 106 | } 107 | } 108 | 109 | void reset(curl_t* ctx) { memset(ctx->state, 0, STATE_LENGTH * sizeof(char)); } 110 | -------------------------------------------------------------------------------- /src/lib/curl.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef CURL_H 3 | #define CURL_H 4 | #include "hash.h" 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | typedef struct { char state[STATE_LENGTH]; } curl_t; 11 | 12 | EXPORT void init_curl(curl_t* ctx); 13 | 14 | EXPORT void absorb(curl_t* ctx, char* const trits, int length); 15 | EXPORT void squeeze(curl_t* ctx, char* const trits, int length); 16 | EXPORT void reset(curl_t* ctx); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/lib/exports.c: -------------------------------------------------------------------------------- 1 | #include "curl.h" 2 | #include "util/converter.h" 3 | #include 4 | #include 5 | 6 | EXPORT char* ccurl_digest_transaction(char* trytes) { 7 | char* hash; 8 | curl_t curl; 9 | init_curl(&curl); 10 | size_t length = strnlen(trytes, TRANSACTION_LENGTH); 11 | char digest[HASH_LENGTH]; 12 | char* input = 13 | trits_from_trytes(trytes, length < TRYTE_LENGTH ? length : TRYTE_LENGTH); 14 | absorb(&curl, input, length * 3); 15 | squeeze(&curl, digest, HASH_LENGTH); 16 | hash = trytes_from_trits(digest, 0, HASH_LENGTH); 17 | // hash[HASH_LENGTH] = 0; 18 | free((void*) input); 19 | return hash; 20 | } 21 | -------------------------------------------------------------------------------- /src/lib/exports_cl.c: -------------------------------------------------------------------------------- 1 | #include "curl.h" 2 | #include "pearcldiver.h" 3 | #include "transaction.h" 4 | #include "pearl_diver.h" 5 | #include "util/converter.h" 6 | #include 7 | #include 8 | 9 | typedef struct pdcl_node { 10 | PearCLDiver* pdcl; 11 | int initialized; 12 | int cl_available; 13 | struct pdcl_node* next; 14 | } pdcl_node_t; 15 | 16 | pdcl_node_t base; 17 | size_t loop_count = 32; 18 | size_t offset = 0; 19 | 20 | int ccurl_pow_node_init(pdcl_node_t* node) { 21 | if (!node->initialized) { 22 | node->pdcl = malloc(sizeof(PearCLDiver)); 23 | // size_t lc = node->pdcl->loop_count; 24 | memset(node->pdcl, 0, sizeof(PearCLDiver)); 25 | // memset(&pdcl, 0, sizeof(PearCLDiver)); 26 | // memset(&pearl_diver, 0, sizeof(PearlDiver)); 27 | // node->pdcl->loop_count = lc; 28 | node->cl_available = init_pearcl(node->pdcl); 29 | node->initialized = 1; 30 | } 31 | return node->cl_available; 32 | } 33 | 34 | EXPORT int ccurl_pow_init() { 35 | if (!base.initialized) { 36 | base.cl_available = ccurl_pow_node_init(&base); 37 | } 38 | return base.cl_available; 39 | } 40 | 41 | EXPORT void ccurl_pow_set_loop_count(size_t c) { 42 | if (c > 0) 43 | loop_count = c; 44 | } 45 | 46 | EXPORT void ccurl_pow_set_offset(size_t o) { offset = o; } 47 | 48 | void ccurl_pow_node_finalize(pdcl_node_t* node) { 49 | if (node->next != NULL) { 50 | fputs("free next", stderr); 51 | ccurl_pow_node_finalize(node->next); 52 | free(node->next); 53 | } 54 | node->initialized = 0; 55 | finalize_cl(&(node->pdcl->cl)); 56 | free(node->pdcl); 57 | } 58 | 59 | EXPORT void ccurl_pow_finalize() { ccurl_pow_node_finalize(&base); } 60 | 61 | EXPORT void ccurl_pow_interrupt() { 62 | pdcl_node_t* node = &base; 63 | do { 64 | interrupt(&node->pdcl->pd); 65 | node = node->next; 66 | } while (node != NULL); 67 | } 68 | 69 | EXPORT char* ccurl_pow(char* trytes, int minWeightMagnitude) { 70 | char* buf = NULL; //= malloc(sizeof(char)*TRYTE_LENGTH); 71 | size_t len = strnlen(trytes, TRANSACTION_LENGTH/3); 72 | char* trits = trits_from_trytes(trytes, len); 73 | pdcl_node_t* pd_node = &base; 74 | 75 | ccurl_pow_node_init(pd_node); 76 | while (pd_node->pdcl->pd.status == PD_SEARCHING) { 77 | if (pd_node->next != NULL) { 78 | pd_node = pd_node->next; 79 | } 80 | } 81 | 82 | curl_t curl; 83 | init_curl(&curl); 84 | absorb(&curl, trits, TRANSACTION_LENGTH - HASH_LENGTH); 85 | memcpy(&curl.state, &trits[TRANSACTION_LENGTH - HASH_LENGTH], HASH_LENGTH * sizeof(char)); 86 | 87 | if (ccurl_pow_node_init(pd_node) == 0) { 88 | if (pd_node->pdcl->loop_count < 1) { 89 | pd_node->pdcl->loop_count = loop_count; 90 | } 91 | #ifdef DEBUG 92 | fprintf(stderr, "OpenCL Hashing with %lu loops...\n", pd_node->pdcl->loop_count); 93 | #endif 94 | pearcl_search(pd_node->pdcl, &curl, offset, minWeightMagnitude); 95 | } 96 | if (pd_node->pdcl->pd.status != PD_FOUND && 97 | pd_node->pdcl->pd.status != PD_INVALID && 98 | pd_node->pdcl->pd.status != PD_INTERRUPTED) { 99 | #ifdef DEBUG 100 | fprintf(stderr, "Thread Hashing...\n"); 101 | #endif 102 | pd_search(&(pd_node->pdcl->pd), &curl, minWeightMagnitude, -1); 103 | } 104 | if (pd_node->pdcl->pd.status == PD_FOUND) { 105 | memcpy(&trits[TRANSACTION_LENGTH - HASH_LENGTH], &curl.state, HASH_LENGTH * sizeof(char)); 106 | buf = trytes_from_trits(trits, 0, TRANSACTION_LENGTH); 107 | } 108 | 109 | free(trits); 110 | pd_node->pdcl->pd.status = PD_FINISHED; 111 | return buf; 112 | } 113 | -------------------------------------------------------------------------------- /src/lib/hash.h: -------------------------------------------------------------------------------- 1 | #ifndef HASH_H 2 | #define HASH_H 3 | 4 | #ifndef EXPORT 5 | #if defined(_WIN32) 6 | #define EXPORT __declspec(dllexport) 7 | #else 8 | #define EXPORT 9 | #endif 10 | #endif 11 | #if defined(_WIN32) && !defined(MINGW) 12 | #else 13 | #include 14 | #endif 15 | 16 | #include 17 | #define HASH_LENGTH 243 18 | #define STATE_LENGTH 3 * HASH_LENGTH 19 | #define TRYTE_LENGTH 2673 20 | #define TRANSACTION_LENGTH TRYTE_LENGTH * 3 21 | typedef int64_t bc_trit_t; 22 | typedef char trit_t; 23 | 24 | #ifndef DEBUG 25 | #define DEBUG 26 | #endif // DEBUG 27 | #endif 28 | -------------------------------------------------------------------------------- /src/lib/pearcldiver.c: -------------------------------------------------------------------------------- 1 | #include "pearcldiver.h" 2 | #include "claccess/clcontext.h" 3 | #include "constants.h" 4 | #include "hash.h" 5 | #include "pearl.cl.h" 6 | #include "pearl_diver.h" 7 | #include 8 | #include 9 | #include 10 | #include 11 | #if defined(_WIN32) && !defined(__MINGW32__) 12 | #else 13 | #include 14 | #endif 15 | 16 | #ifndef PD_NUM_SRC 17 | #define PD_NUM_SRC 1 18 | #endif /*PD_NUM_SRC*/ 19 | 20 | typedef struct { 21 | States states; 22 | char* trits; 23 | curl_t *curl; 24 | size_t min_weight_magnitude; 25 | size_t index; 26 | size_t offset; 27 | PearCLDiver* pdcl; 28 | } PDCLThread; 29 | 30 | int init_pearcl(PearCLDiver* pdcl) { 31 | CLContext* cl; 32 | unsigned char* src[PD_NUM_SRC] = {pearl_cl}; 33 | size_t size[PD_NUM_SRC] = {pearl_cl_len}; 34 | char** names = (char* []){"init", "search", "finalize"}; 35 | if (!pdcl) { 36 | pdcl = malloc(sizeof(PearCLDiver)); 37 | } 38 | cl = &(pdcl->cl); 39 | cl->kernel.num_src = PD_NUM_SRC; 40 | cl->kernel.num_kernels = 3; 41 | if (pd_init_cl(cl, src, size, names) != 0) { 42 | return 1; 43 | } 44 | cl->kernel.num_buffers = 9; 45 | cl->kernel.buffer[0] = (BufferInfo){sizeof(char) * HASH_LENGTH, 46 | CL_MEM_WRITE_ONLY}; // trit_hash // 47 | cl->kernel.buffer[1] = (BufferInfo){sizeof(bc_trit_t) * STATE_LENGTH, 48 | CL_MEM_READ_WRITE, 2}; // states array // 49 | cl->kernel.buffer[2] = (BufferInfo){sizeof(bc_trit_t) * STATE_LENGTH, 50 | CL_MEM_READ_WRITE, 2}; // states array // 51 | cl->kernel.buffer[3] = (BufferInfo){sizeof(bc_trit_t) * STATE_LENGTH, 52 | CL_MEM_READ_WRITE, 2}; // states array // 53 | cl->kernel.buffer[4] = (BufferInfo){sizeof(bc_trit_t) * STATE_LENGTH, 54 | CL_MEM_READ_WRITE, 2}; // states array // 55 | cl->kernel.buffer[5] = 56 | (BufferInfo){sizeof(size_t), CL_MEM_READ_ONLY}; // minweightmagnitude // 57 | cl->kernel.buffer[6] = 58 | (BufferInfo){sizeof(char), CL_MEM_READ_WRITE}; // found // 59 | cl->kernel.buffer[7] = 60 | (BufferInfo){sizeof(bc_trit_t), CL_MEM_READ_WRITE, 2}; // nonce_probe // 61 | cl->kernel.buffer[8] = 62 | (BufferInfo){sizeof(size_t), CL_MEM_READ_ONLY}; // loop_length // 63 | 64 | return kernel_init_buffers(cl); 65 | } 66 | 67 | void pearcl_write_buffers(PDCLThread* thread) { 68 | PearCLDiver* pdcl = thread->pdcl; 69 | CLContext* cl = &(pdcl->cl); 70 | cl_command_queue* cmdq = &(cl->clcmdq[thread->index]); 71 | cl_mem* mem = cl->buffers[thread->index]; 72 | BufferInfo* bufinfo = cl->kernel.buffer; 73 | 74 | clEnqueueWriteBuffer(*cmdq, mem[1], CL_TRUE, 0, bufinfo[1].size, 75 | &(thread->states.mid_low), 0, NULL, NULL); 76 | clEnqueueWriteBuffer(*cmdq, mem[2], CL_TRUE, 0, bufinfo[2].size, 77 | &(thread->states.mid_high), 0, NULL, NULL); 78 | clEnqueueWriteBuffer(*cmdq, mem[5], CL_TRUE, 0, bufinfo[5].size, 79 | &(thread->min_weight_magnitude), 0, NULL, NULL); 80 | clEnqueueWriteBuffer(*cmdq, mem[8], CL_TRUE, 0, bufinfo[8].size, 81 | &(pdcl->loop_count), 0, NULL, NULL); 82 | /* 83 | fprintf(stderr, "E: failed to write mid state low"); 84 | fprintf(stderr, "E: failed to write mid state low"); 85 | fprintf(stderr, "E: failed to write min_weight_magnitude"); 86 | fprintf(stderr, "E: failed to write min_weight_magnitude"); 87 | */ 88 | } 89 | #if defined(_WIN32) && !defined(__MINGW32__) 90 | DWORD WINAPI pearcl_find(void* data) { 91 | #else 92 | void* pearcl_find(void* data) { 93 | #endif 94 | size_t local_work_size, global_work_size, global_offset, num_groups; 95 | char found = 0; 96 | cl_event ev, ev1; 97 | PDCLThread* thread; 98 | PearCLDiver* pdcl; 99 | int i; 100 | thread = (PDCLThread*)data; 101 | global_offset = thread->offset; 102 | pdcl = thread->pdcl; 103 | num_groups = (pdcl->cl.num_cores[thread->index]); 104 | local_work_size = STATE_LENGTH; 105 | while (local_work_size > pdcl->cl.num_multiple[thread->index]) { 106 | local_work_size /= 3; 107 | } 108 | global_work_size = local_work_size * num_groups; 109 | 110 | for (i = 0; i < thread->index; i++) { 111 | global_offset += pdcl->cl.num_cores[i]; 112 | } 113 | pearcl_write_buffers(thread); 114 | 115 | if (CL_SUCCESS == clEnqueueNDRangeKernel(pdcl->cl.clcmdq[thread->index], 116 | pdcl->cl.clkernel[thread->index][0], 117 | 1, &global_offset, &global_work_size, 118 | &local_work_size, 0, NULL, &ev)) { 119 | clWaitForEvents(1, &ev); 120 | clReleaseEvent(ev); 121 | 122 | while (found == 0 && pdcl->pd.status == PD_SEARCHING) { 123 | if (clEnqueueNDRangeKernel(pdcl->cl.clcmdq[thread->index], 124 | pdcl->cl.clkernel[thread->index][1], 1, NULL, 125 | &global_work_size, &local_work_size, 0, NULL, 126 | &ev1) != CL_SUCCESS) { 127 | clReleaseEvent(ev1); 128 | fprintf(stderr, "E: running search kernel failed. \n"); 129 | break; 130 | } 131 | clWaitForEvents(1, &ev1); 132 | clReleaseEvent(ev1); 133 | if (CL_SUCCESS != clEnqueueReadBuffer(pdcl->cl.clcmdq[thread->index], 134 | pdcl->cl.buffers[thread->index][6], 135 | CL_TRUE, 0, sizeof(char), &found, 0, 136 | NULL, NULL)) { 137 | fprintf(stderr, "E: reading finished bool failed.\n"); 138 | break; 139 | } 140 | } 141 | } else { 142 | fprintf(stderr, "E: running init kernel failed.\n"); 143 | clReleaseEvent(ev); 144 | } 145 | 146 | if (CL_SUCCESS != clEnqueueNDRangeKernel(pdcl->cl.clcmdq[thread->index], 147 | pdcl->cl.clkernel[thread->index][2], 148 | 1, NULL, &global_work_size, 149 | &local_work_size, 0, NULL, &ev)) 150 | fprintf(stderr, "E: running finalize kernel failed.\n"); 151 | 152 | if (found > 0) { 153 | pthread_mutex_lock(&pdcl->pd.new_thread_search); 154 | if (pdcl->pd.status != PD_FOUND) { 155 | pdcl->pd.status = PD_FOUND; 156 | if (CL_SUCCESS != clEnqueueReadBuffer( 157 | pdcl->cl.clcmdq[thread->index], 158 | pdcl->cl.buffers[thread->index][0], CL_TRUE, 0, 159 | HASH_LENGTH * sizeof(char), 160 | &(thread->curl[0]), 161 | //&(thread->trits[TRANSACTION_LENGTH - HASH_LENGTH]), 162 | 1, &ev, NULL)) { 163 | } 164 | } 165 | pthread_mutex_unlock(&pdcl->pd.new_thread_search); 166 | } 167 | clReleaseEvent(ev); 168 | return 0; 169 | } 170 | 171 | void pearcl_search( 172 | PearCLDiver* pdcl, 173 | curl_t * const curl, 174 | size_t offset, 175 | size_t min_weight_magnitude 176 | ) { 177 | int k, thread_count; 178 | int numberOfThreads = pdcl->cl.num_devices; 179 | 180 | if (min_weight_magnitude > HASH_LENGTH) { 181 | pdcl->pd.status = PD_INVALID; 182 | return; 183 | } 184 | 185 | pdcl->pd.status = PD_SEARCHING; 186 | 187 | States states; 188 | pd_search_init(&states, curl, HASH_LENGTH - NONCE_LENGTH); 189 | 190 | if (numberOfThreads == 0) { 191 | pdcl->pd.status = PD_FAILED; 192 | return; 193 | } 194 | 195 | pthread_mutex_init(&pdcl->pd.new_thread_search, NULL); 196 | pthread_t* tid = malloc(numberOfThreads * sizeof(pthread_t)); 197 | thread_count = numberOfThreads; 198 | 199 | PDCLThread* pdthreads = 200 | (PDCLThread*)malloc(numberOfThreads * sizeof(PDCLThread)); 201 | while (numberOfThreads-- > 0) { 202 | pdthreads[numberOfThreads] = 203 | (PDCLThread){.states = states, 204 | .curl = curl, 205 | .min_weight_magnitude = min_weight_magnitude, 206 | .index = numberOfThreads, 207 | .offset = offset, 208 | .pdcl = pdcl}; 209 | pthread_create(&tid[numberOfThreads], NULL, &pearcl_find, 210 | (void*)&(pdthreads[numberOfThreads])); 211 | } 212 | 213 | sched_yield(); 214 | for (k = thread_count; k > 0; k--) { 215 | pthread_join(tid[k - 1], NULL); 216 | } 217 | 218 | pthread_mutex_destroy(&pdcl->pd.new_thread_search); 219 | free(tid); 220 | free(pdthreads); 221 | // return pdcl->pd.interrupted; 222 | } 223 | -------------------------------------------------------------------------------- /src/lib/pearcldiver.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _PEARCLDIVER_H_ 3 | #define _PEARCLDIVER_H_ 4 | #include "claccess/clcontext.h" 5 | #include "pearl_diver.h" 6 | //#include "hash.h" 7 | 8 | typedef struct { 9 | CLContext cl; 10 | PearlDiver pd; 11 | size_t num_groups; 12 | size_t loop_count; 13 | } PearCLDiver; 14 | 15 | int init_pearcl(PearCLDiver* pd); 16 | void pearcl_search( 17 | PearCLDiver* pdcl, 18 | curl_t* const curl, 19 | size_t offset, 20 | size_t min_weight_magnitude 21 | ); 22 | #endif /* _PEARCLDIVER_H_ */ 23 | -------------------------------------------------------------------------------- /src/lib/pearl_diver.c: -------------------------------------------------------------------------------- 1 | #include "pearl_diver.h" 2 | #include "constants.h" 3 | #include "hash.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #if defined(_WIN32) && !defined(__MINGW32__) 9 | #include 10 | #else 11 | #include 12 | #endif 13 | 14 | 15 | #define OFFSET_LENGTH 4 16 | #define NONCE_START HASH_LENGTH - NONCE_LENGTH 17 | #define NONCE_INIT_START NONCE_START + OFFSET_LENGTH 18 | #define NONCE_INCREMENT_START NONCE_INIT_START + INT_LENGTH 19 | 20 | typedef struct { 21 | States* states; 22 | char* trits; 23 | int min_weight_magnitude; 24 | int threadIndex; 25 | PearlDiver* ctx; 26 | } PDThread; 27 | 28 | #if defined(_WIN32) && !defined(__MINGW32__) 29 | DWORD WINAPI find_nonce(void* data); 30 | #else 31 | void* find_nonce(void* states); 32 | #endif 33 | 34 | void interrupt(PearlDiver* ctx) { 35 | pthread_mutex_lock(&ctx->new_thread_search); 36 | if (ctx->status == PD_SEARCHING) { 37 | ctx->status = PD_INTERRUPTED; 38 | } 39 | pthread_mutex_unlock(&ctx->new_thread_search); 40 | } 41 | 42 | void pd_search( 43 | PearlDiver* ctx, 44 | curl_t *const curl, 45 | const int min_weight_magnitude, 46 | int numberOfThreads 47 | ) { 48 | int k, thread_count; 49 | 50 | if (min_weight_magnitude < 0 || 51 | min_weight_magnitude > HASH_LENGTH) { 52 | ctx->status = PD_INVALID; 53 | 54 | #ifdef DEBUG 55 | fprintf(stderr, "E: Invalid arguments.\n"); 56 | #endif 57 | return; 58 | } 59 | 60 | ctx->status = PD_SEARCHING; 61 | 62 | States states; 63 | pd_search_init(&states, curl, HASH_LENGTH - NONCE_LENGTH); 64 | 65 | if (numberOfThreads <= 0) { 66 | 67 | #if defined(_WIN32) 68 | SYSTEM_INFO sysinfo; 69 | GetSystemInfo(&sysinfo); 70 | numberOfThreads = sysinfo.dwNumberOfProcessors; 71 | #else 72 | numberOfThreads = sysconf(_SC_NPROCESSORS_ONLN) - 1; 73 | #endif 74 | if (numberOfThreads < 1) 75 | numberOfThreads = 1; 76 | } 77 | 78 | pthread_mutex_init(&ctx->new_thread_search, NULL); 79 | pthread_t tid[numberOfThreads]; 80 | 81 | PDThread pdthreads[numberOfThreads]; 82 | thread_count = 0; 83 | #ifdef DEBUG 84 | fprintf(stderr, "I: Starting search threads.\n"); 85 | #endif 86 | while (thread_count < numberOfThreads) { 87 | 88 | pdthreads[thread_count] = 89 | (PDThread){.states = &states, 90 | .trits = curl->state, 91 | .min_weight_magnitude = min_weight_magnitude, 92 | .threadIndex = thread_count, 93 | .ctx = ctx}; 94 | if(pthread_create(&tid[thread_count], NULL, &find_nonce, 95 | (void*)&(pdthreads[thread_count]))) { 96 | //tid[thread_count] = 0; 97 | } 98 | thread_count++; 99 | } 100 | 101 | for (k = 0; k < thread_count; k++) { 102 | // Could be that thread creation has failed. 103 | if(tid[k]) { 104 | pthread_join(tid[k], NULL); 105 | } 106 | } 107 | 108 | #ifdef DEBUG 109 | fprintf(stderr, "I: Found threads. Returning.\n"); 110 | #endif 111 | return; // ctx->status == PD_INTERRUPTED; 112 | } 113 | 114 | void pd_search_init(States* states, curl_t* curl, size_t offset) { 115 | int i; 116 | for (i = 0; i < STATE_LENGTH; i++) { 117 | switch (curl->state[i]) { 118 | case 0: { 119 | states->mid_low[i] = HIGH_BITS; 120 | states->mid_high[i] = HIGH_BITS; 121 | } break; 122 | case 1: { 123 | states->mid_low[i] = LOW_BITS; 124 | states->mid_high[i] = HIGH_BITS; 125 | } break; 126 | default: { 127 | states->mid_low[i] = HIGH_BITS; 128 | states->mid_high[i] = LOW_BITS; 129 | } 130 | } 131 | } 132 | states->mid_low[offset] = LOW_0; 133 | states->mid_high[offset] = HIGH_0; 134 | states->mid_low[offset + 1] = LOW_1; 135 | states->mid_high[offset + 1] = HIGH_1; 136 | states->mid_low[offset + 2] = LOW_2; 137 | states->mid_high[offset + 2] = HIGH_2; 138 | states->mid_low[offset + 3] = LOW_3; 139 | states->mid_high[offset + 3] = HIGH_3; 140 | 141 | } 142 | 143 | int is_found(bc_trit_t* low, bc_trit_t* high, int index, int min_weight_magnitude) { 144 | int i; 145 | for (i = min_weight_magnitude; i-- > 0;) { 146 | if ((((bc_trit_t)(low[HASH_LENGTH - 1 - i])) & (1 << index)) != 147 | (((bc_trit_t)(high[HASH_LENGTH - 1 - i])) & (1 << index))) { 148 | return 0; 149 | } 150 | } 151 | return 1; 152 | } 153 | 154 | int is_found_fast(bc_trit_t* low, bc_trit_t* high, int min_weight_magnitude) { 155 | int i; 156 | bc_trit_t lastMeasurement = HIGH_BITS; /* (low[index] >> bitIndex & 1) != 157 | (high[index] >> bitIndex & 1) */ 158 | for (i = min_weight_magnitude; i-- > 0;) { 159 | lastMeasurement &= ~(low[HASH_LENGTH - 1 - i] ^ high[HASH_LENGTH - 1 - i]); 160 | if (lastMeasurement == 0) { 161 | return 0; 162 | } 163 | } 164 | return lastMeasurement; 165 | } 166 | 167 | char ctxStatusEq(PDThread* thread, PearlDiver* ctx, int cmp) { 168 | #if defined(_WIN32) && !defined(__MINGW32__) 169 | EnterCriticalSection(&thread->ctx->new_thread_search); 170 | #else 171 | pthread_mutex_lock(&thread->ctx->new_thread_search); 172 | #endif 173 | 174 | char eq = ctx->status == cmp; 175 | 176 | #if defined(_WIN32) && !defined(__MINGW32__) 177 | LeaveCriticalSection(&thread->ctx->new_thread_search); 178 | #else 179 | pthread_mutex_unlock(&thread->ctx->new_thread_search); 180 | #endif 181 | 182 | return eq; 183 | } 184 | 185 | #if defined(_WIN32) && !defined(__MINGW32__) 186 | DWORD WINAPI find_nonce(void* data) { 187 | #else 188 | void* find_nonce(void* data) { 189 | #endif 190 | bc_trit_t midStateCopyLow[STATE_LENGTH], midStateCopyHigh[STATE_LENGTH]; 191 | int i, shift; 192 | bc_trit_t nonce_probe, nonce_output; 193 | PDThread* my_thread = (PDThread*)data; 194 | char* trits = my_thread->trits; 195 | 196 | memset(midStateCopyLow, 0, STATE_LENGTH * sizeof(bc_trit_t)); 197 | memset(midStateCopyHigh, 0, STATE_LENGTH * sizeof(bc_trit_t)); 198 | PearlDiver* ctx = my_thread->ctx; 199 | memcpy(midStateCopyLow, my_thread->states->mid_low, 200 | STATE_LENGTH * sizeof(bc_trit_t)); 201 | memcpy(midStateCopyHigh, my_thread->states->mid_high, 202 | STATE_LENGTH * sizeof(bc_trit_t)); 203 | 204 | for (i = my_thread->threadIndex; i-- > 0;) { 205 | pd_increment(midStateCopyLow, midStateCopyHigh, NONCE_INIT_START, 206 | NONCE_INCREMENT_START); 207 | } 208 | 209 | bc_trit_t scratchpadLow[STATE_LENGTH], scratchpadHigh[STATE_LENGTH], 210 | stateLow[STATE_LENGTH], stateHigh[STATE_LENGTH]; 211 | memset(stateLow, 0, STATE_LENGTH * sizeof(bc_trit_t)); 212 | memset(stateHigh, 0, STATE_LENGTH * sizeof(bc_trit_t)); 213 | memset(scratchpadLow, 0, STATE_LENGTH * sizeof(bc_trit_t)); 214 | memset(scratchpadHigh, 0, STATE_LENGTH * sizeof(bc_trit_t)); 215 | 216 | while (ctxStatusEq(my_thread, ctx, PD_SEARCHING)) { 217 | pd_increment(midStateCopyLow, midStateCopyHigh, NONCE_INCREMENT_START, 218 | HASH_LENGTH); 219 | memcpy(stateLow, midStateCopyLow, STATE_LENGTH * sizeof(bc_trit_t)); 220 | memcpy(stateHigh, midStateCopyHigh, STATE_LENGTH * sizeof(bc_trit_t)); 221 | pd_transform(stateLow, stateHigh, scratchpadLow, scratchpadHigh); 222 | 223 | if ((nonce_probe = is_found_fast(stateLow, stateHigh, 224 | my_thread->min_weight_magnitude)) == 0) 225 | continue; 226 | 227 | #if defined(_WIN32) && !defined(__MINGW32__) 228 | #ifdef _WIN64 229 | _BitScanForward64(&shift, nonce_probe); 230 | #else 231 | _BitScanForward(&shift, nonce_probe); 232 | #endif 233 | nonce_output = 1 << shift; 234 | EnterCriticalSection(&my_thread->ctx->new_thread_search); 235 | #else 236 | shift = __builtin_ctzll(nonce_probe); 237 | nonce_output = 1 << shift; 238 | pthread_mutex_lock(&my_thread->ctx->new_thread_search); 239 | #endif 240 | 241 | if (ctx->status != PD_FOUND) { 242 | ctx->status = PD_FOUND; 243 | for (i = 0; i < HASH_LENGTH; i++) { 244 | trits[i] = 245 | (((bc_trit_t)(midStateCopyLow[i]) & nonce_output) == 0) 246 | ? 1 247 | : ((((bc_trit_t)(midStateCopyHigh[i]) & nonce_output) == 0) ? -1 248 | : 0); 249 | } 250 | } 251 | 252 | #if defined(_WIN32) && !defined(__MINGW32__) 253 | LeaveCriticalSection(&my_thread->ctx->new_thread_search); 254 | #else 255 | pthread_mutex_unlock(&my_thread->ctx->new_thread_search); 256 | #endif 257 | 258 | return 0; 259 | } 260 | return 0; 261 | } 262 | 263 | void pd_transform(bc_trit_t* const stateLow, bc_trit_t* const stateHigh, 264 | bc_trit_t* const scratchpadLow, bc_trit_t* const scratchpadHigh) { 265 | 266 | int scratchpadIndex = 0, round, stateIndex; 267 | bc_trit_t alpha, beta, gamma, delta; 268 | 269 | for (round = NUMBER_OF_ROUNDS; round-- > 0;) { 270 | memcpy(scratchpadLow, stateLow, STATE_LENGTH * sizeof(bc_trit_t)); 271 | memcpy(scratchpadHigh, stateHigh, STATE_LENGTH * sizeof(bc_trit_t)); 272 | 273 | for (stateIndex = 0; stateIndex < STATE_LENGTH; stateIndex++) { 274 | 275 | alpha = scratchpadLow[scratchpadIndex]; 276 | beta = scratchpadHigh[scratchpadIndex]; 277 | gamma = scratchpadHigh[scratchpadIndex += 278 | (scratchpadIndex < 365 ? 364 : -365)]; 279 | delta = (alpha | (~gamma)) & (scratchpadLow[scratchpadIndex] ^ beta); 280 | 281 | stateLow[stateIndex] = ~delta; 282 | stateHigh[stateIndex] = (alpha ^ gamma) | delta; 283 | } 284 | } 285 | } 286 | void pd_increment(bc_trit_t* const mid_low, bc_trit_t* const mid_high, 287 | const int from_index, const int to_index) { 288 | 289 | size_t i; 290 | bc_trit_t carry = 1; 291 | bc_trit_t low, hi; 292 | for (i = from_index; i < to_index && carry != 0; i++) { 293 | low = mid_low[i]; 294 | hi = mid_high[i]; 295 | mid_low[i] = hi ^ low; 296 | mid_high[i] = low; 297 | carry = hi & (~low); 298 | } 299 | } 300 | -------------------------------------------------------------------------------- /src/lib/pearl_diver.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PEARLDIVER_H 3 | #define PEARLDIVER_H 4 | 5 | #include "curl.h" 6 | 7 | #if defined(_WIN32) 8 | #include 9 | #endif 10 | #if defined(_WIN32) && !defined(__MINGW32__) 11 | #else 12 | #include 13 | #endif 14 | #include "hash.h" 15 | #include 16 | 17 | #define Invalid_transaction_trits_length 0x63 18 | #define Invalid_min_weight_magnitude 0x64 19 | #define InterruptedException 0x65 20 | //#define HIGH_BITS 21 | //0b1111111111111111111111111111111111111111111111111111111111111111L 22 | //#define LOW_BITS 23 | //0b0000000000000000000000000000000000000000000000000000000000000000L 24 | #define HIGH_BITS 0xFFFFFFFFFFFFFFFF 25 | #define LOW_BITS 0x0000000000000000 26 | #define LOW_0 0xDB6DB6DB6DB6DB6D 27 | #define HIGH_0 0xB6DB6DB6DB6DB6DB 28 | #define LOW_1 0xF1F8FC7E3F1F8FC7 29 | #define HIGH_1 0x8FC7E3F1F8FC7E3F 30 | #define LOW_2 0x7FFFE00FFFFC01FF 31 | #define HIGH_2 0xFFC01FFFF803FFFF 32 | #define LOW_3 0xFFC0000007FFFFFF 33 | #define HIGH_3 0x003FFFFFFFFFFFFF 34 | 35 | #if defined(_WIN32) && !defined(__MINGW32__) 36 | #define pthread_mutex_init(A, B) InitializeCriticalSection(A) 37 | #define pthread_mutex_destroy(A) DeleteCriticalSection(A) 38 | #define pthread_t HANDLE 39 | #define pthread_create(A, B, C, D) *A = CreateThread(B, 0, C, D, 0, NULL) 40 | #define sched_yield() SwitchToThread() 41 | #define pthread_join(A, B) WaitForSingleObject(A, INFINITE) 42 | #define pthread_mutex_t CRITICAL_SECTION 43 | #define pthread_mutex_unlock(A) LeaveCriticalSection(A) 44 | // http://stackoverflow.com/questions/800383/what-is-the-difference-between-mutex-and-critical-section 45 | #define pthread_mutex_lock(A) EnterCriticalSection(A) 46 | #endif 47 | 48 | typedef struct { 49 | bc_trit_t mid_low[STATE_LENGTH]; 50 | bc_trit_t mid_high[STATE_LENGTH]; 51 | bc_trit_t low[STATE_LENGTH]; 52 | bc_trit_t high[STATE_LENGTH]; 53 | } States; 54 | 55 | typedef enum { 56 | PD_FINISHED, 57 | PD_SEARCHING, 58 | PD_FAILED, 59 | PD_FOUND, 60 | PD_INTERRUPTED, 61 | PD_INVALID 62 | } PDStatus; 63 | 64 | typedef struct { 65 | PDStatus status; 66 | pthread_mutex_t new_thread_search; 67 | } PearlDiver; 68 | 69 | void init_pearldiver(PearlDiver* ctx); 70 | void interrupt(PearlDiver* ctx); 71 | void pd_search(PearlDiver* ctx, curl_t* const curl, 72 | const int min_weight_magnitude, int numberOfThreads); 73 | void pd_transform(bc_trit_t* const stateLow, bc_trit_t* const stateHigh, 74 | bc_trit_t* const scratchpadLow, bc_trit_t* const scratchpadHigh); 75 | void pd_increment(bc_trit_t* const midStateCopyLow, bc_trit_t* const midStateCopyHigh, 76 | const int fromIndex, const int toIndex); 77 | void pd_search_init(States* states, curl_t *const curl, size_t offset); 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /src/lib/transaction.h: -------------------------------------------------------------------------------- 1 | #ifndef __TRANSACTION_H__ 2 | #define __TRANSACTION_H__ 3 | #include "constants.h" 4 | 5 | typedef struct __attribute__((packed)) { 6 | trit_t message[MESSAGE_LENGTH]; 7 | trit_t address[HASH_LENGTH]; 8 | trit_t value[VALUE_LENGTH]; 9 | trit_t obsolete_tag[NONCE_LENGTH]; 10 | trit_t timestamp[INT_LENGTH]; 11 | trit_t index[INT_LENGTH]; 12 | trit_t end[INT_LENGTH]; 13 | trit_t bundle[HASH_LENGTH]; 14 | trit_t trunk[HASH_LENGTH]; 15 | trit_t branch[HASH_LENGTH]; 16 | trit_t tag[NONCE_LENGTH]; 17 | trit_t attachment_timestamp[INT_LENGTH]; 18 | trit_t attachment_timestamp_lower_bound[INT_LENGTH]; 19 | trit_t attachment_timestamp_upper_bound[INT_LENGTH]; 20 | trit_t nonce[NONCE_LENGTH]; 21 | } transaction_t; 22 | #endif // __TRANSACTION_H__ 23 | 24 | -------------------------------------------------------------------------------- /src/lib/util/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.5) 2 | enable_language (C) 3 | project (iotaconverter) 4 | 5 | set(CMAKE_INSTALL_PREFIX "/usr") 6 | 7 | 8 | set (LIBRARY_NAME iotaconverter) 9 | 10 | set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0") 11 | #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread -Wall -g -O0") 12 | 13 | SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) 14 | SET (CTEST_BUILD_TARGET "RELEASE") 15 | 16 | set (SOURCES converter.c) 17 | 18 | #add_library(${LIBRARY_NAME } SHARED ${SOURCES }) 19 | add_library (${LIBRARY_NAME} SHARED ${SOURCES} ) 20 | #target_link_libraries(${LIBRARY_NAME } ${OPENCL_LIBRARIES }) 21 | 22 | set_target_properties (${LIBRARY_NAME} PROPERTIES 23 | LIBRARY_OUTPUT_DIRECTORY lib 24 | #LINK_FLAGS - lpthread 25 | ) 26 | 27 | install(TARGETS ${LIBRARY_NAME} 28 | LIBRARY DESTINATION lib 29 | ARCHIVE DESTINATION lib 30 | RUNTIME DESTINATION bin) 31 | 32 | #Install library headers 33 | file(GLOB HEADERS src/lib/*.h) 34 | install(FILES ${HEADERS} DESTINATION include) 35 | -------------------------------------------------------------------------------- /src/lib/util/converter.c: -------------------------------------------------------------------------------- 1 | #include "converter.h" 2 | #include 3 | #include 4 | #include 5 | 6 | //#define HASH_LENGTH 243 7 | #define TRYTE_SPACE 27 8 | #define MIN_TRYTE_VALUE -13 9 | #define MAX_TRYTE_VALUE 13 10 | #define RADIX 3 11 | #define MAX_TRIT_VALUE (RADIX - 1) / 2 12 | #define MIN_TRIT_VALUE -MAX_TRIT_VALUE 13 | #define NUMBER_OF_TRITS_IN_A_BYTE 5 14 | #define NUMBER_OF_TRITS_IN_A_TRYTE 3 15 | #define TRYTE_STRING "9ABCDEFGHIJKLMNOPQRSTUVWXYZ" 16 | 17 | //#define mytrits[NUMBER_OF_TRITS_IN_A_BYTE] 18 | // char trits[NUMBER_OF_TRITS_IN_A_BYTE]; 19 | //#define IN_BYTE_TO_TRITS[HASH_LENGTH][] 20 | //#define IN_TRYTE_TO_TRITS[HASH_LENGTH][] 21 | 22 | /* 23 | #define BLANK_BYTE_MAPPINGS 24 | {0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0} 25 | #define BLANK_TRYTE_MAPPINGS 26 | {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0} 27 | */ 28 | 29 | char BYTE_TO_TRITS_MAPPINGS 30 | [HASH_LENGTH][NUMBER_OF_TRITS_IN_A_BYTE]; /*[HASH_LENGTH] = (char *[]){ 31 | BLANK_BYTE_MAPPINGS };*/ 32 | char TRYTE_TO_TRITS_MAPPINGS 33 | [TRYTE_SPACE][NUMBER_OF_TRITS_IN_A_TRYTE]; /*[TRYTE_SPACE] = (char *[]){ 34 | BLANK_TRYTE_MAPPINGS };*/ 35 | 36 | static const char* TRYTE_ALPHABET = TRYTE_STRING; 37 | 38 | char long_value(char* const trits, const int offset, const int size) { 39 | int i; 40 | 41 | char value = 0; 42 | for (i = size; i-- > 0;) { 43 | value = value * RADIX + trits[offset + i]; 44 | } 45 | return value; 46 | } 47 | 48 | char* bytes_from_trits(char* const trits, const int offset, const int size) { 49 | int i, j; 50 | int length = 51 | (size + NUMBER_OF_TRITS_IN_A_BYTE - 1) / NUMBER_OF_TRITS_IN_A_BYTE; 52 | char* bytes = (char*)malloc(sizeof(char) * length); 53 | for (i = 0; i < length; i++) { 54 | 55 | char value = 0; 56 | for (j = (size - i * NUMBER_OF_TRITS_IN_A_BYTE) < 5 57 | ? (size - i * NUMBER_OF_TRITS_IN_A_BYTE) 58 | : NUMBER_OF_TRITS_IN_A_BYTE; 59 | j-- > 0;) { 60 | value = value * RADIX + trits[offset + i * NUMBER_OF_TRITS_IN_A_BYTE + j]; 61 | } 62 | bytes[i] = (char)value; 63 | } 64 | 65 | return bytes; 66 | } 67 | 68 | void getTrits(const char* bytes, int bytelength, char* const trits, 69 | int length) { 70 | int i; 71 | 72 | int offset = 0; 73 | for (i = 0; i < bytelength && offset < length; i++) { 74 | memcpy( 75 | trits + offset, 76 | BYTE_TO_TRITS_MAPPINGS 77 | [bytes[i] < 0 78 | ? (bytes[i] + 79 | HASH_LENGTH /* length of what? first? BYTE_TO_TRITS_MAPPINGS.length */) 80 | : bytes[i]], 81 | sizeof(char) * (length - offset < NUMBER_OF_TRITS_IN_A_BYTE 82 | ? (length - offset) 83 | : NUMBER_OF_TRITS_IN_A_BYTE)); 84 | offset += NUMBER_OF_TRITS_IN_A_BYTE; 85 | } 86 | while (offset < length) { 87 | trits[offset++] = 0; 88 | } 89 | } 90 | 91 | char* trits_from_trytes(const char* trytes, int length) { 92 | int i; 93 | char* trits = malloc(length * NUMBER_OF_TRITS_IN_A_TRYTE * sizeof(char)); 94 | for (i = 0; i < length; i++) { 95 | memcpy(trits + i * NUMBER_OF_TRITS_IN_A_TRYTE, 96 | TRYTE_TO_TRITS_MAPPINGS[strchr(TRYTE_ALPHABET, trytes[i]) - 97 | TRYTE_ALPHABET], 98 | sizeof(char) * NUMBER_OF_TRITS_IN_A_TRYTE); 99 | } 100 | 101 | return trits; 102 | } 103 | 104 | void copyTrits(char const value, char* const destination, const int offset, 105 | const int size) { 106 | int i; 107 | 108 | char absoluteValue = value < 0 ? -value : value; 109 | for (i = 0; i < size; i++) { 110 | 111 | int remainder = (int)(absoluteValue % RADIX); 112 | absoluteValue /= RADIX; 113 | if (remainder > MAX_TRIT_VALUE) { 114 | 115 | remainder = MIN_TRIT_VALUE; 116 | absoluteValue++; 117 | } 118 | destination[offset + i] = remainder; 119 | } 120 | 121 | if (value < 0) { 122 | for (i = 0; i < size; i++) { 123 | destination[offset + i] = -destination[offset + i]; 124 | } 125 | } 126 | } 127 | 128 | char* trytes_from_trits(char* const trits, const int offset, const int size) { 129 | int i; 130 | const int length = 131 | (size + NUMBER_OF_TRITS_IN_A_TRYTE - 1) / NUMBER_OF_TRITS_IN_A_TRYTE; 132 | char* trytes = malloc(sizeof(char) * (length + 1)); 133 | trytes[length] = '\0'; 134 | 135 | for (i = 0; i < length; i++) { 136 | char j = trits[offset + i * 3] + trits[offset + i * 3 + 1] * 3 + 137 | trits[offset + i * 3 + 2] * 9; 138 | if (j < 0) { 139 | j += 27; 140 | } 141 | trytes[i] = TRYTE_ALPHABET[(size_t)j]; 142 | } 143 | return trytes; 144 | } 145 | 146 | char tryteValue(char* const trits, const int offset) { 147 | return trits[offset] + trits[offset + 1] * 3 + trits[offset + 2] * 9; 148 | } 149 | 150 | static void increment(char* trits, int size) { 151 | int i; 152 | for (i = 0; i < size; i++) { 153 | if (++trits[i] > MAX_TRIT_VALUE) { 154 | trits[i] = MIN_TRIT_VALUE; 155 | } else { 156 | break; 157 | } 158 | } 159 | } 160 | 161 | void init_converter (void) __attribute__ ((constructor)); 162 | void init_converter() { 163 | int i; 164 | char trits[NUMBER_OF_TRITS_IN_A_BYTE]; 165 | memset(trits, 0, NUMBER_OF_TRITS_IN_A_BYTE * sizeof(char)); 166 | for (i = 0; i < HASH_LENGTH; i++) { 167 | memcpy(&(BYTE_TO_TRITS_MAPPINGS[i]), trits, 168 | NUMBER_OF_TRITS_IN_A_BYTE * sizeof(char)); 169 | increment(trits, NUMBER_OF_TRITS_IN_A_BYTE); 170 | } 171 | for (i = 0; i < TRYTE_SPACE; i++) { 172 | memcpy(&(TRYTE_TO_TRITS_MAPPINGS[i]), trits, 173 | NUMBER_OF_TRITS_IN_A_TRYTE * sizeof(char)); 174 | increment(trits, NUMBER_OF_TRITS_IN_A_TRYTE); 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /src/lib/util/converter.h: -------------------------------------------------------------------------------- 1 | #ifndef _CONVERTER_H_ 2 | #define _CONVERTER_H_ 3 | 4 | #include "../hash.h" 5 | 6 | char long_value(char* const trits, const int offset, const int size); 7 | char charValue(char* const trits, const int offset, const int size); 8 | char* bytes_from_trits(char* const trits, const int offset, const int size); 9 | void getTrits(const char* bytes, int bytelength, char* const trits, 10 | int length); 11 | int indexOf(char* values, char find); 12 | char* trits_from_trytes(const char* trytes, int length); 13 | void copyTrits(char const value, char* const destination, const int offset, 14 | const int size); 15 | char* trytes_from_trits(char* const trits, const int offset, const int size); 16 | char tryteValue(char* const trits, const int offset); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | enable_testing () 2 | 3 | FILE(GLOB THE_TESTS "test*.c") 4 | FOREACH(TEST_TO_RUN ${THE_TESTS}) 5 | get_filename_component(TEST_NAME ${TEST_TO_RUN} NAME) 6 | string(REGEX REPLACE "\\.[^.]*$" "" TEST_WITHOUT_EXT ${TEST_NAME}) 7 | 8 | add_executable (${TEST_WITHOUT_EXT} ${TEST_TO_RUN} ./cunit_include.c ${SOURCES}) 9 | 10 | if (WIN32) 11 | set_target_properties (${TEST_WITHOUT_EXT} PROPERTIES LINK_FLAGS -Wl,-lbcunit) 12 | else() 13 | set_target_properties (${TEST_WITHOUT_EXT} PROPERTIES LINK_FLAGS -Wl,-lbcunit,-lpthread) 14 | endif() 15 | target_link_libraries(${TEST_WITHOUT_EXT} ${OPENCL_LIBRARIES} ${CLCONTEXT_LIBRARY}) 16 | 17 | add_test (${TEST_WITHOUT_EXT} ${EXECUTABLE_OUTPUT_PATH}/${TEST_WITHOUT_EXT}) 18 | 19 | LIST(APPEND COMPILED_RESOURCES ${OUTPUT_FILE}) 20 | ENDFOREACH() 21 | -------------------------------------------------------------------------------- /test/cunit_include.c: -------------------------------------------------------------------------------- 1 | #include "cunit_include.h" 2 | #ifdef __APPLE__ 3 | #include "CUnit/Basic.h" 4 | #else 5 | #include "BCUnit/Basic.h" 6 | #endif 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | int run_tests(CU_SuiteInfo* suites) { 13 | if (CUE_SUCCESS != CU_initialize_registry()) 14 | return CU_get_error(); 15 | 16 | CU_ErrorCode error; 17 | 18 | error = CU_register_suites(suites); 19 | if (CUE_SUCCESS != error) { 20 | CU_cleanup_registry(); 21 | fprintf(stderr, "suite registration failed - %s\n", CU_get_error_msg()); 22 | exit(EXIT_FAILURE); 23 | } 24 | CU_basic_set_mode(CU_BRM_VERBOSE); 25 | CU_basic_run_tests(); 26 | CU_cleanup_registry(); 27 | 28 | // CU_automated_run_tests(); 29 | // CU_list_tests_to_file(); 30 | return CU_get_error(); 31 | } 32 | -------------------------------------------------------------------------------- /test/cunit_include.h: -------------------------------------------------------------------------------- 1 | #ifndef _CUNIT_INCLUDE_H_ 2 | #define _CUNIT_INCLUDE_H_ 3 | 4 | #ifdef __APPLE__ 5 | #include "CUnit/CUnit.h" 6 | #else 7 | #include "BCUnit/BCUnit.h" 8 | #endif 9 | 10 | int run_tests(CU_SuiteInfo* suites); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /test/random_trits.c: -------------------------------------------------------------------------------- 1 | 2 | #include "random_trits.h" 3 | #include 4 | #include 5 | 6 | void get_random_trits(long* RandomTrits, int length) { 7 | int i = 0; 8 | srand(time(NULL)); 9 | while (i < length) { 10 | RandomTrits[i] = rand() % 3 - 1; 11 | i++; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/random_trits.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef RANDOM_TRITS 3 | #define RANDOM_TRITS 4 | 5 | void getRandomTrits(long* RandomTrits, int length); 6 | #endif 7 | -------------------------------------------------------------------------------- /test/test_curl.c: -------------------------------------------------------------------------------- 1 | #include "../src/lib/ccurl.h" 2 | #include "../src/lib/curl.h" 3 | #include "../src/lib/hash.h" 4 | #include "../src/lib/util/converter.h" 5 | #include "cunit_include.h" 6 | #include "random_trits.h" 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | static const size_t length = STATE_LENGTH; 13 | static const int length_2 = length; 14 | static const char trits_2[] = (const char[]){ 15 | 0, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, 0, -1, -1, 16 | -1, 0, -1, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, -1, -1, -1, 0, -1, -1, 17 | 0, -1, 0, -1, -1, -1, 0, -1, 0, 0, -1, -1, -1, -1, 0, 0, -1, 0, -1, 18 | 0, 0, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, -1, -1, -1, 0, -1, 0, 0, 19 | -1, -1, 0, 0, 0, -1, 0, -1, -1, -1, 0, 0, -1, -1, 0, 0, 0, -1, 0, 20 | 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, 21 | 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, 0, 0, -1, -1, 0, 0, -1, 0, 0, 22 | 0, 0, 0, 0, -1, 0, 0, -1, -1, -1, 0, 0, -1, 0, 0, -1, 0, -1, -1, 23 | 0, 0, -1, -1, -1, -1, 0, -1, -1, 0, -1, 0, -1, -1, 0, -1, 0, 0, 0, 24 | 0, -1, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, -1, 0, 0, -1, -1, 0, 25 | 0, -1, -1, -1, -1, 0, -1, -1, -1, -1, 0, -1, 0, 0, -1, -1, 0, 0, 0, 26 | 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, -1, -1, -1, 0, 0, 27 | -1, -1, -1, 0, -1, 0, 0, 0, -1, -1, -1, -1, -1, 0, 0, -1, 0, 0, -1, 28 | 0, 0, 0, -1, -1, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, -1, -1, -1, 0, 29 | -1, -1, 0, 0, -1, 0, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, -1, -1, 30 | 0, 0, -1, 0, 0, -1, -1, -1, -1, 0, 0, -1, -1, 0, 0, 0, -1, -1, -1, 31 | 0, -1, -1, 0, -1, -1, -1, -1, 0, -1, 0, -1, -1, 0, 0, 0, 0, -1, -1, 32 | 0, 0, 0, -1, 0, 0, 0, -1, -1, -1, 0, 0, -1, 0, -1, -1, -1, -1, 0, 33 | -1, -1, 0, -1, -1, 0, -1, -1, -1, 0, -1, 0, 0, -1, -1, 0, -1, 0, 0, 34 | 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, -1, 0, 0, -1, 0, 35 | -1, -1, 0, 0, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 36 | 0, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, -1, 0, 0, 0, -1, 0, -1, 37 | 0, -1, -1, 0, -1, 0, -1, 0, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, -1, 38 | 0, 0, -1, 0, 0, 0, -1, -1, 0, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 39 | -1, -1, -1, 0, 0, -1, -1, 0, -1, 0, -1, 0, -1, -1, -1, -1, -1, 0, 0, 40 | 0, -1, 0, -1, 0, 0, -1, -1, 0, -1, 0, -1, -1, -1, 0, -1, 0, 0, 0, 41 | 0, -1, -1, -1, 0, -1, -1, -1, 0, -1, -1, -1, 0, 0, -1, 0, 0, -1, 0, 42 | 0, 0, -1, -1, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 43 | -1, 0, -1, -1, 0, -1, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1, -1, 44 | -1, -1, 0, 0, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, 0, 0, -1, -1, 0, 45 | -1, -1, -1, 0, 0, -1, 0, 0, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, 0, 46 | -1, -1, 0, 0, -1, -1, -1, -1, 0, 0, -1, 0, -1, 0, 0, 0, -1, -1, 0, 47 | -1, 0, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, -1, 48 | 0, -1, 0, -1, -1, 0, 0, -1, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 49 | -1, 0, 0, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, -1, 0, 0, -1, -1, 0, 50 | -1, 0, 0, 0, 0, 0, -1, -1, 0, -1, 0, 0, 0, -1, 0, -1, 0, 0, 0, 51 | -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, -1, 0, -1, -1, 0, -1, 0, -1, 0, 52 | 0, -1, -1, 0, 0, 0, 0, -1, 0, -1, -1, 0, 0, -1, -1, -1, -1, -1, 0, 53 | -1, -1, 0, -1, 0, -1, 0}; 54 | static const char expect_2[] = (const char[]){ 55 | 0, 1, 1, 0, -1, 0, 1, 0, 1, -1, -1, 0, 0, 1, 0, -1, 1, 1, -1, 56 | 1, -1, 1, 1, 1, 0, -1, 0, 1, -1, -1, 1, 0, 0, -1, -1, -1, 1, 0, 57 | -1, 1, 1, 0, 0, -1, 1, -1, 1, 0, 0, -1, 1, 0, 1, 1, 1, 1, -1, 58 | 1, -1, 0, 1, 0, 1, -1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, -1, -1, 59 | 1, -1, 1, 0, 1, -1, -1, -1, 0, -1, -1, 1, 1, 0, 0, 0, -1, 1, 0, 60 | 0, 0, -1, 0, 0, -1, -1, 1, 0, 1, -1, 0, 0, 1, 1, 0, -1, 0, 0, 61 | -1, -1, 1, 0, -1, -1, -1, 0, 1, -1, 0, -1, 0, 1, -1, -1, 0, -1, 0, 62 | 0, 0, 0, 0, -1, -1, -1, -1, 0, 1, -1, -1, 1, 0, -1, 0, -1, -1, 1, 63 | 1, 0, 0, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 0, -1, 1, 0, -1, 64 | 0, 1, 1, 0, -1, -1, -1, -1, 1, -1, 1, -1, 0, 1, 1, 0, 1, 0, 0, 65 | 0, 1, 1, -1, 1, -1, 1, 1, 0, 0, 1, 1, -1, 0, -1, 1, -1, -1, 0, 66 | -1, -1, 0, 1, -1, 0, -1, 1, -1, -1, 0, 0, -1, 1, 0, 0, 1, 0, -1, 67 | 0, 1, 1, 1, -1, 1, 0, 1, 1, 1, 1, 0, 1, -1, -1, -1, 1, 0, 1, 68 | -1, 1, 1, 1, 1, 1, 0, 0, 1, 0, -1, 1, 0, 1, 1, 1, 0, 0, -1, 69 | 0, -1, -1, -1, 1, 1, 0, 0, 0, 0, 0, -1, 1, 1, 1, 1, 1, -1, -1, 70 | -1, 0, -1, 0, -1, 1, 0, 1, 1, -1, 1, 0, 0, -1, -1, 0, -1, -1, 1, 71 | -1, 1, -1, -1, -1, 1, -1, 0, 0, 1, 0, 0, 1, -1, -1, 0, -1, -1, 0, 72 | -1, 1, 0, 0, -1, -1, -1, 0, 0, 1, 0, 1, 0, 1, -1, -1, 1, 0, 1, 73 | -1, 1, -1, -1, -1, 0, 0, 0, 0, -1, 1, 1, 1, 0, 1, -1, 0, -1, -1, 74 | 0, -1, 0, 0, 0, 0, -1, 1, -1, -1, 1, 0, 1, -1, -1, 0, -1, 1, 1, 75 | -1, -1, 1, -1, 0, 1, 1, 1, 0, -1, -1, -1, -1, 1, 0, 0, 0, 1, 1, 76 | 1, -1, 0, 0, -1, 0, 1, 0, -1, 0, 0, -1, 1, 0, 1, -1, 1, 0, 0, 77 | 0, 1, 1, 1, 0, -1, 1, 1, -1, 0, 0, -1, -1, 0, -1, -1, 0, -1, 0, 78 | -1, 1, 1, 0, 1, 0, 1, -1, -1, 0, -1, 1, -1, -1, 0, -1, 1, 1, 0, 79 | 1, 0, 0, -1, 0, 0, 1, -1, 0, -1, -1, -1, 1, 0, -1, -1, 1, 0, 0, 80 | 0, 1, -1, 0, 1, -1, 1, -1, 0, -1, 0, -1, 0, -1, 0, 0, 0, 0, 0, 81 | 0, -1, 0, 0, 1, 0, -1, -1, 0, -1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 82 | 0, 0, -1, -1, 0, 1, 1, -1, -1, -1, 1, 0, 1, -1, -1, -1, 1, 1, 1, 83 | 0, -1, 0, 0, 0, 0, 0, 0, 1, 1, -1, -1, 0, 0, 1, 0, 1, 1, 0, 84 | -1, 1, 0, -1, 0, 1, 0, 1, 1, 1, -1, 1, 0, 0, 0, 1, 0, 1, 0, 85 | -1, 1, 0, 1, 1, -1, -1, -1, 0, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 86 | 0, 0, -1, 0, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 87 | 0, 1, 1, 0, -1, -1, -1, 0, 0, 0, -1, 0, 0, 0, 1, 0, -1, 0, 1, 88 | 0, -1, -1, 0, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 0, 0, 1, 89 | -1, 0, -1, 1, 0, -1, 1, 0, 1, -1, 1, 1, -1, -1, -1, 0, 1, 1, 0, 90 | 1, 1, -1, 0, -1, 0, 0, -1, 1, 1, -1, 0, 1, 1, 1, 1, 1, 0, -1, 91 | 1, 0, 0, -1, -1, -1, 1, 0, -1, -1, 1, 0, -1, 1, -1, 1, -1, 0, 1, 92 | 1, -1, 1, 0, 0, 1, -1, -1, -1, 1, 1, 1, 1, -1, 0, 0, -1, 0, 1, 93 | -1, 0, 1, 1, -1, -1, -1}; 94 | 95 | static const char trits_in_2[] = (const char[]){ 96 | 0, 0, -1, -1, 0, 0, -1, 0, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, -1, 97 | 0, -1, -1, -1, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, -1, 0, 0, 0, 98 | -1, 0, -1, 0, -1, -1, 0, 0, -1, -1, -1, 0, 0, 0, -1, 0, -1, -1, -1, 99 | 0, 0, 0, 0, -1, 0, -1, -1, 0, -1, 0, 0, 0, -1, 0, 0, -1, -1, -1, 100 | 0, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1, 0, -1, -1, -1, -1, -1, 101 | 0, -1, -1, -1, 0, -1, -1, 0, -1, -1, -1, 0, -1, 0, 0, -1, -1, 0, -1, 102 | 0, 0, 0, 0, 0, -1, 0, 0, -1, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, 103 | -1, -1, 0, 0, -1, -1, -1, -1, 0, 0, 0, -1, 0, -1, -1, -1, -1, -1, 0, 104 | 0, 0, -1, 0, -1, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, -1, -1, -1, -1, 105 | 0, -1, -1, -1, 0, 0, 0, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, 0, 106 | 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, -1, 0, -1, -1, 0, 0, -1, 0, 0, 107 | 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, 0, 0, 0, 0, -1, 0, 0, 108 | 0, 0, -1, 0, -1, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, 0, 0, 0, 0, 109 | 0, 0, -1, 0, 0, -1, -1, -1, 0, 0, 0, -1, 0, -1, 0, -1, 0, -1, 0, 110 | 0, 0, -1, -1, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, -1, -1, -1, -1, 0, 111 | -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, 0, 112 | 0, -1, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, -1, -1, 0, -1, 0, 0, 113 | -1, 0, 0, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 114 | -1, 0, -1, -1, 0, -1, 0, 0, 0, 0, 0, 0, -1, -1, -1, 0, -1, -1, -1, 115 | -1, 0, 0, 0, -1, -1, 0, 0, -1, -1, -1, 0, 0, -1, 0, 0, 0, 0, -1, 116 | 0, -1, -1, 0, -1, -1, 0, 0, -1, -1, 0, -1, 0, 0, 0, -1, -1, 0, -1, 117 | 0, 0, 0, 0, 0, -1, 0, 0, -1, -1, -1, 0, -1, -1, 0, 0, -1, 0, 0, 118 | -1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, -1, -1, -1, -1, 0, -1, 119 | -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, 0, 120 | -1, -1, -1, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 121 | -1, 0, 0, 0, -1, -1, 0, -1, 0, 0, -1, 0, -1, 0, -1, 0, 0, -1, 0, 122 | 0, -1, -1, 0, 0, 0, 0, -1, -1, 0, 0, 0, -1, -1, 0, 0, -1, 0, -1, 123 | 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, -1, 124 | 0, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, 0, -1, -1, 0, -1, -1, 0, 125 | -1, -1, 0, -1, -1, -1, -1, 0, 0, 0, -1, 0, -1, -1, -1, -1, 0, -1, 0, 126 | 0, -1, 0, -1, 0, -1, -1, -1, 0, 0, 0, -1, 0, 0, 0, 0, -1, -1, 0, 127 | -1, -1, 0, 0, 0, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 128 | 0, 0, 0, 0, -1, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 129 | -1, -1, -1, -1, -1, 0, 0, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, -1, 0, 130 | -1, 0, 0, -1, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 131 | -1, 0, -1, -1, 0, 0, 0, 0, 0, 0, -1, -1, 0, -1, 0, 0, -1, 0, 0, 132 | -1, -1, -1, -1, 0, -1, -1, -1, 0, 0, 0, -1, -1, 0, -1, 0, 0, -1, 0, 133 | -1, 0, 0, 0, -1, 0, -1, 0, 0, 0, -1, -1, 0, -1, 0, 0, -1, 0, 0, 134 | -1, 0, 0, -1, -1, -1, 0}; 135 | static const char trits_out_2[] = (const char[]){ 136 | 1, 1, 1, 1, 1, 0, 0, 0, 1, -1, 0, -1, 0, 0, 0, 0, 1, 0, 1, 137 | 0, 1, -1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, -1, 1, 0, -1, -1, 1, 138 | 1, 0, 1, 1, 1, 1, 0, -1, 0, 1, 0, -1, 0, 0, 1, 1, 0, 0, 0, 139 | 0, -1, 0, 0, 1, 0, -1, 1, 0, 1, 1, 1, -1, 1, 1, 1, 1, 1, 0, 140 | 1, 1, -1, 1, 1, 1, -1, 0, 1, 0, 1, -1, -1, 0, 1, 1, 0, 1, 0, 141 | -1, 1, 1, 1, 0, 1, 0, 1, 1, -1, -1, -1, -1, -1, 1, -1, 0, 1, 1, 142 | 0, 1, 0, -1, -1, -1, -1, 0, 0, 1, 1, 0, 0, 1, -1, 0, 1, 1, 1, 143 | -1, 0, -1, 0, -1, 1, 1, 1, 0, 1, 1, -1, 0, -1, -1, -1, 0, 0, 1, 144 | -1, -1, 0, 0, -1, 1, -1, 1, 0, 0, -1, 1, 1, 1, -1, -1, 1, -1, 0, 145 | 0, -1, 1, -1, -1, 0, 0, 1, 0, 0, 1, 0, -1, -1, -1, 1, 1, -1, 0, 146 | -1, 1, -1, 0, 0, 0, 1, -1, 1, 0, 1, 1, 1, -1, -1, 0, 1, -1, 1, 147 | 0, 0, 0, 1, -1, 0, -1, 1, 1, 0, 0, -1, -1, 1, -1, 0, -1, 0, 1, 148 | 0, 1, 0, -1, 0, 1, -1, 0, 1, 1, 0, -1, -1, -1, -1, 1, 0, -1, 1, 149 | 0, -1, 0, 0, 0, -1, 0, -1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 150 | -1, 1, 1, -1, 0, 0, -1, 1, -1, -1, -1, -1, -1, -1, 0, 0, -1, -1, 0, 151 | -1, 1, 0, 1, 1, 1, -1, 0, 1, 0, 1, 1, -1, -1, -1, 0, 1, 1, -1, 152 | 1, 0, 0, 0, 1, 1, 0, -1, 0, 1, 1, 1, 0, 0, 0, 1, -1, 1, 0, 153 | 0, 0, 0, -1, 1, 0, 0, 1, 0, 0, 0, -1, -1, 1, 0, 1, 0, 0, 1, 154 | -1, -1, 0, 0, 0, 1, 0, -1, 0, -1, 1, -1, -1, 0, 1, 1, 0, -1, 1, 155 | -1, -1, 1, 1, 0, -1, 0, 1, -1, 1, -1, 1, 1, 1, 0, 0, -1, 0, 0, 156 | 1, -1, 1, 0, -1, 0, 1, 1, 1, 0, 1, 0, -1, 1, 1, -1, -1, -1, 1, 157 | -1, -1, 1, 1, -1, 0, 1, -1, 0, -1, 1, 1, 1, 1, 0, 1, -1, 0, 0, 158 | 1, -1, 1, -1, 1, -1, -1, 0, -1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 159 | 1, 0, -1, -1, -1, 0, 0, -1, 1, -1, -1, 1, 1, 0, -1, 1, 0, 0, 1, 160 | -1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, -1, 0, -1, 1, 1, 1, 161 | 1, 1, 1, 1, 0, -1, 0, 0, 0, -1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 162 | 1, 0, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 163 | -1, 0, -1, 0, 1, 1, 0, -1, 1, 1, 0, 1, 1, -1, 0, 0, 0, -1, 1, 164 | -1, 1, -1, 1, -1, 0, 1, -1, -1, -1, 0, 0, 1, -1, -1, -1, 0, 0, 1, 165 | 0, 1, 0, -1, 0, 0, 0, -1, 0, 0, 1, 1, 0, -1, 0, 1, 1, -1, 0, 166 | 0, 1, 0, 1, 1, -1, 1, -1, 1, 0, -1, 0, 0, -1, 1, 0, 1, -1, -1, 167 | 0, 1, 0, 1, 0, 0, -1, 1, -1, -1, 1, 0, -1, -1, 0, 1, 0, 0, 1, 168 | 1, 1, 0, 1, 1, 1, -1, 1, 1, -1, 0, -1, 1, -1, 1, 1, 1, 1, 1, 169 | -1, -1, 0, 1, 0, 1, -1, 1, 1, -1, -1, -1, 0, -1, 1, 1, 0, 0, 0, 170 | 0, 0, 1, 0, -1, -1, -1, 0, 0, 0, -1, -1, -1, -1, 1, -1, 0, -1, 0, 171 | 0, 0, 1, 1, 0, -1, 1, 1, -1, 0, 1, 0, 0, -1, 0, 0, 0, 1, 1, 172 | 0, 1, -1, 1, -1, 1, -1, 0, 1, 1, -1, -1, -1, -1, 1, 1, 0, 0, 1, 173 | 0, -1, 0, 0, 1, 0, 0, 0, 0, 1, 1, -1, 1, 0, 0, 0, 0, 1, 0, 174 | 0, 1, 0, 0, -1, 0, 1}; 175 | static const char trits_in_1[] = (const char[]){ 176 | -1, -1, 0, 0, -1, 0, -1, -1, -1, -1, -1, -1, 0, 0, -1, -1, 0, -1, 0, 177 | 0, 0, -1, -1, -1, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, -1, -1, 0, 178 | -1, -1, -1, 0, 0, 0, -1, -1, 0, -1, 0, -1, -1, 0, -1, 0, -1, -1, -1, 179 | 0, 0, 0, 0, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, 0, 0, 0, -1, 180 | 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, -1, 0, -1, -1, -1, -1, 0, -1, 0, 181 | 0, -1, -1, 0, -1, -1, -1, 0, -1, 0, 0, 0, -1, -1, -1, -1, -1, 0, 0, 182 | -1, -1, -1, -1, -1, 0, -1, -1, 0, 0, -1, -1, 0, 0, 0, 0, -1, -1, 0, 183 | -1, -1, -1, 0, -1, 0, 0, -1, 0, -1, -1, 0, 0, -1, -1, -1, -1, 0, 0, 184 | 0, -1, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, -1, 0, -1, -1, 0, -1, -1, 185 | -1, 0, 0, -1, -1, -1, -1, 0, -1, 0, 0, 0, -1, -1, -1, 0, -1, -1, -1, 186 | 0, 0, -1, 0, -1, 0, -1, 0, 0, -1, 0, -1, -1, 0, -1, 0, -1, -1, 0, 187 | -1, 0, 0, 0, -1, -1, -1, -1, -1, 0, 0, 0, -1, -1, -1, 0, 0, 0, 0, 188 | 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, -1, 0, -1, 0, 0, 0, 0, 0, 189 | 0, -1, -1, -1, 0, -1, 0, 0, -1, 0, -1, -1, 0, 0, -1, -1, -1, 0, 0, 190 | 0, 0, 0, 0, 0, -1, 0, 0, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, 0, 191 | -1, -1, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, -1, -1, -1, 0, -1, 0, 0, 192 | -1, 0, 0, 0, 0, -1, -1, 0, 0, -1, 0, -1, -1, 0, -1, -1, -1, -1, 0, 193 | -1, -1, 0, -1, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 194 | -1, 0, -1, -1, -1, -1, 0, -1, -1, 0, -1, -1, -1, -1, 0, -1, -1, -1, 0, 195 | 0, 0, -1, -1, 0, 0, 0, -1, -1, 0, 0, -1, 0, -1, -1, 0, -1, 0, 0, 196 | 0, -1, 0, 0, 0, 0, -1, 0, 0, -1, 0, -1, -1, -1, -1, 0, -1, -1, -1, 197 | 0, -1, 0, 0, 0, -1, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, -1, 198 | -1, -1, -1, 0, -1, 0, 0, -1, 0, -1, -1, 0, -1, -1, -1, -1, 0, -1, 0, 199 | 0, -1, -1, -1, 0, 0, 0, -1, -1, 0, -1, 0, 0, -1, 0, 0, 0, 0, 0, 200 | 0, -1, -1, 0, -1, -1, -1, 0, -1, 0, 0, 0, -1, 0, 0, -1, 0, 0, 0, 201 | -1, -1, -1, 0, -1, 0, -1, -1, 0, 0, -1, -1, 0, 0, -1, 0, -1, -1, 0, 202 | -1, -1, 0, 0, -1, 0, -1, -1, -1, -1, 0, -1, 0, 0, -1, 0, 0, -1, -1, 203 | -1, -1, 0, 0, -1, 0, -1, 0, 0, -1, -1, 0, -1, 0, 0, 0, 0, 0, 0, 204 | -1, 0, -1, 0, -1, -1, 0, 0, 0, 0, -1, 0, 0, -1, -1, -1, -1, 0, 0, 205 | -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, 0, -1, -1, 0, 0, 206 | 0, 0, -1, 0, 0, -1, -1, -1, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, 0, 207 | -1, -1, 0, -1, 0, -1, 0, 0, -1, -1, 0, 0, 0, -1, -1, 0, -1, 0, 0, 208 | 0, 0, -1, -1, -1, 0, -1, -1, -1, -1, 0, 0, 0, 0, -1, -1, -1, 0, -1, 209 | -1, 0, 0, -1, 0, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210 | -1, -1, 0, 0, -1, -1, -1, 0, 0, -1, -1, 0, 0, -1, -1, 0, 0, -1, -1, 211 | -1, 0, -1, 0, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, -1, 0, -1, 0, -1, 212 | 0, -1, -1, -1, 0, -1, 0, 0, 0, 0, -1, -1, -1, -1, 0, 0, -1, 0, -1, 213 | 0, 0, 0, -1, -1, -1, 0, 0, 0, -1, -1, 0, 0, 0, 0, -1, -1, 0, 0, 214 | 0, 0, -1, 0, 0, 0, -1}; 215 | static const char trits_out_1[] = (const char[]){ 216 | 0, -1, 1, 1, 1, -1, -1, 0, 0, -1, 1, 0, 0, 1, -1, 1, 0, -1, 1, 217 | 0, 0, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 0, 1, -1, 0, 0, 218 | 0, -1, 0, 1, 1, 0, 1, -1, 0, -1, -1, 1, 0, 1, 0, -1, -1, 1, 1, 219 | -1, 1, 0, -1, -1, 1, 1, 0, 0, 0, 1, -1, 1, 0, 1, 0, -1, -1, -1, 220 | -1, 1, -1, 1, -1, -1, -1, 1, 0, 0, 0, -1, -1, 1, 1, 1, 0, 0, 0, 221 | 0, 0, -1, 1, 0, 1, 0, -1, -1, 0, 1, -1, 0, -1, 1, 1, -1, -1, 0, 222 | 0, 0, 1, 1, 0, -1, 1, 0, 0, -1, 1, -1, 1, 0, 1, -1, 1, 1, 1, 223 | 1, 0, 0, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 0, -1, -1, 0, 0, 224 | 1, 0, -1, 1, 1, 1, -1, 1, 0, 0, 0, 0, 1, 0, -1, 1, -1, -1, -1, 225 | -1, -1, -1, 1, -1, 0, -1, 1, 0, 1, 0, 0, -1, 1, 1, -1, 0, 1, 1, 226 | 0, 0, -1, 0, -1, 1, -1, -1, -1, -1, 0, -1, -1, 0, 1, 1, 1, -1, 1, 227 | -1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 228 | -1, 0, 1, 0, 1, -1, -1, 1, 0, -1, 1, 0, 0, 0, -1, 0, -1, -1, 0, 229 | 0, -1, 0, 0, 0, 0, 0, 0, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 230 | -1, 1, 1, 0, 0, 1, -1, 0, -1, -1, 0, -1, 1, 1, 1, 0, 1, -1, -1, 231 | 0, -1, -1, 1, 0, 0, -1, 0, 0, 1, 1, -1, 0, 1, -1, 0, 0, -1, -1, 232 | 0, 0, 1, -1, 1, -1, -1, -1, 0, 0, -1, -1, -1, 1, 1, -1, -1, -1, 1, 233 | 0, -1, -1, 1, -1, 1, 1, 1, 1, 0, 1, 1, 1, -1, 1, 1, -1, 1, 0, 234 | -1, -1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, -1, -1, -1, 0, -1, 235 | 1, 1, 0, 1, -1, -1, -1, -1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 236 | 0, -1, 1, 0, 0, 1, 1, 1, -1, 0, 0, 0, 0, 1, 1, -1, 1, -1, -1, 237 | -1, 0, 1, 0, 0, 0, 1, 1, -1, 0, 0, 0, 1, 1, 1, -1, 1, -1, 1, 238 | 1, -1, 0, 0, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 0, -1, 239 | 0, 0, 0, 0, 1, 1, 0, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, 1, 240 | 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, -1, -1, 1, 0, 0, 1, 1, -1, 1, 241 | 0, 1, 1, 0, -1, 1, -1, 0, 0, 0, 0, -1, 1, 1, 0, 0, 1, 1, 1, 242 | 0, -1, 1, 1, 0, 0, 1, 1, 0, -1, -1, 1, 0, 0, 1, 1, -1, -1, 0, 243 | -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 0, -1, 0, -1, 0, 0, 1, 0, 0, 244 | 1, -1, 0, 1, 1, -1, -1, 0, -1, -1, 1, 0, 1, -1, 0, -1, 0, 1, 0, 245 | -1, 1, 1, 1, -1, 0, 1, -1, -1, -1, 1, 1, 0, 0, -1, 0, -1, -1, -1, 246 | 1, 0, 1, 0, 1, 1, 0, -1, 0, 0, 1, -1, -1, 0, 1, 0, -1, -1, -1, 247 | 0, 1, 1, -1, -1, 1, -1, 0, 0, -1, 1, 1, 1, -1, 1, -1, 0, -1, 0, 248 | 1, -1, 1, -1, 0, 1, -1, -1, -1, 1, 0, -1, 0, 0, 1, 0, 0, 0, 1, 249 | -1, 1, 1, -1, -1, -1, 0, -1, 1, 1, -1, 1, 1, 0, 1, -1, 1, 0, 0, 250 | 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, -1, 0, 0, 0, -1, 0, -1, 0, -1, 251 | 0, 0, 0, 1, 1, 1, 0, 0, 1, -1, -1, -1, -1, 1, -1, 0, -1, -1, 1, 252 | 1, -1, -1, -1, -1, -1, 1, 0, 0, 0, 0, 1, 1, 0, 1, -1, -1, -1, -1, 253 | -1, 0, -1, -1, 1, 1, 0, 0, 0, 0, 1, 1, -1, 0, 1, 0, -1, 0, 0, 254 | 1, 0, 0, 0, 0, 1, -1}; 255 | 256 | // static const char trit_hash = 257 | // "BPFFJDLS9CSEZCUXPLDPLDASUL9PTJVFZEBNHRE9TWLUJKNCBYSMXWJYMBYFXRDJUZJDQRIXHRWBY9999"; 258 | 259 | #define nocl_pd_trans \ 260 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 261 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 262 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 263 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 264 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 265 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 266 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 267 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 268 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 269 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 270 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 271 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 272 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 273 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 274 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 275 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 276 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 277 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 278 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 279 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 280 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 281 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 282 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 283 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 284 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 285 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 286 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 287 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 288 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 289 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 290 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 291 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 292 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 293 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 294 | "99999999999999999999999999999999999999999999999999999999999999999999999999" \ 295 | "99T99999999999999999999999999999999999999999999999999999OLOB99999999999999" \ 296 | "999999999" 297 | #define nocl_pd_hash \ 298 | "TAQCQAEBHLLYKAZWMNSXUPWQICMFSKWPEGQBNM9AQMGLFZGME9REOZTQIJQRKYHDANIYSMFYPV" \ 299 | "ABX9999" 300 | /* 301 | #define trits_in 302 | "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999ZDWNRTMICEUJKUZIZGXKNUXGTFQTGNXHYHYYQYLWPPWKRWFVTIOBFGMVLKGCOGHF9LINGNLPHQBO9UHSE999999999999999999999999999999999999999999999999999999CAAUHVD99999999999999999999HRNCLJOVIU999QYHADTTFLUMTDSUAYKUUBWCWACGEPWZQUHQDWSGMFFKNHAIUUVQHPXOTHFFGLUUMYRMKPYHODCQSKTYJBNXYLMDXGTAIDMXNNXZPCJZD9PAXVITTAPLDDDAVZXHVY9QABYMTFGODIGFV9JZFW9999UNBHOV9VMEMRMBPJLEIJLUMXNFTSOMQ9JLNPAKOPIXALNXQHOMNRJPSRJOQYYWWXZJJX9FYOSKB999999TCKFGDZLRGMOMLDTQZOQ9DVUCNWGAXKOWCQDLLGMZAZKYYKIIQBT9XRFIKTMPPOAN9UJYKKBGNSWAZVHJ" 303 | #define hash_out 304 | "CAGIYKAKEMWFOLFPYUFHNWUP9FHQIXPGLDQ9NUTCXQG9YHVKZZSFACQ9HKSFJTCNADLBWSQJWKAGY9999" 305 | */ 306 | 307 | int init_suite(void) { 308 | init_converter(); 309 | return 0; 310 | } 311 | int clean_suite(void) { return 0; } 312 | 313 | void test_curl_absorb(void); 314 | 315 | void test_curl_absorb(void) { 316 | char my_trits_1[STATE_LENGTH]; 317 | 318 | Curl curl; 319 | init_curl(&curl); 320 | 321 | int length_1 = STATE_LENGTH; 322 | memcpy(my_trits_1, trits_in_2, length_1 * sizeof(char)); 323 | 324 | for (int i = 0; i < 3; i++) { 325 | absorb(&curl, my_trits_1, i * HASH_LENGTH, HASH_LENGTH); 326 | } 327 | squeeze(&curl, my_trits_1, 0, length_1); 328 | reset(&curl); 329 | CU_ASSERT(memcmp(my_trits_1, trits_in_2, STATE_LENGTH * sizeof(char)) != 0); 330 | CU_ASSERT(memcmp(my_trits_1, trits_out_2, STATE_LENGTH * sizeof(char)) == 331 | 0); 332 | 333 | length_1 = STATE_LENGTH; 334 | memcpy(my_trits_1, trits_in_1, length_1 * sizeof(char)); 335 | CU_ASSERT(memcmp(my_trits_1, trits_in_1, STATE_LENGTH * sizeof(char)) == 0); 336 | 337 | absorb(&curl, my_trits_1, HASH_LENGTH, HASH_LENGTH); 338 | length_1 = STATE_LENGTH; 339 | squeeze(&curl, my_trits_1, 0, length_1); 340 | 341 | CU_ASSERT(memcmp(my_trits_1, trits_out_1, length_1 * sizeof(char)) == 0); 342 | } 343 | 344 | void test_curl_reset() { 345 | 346 | char my_trits_2[length_2]; 347 | 348 | Curl curl; 349 | init_curl(&curl); 350 | 351 | memcpy(my_trits_2, trits_2, length_2 * sizeof(char)); 352 | 353 | absorb(&curl, my_trits_2, 0, length_2); 354 | squeeze(&curl, my_trits_2, 0, length_2); 355 | CU_ASSERT(memcmp(my_trits_2, expect_2, length_2 * sizeof(char)) == 0); 356 | 357 | reset(&curl); 358 | memcpy(my_trits_2, trits_2, length_2 * sizeof(char)); 359 | 360 | absorb(&curl, my_trits_2, 0, length_2); 361 | squeeze(&curl, my_trits_2, 0, length_2); 362 | CU_ASSERT(memcmp(my_trits_2, expect_2, length_2 * sizeof(char)) == 0); 363 | } 364 | 365 | void test_curl_noreset_fail() { 366 | char my_trits_2[length_2]; 367 | 368 | Curl curl; 369 | init_curl(&curl); 370 | memcpy(my_trits_2, trits_2, length_2 * sizeof(char)); 371 | memcpy(my_trits_2, trits_2, length_2 * sizeof(char)); 372 | 373 | absorb(&curl, my_trits_2, 0, length_2); 374 | squeeze(&curl, my_trits_2, 0, length_2); 375 | CU_ASSERT(memcmp(my_trits_2, expect_2, length_2 * sizeof(char)) == 0); 376 | 377 | int length = HASH_LENGTH; 378 | absorb(&curl, my_trits_2, 0, length); 379 | squeeze(&curl, my_trits_2, 0, length); 380 | CU_ASSERT_FALSE(memcmp(my_trits_2, expect_2, HASH_LENGTH * sizeof(char)) == 381 | 0); 382 | } 383 | 384 | void test_curl_hash_works() { 385 | Curl curl; 386 | init_curl(&curl); 387 | 388 | char* mytrits = trits_from_trytes(nocl_pd_trans, TRANSACTION_LENGTH / 3); 389 | 390 | char myhash[HASH_LENGTH]; 391 | 392 | absorb(&curl, mytrits, 0, TRANSACTION_LENGTH); 393 | squeeze(&curl, myhash, 0, HASH_LENGTH); 394 | char* hashtrytes = trytes_from_trits(myhash, 0, HASH_LENGTH); 395 | 396 | CU_ASSERT(strcmp(hashtrytes, nocl_pd_hash) == 0); 397 | free(hashtrytes); 398 | free(mytrits); 399 | } 400 | 401 | void test_export_hash_trytes(void) { 402 | CU_ASSERT(strcmp(ccurl_digest_transaction(nocl_pd_trans), nocl_pd_hash) == 0); 403 | } 404 | 405 | void test_curl_benchmark() { 406 | float start, end; 407 | int count = 1000; 408 | Curl curl; 409 | init_curl(&curl); 410 | char* mytrits = trits_from_trytes(nocl_pd_trans, TRANSACTION_LENGTH / 3); 411 | char myhash[HASH_LENGTH]; 412 | 413 | start = (float)clock()/CLOCKS_PER_SEC; 414 | for(int i = 0; i < count; i++) { 415 | absorb(&curl, mytrits, 0, TRANSACTION_LENGTH); 416 | squeeze(&curl, myhash, 0, HASH_LENGTH); 417 | reset(&curl); 418 | } 419 | end = (float)clock()/CLOCKS_PER_SEC; 420 | fprintf (stderr, "\nTime elapsed %f \n", (end-start)/count); 421 | } 422 | 423 | static CU_TestInfo tests[] = { 424 | {"Curl Absorb Test", test_curl_absorb}, 425 | {"Curl Reset Test", test_curl_reset}, 426 | {"Curl NoReset Fail Test", test_curl_noreset_fail}, 427 | {"Curl Hash Fail Test", test_curl_hash_works}, 428 | {"Curl export digest test", test_export_hash_trytes}, 429 | {"Curl benchmark", test_curl_benchmark}, 430 | CU_TEST_INFO_NULL, 431 | }; 432 | 433 | static CU_SuiteInfo suites[] = { 434 | {"suitename1", init_suite, clean_suite, NULL, NULL, tests}, 435 | CU_SUITE_INFO_NULL, 436 | }; 437 | 438 | int main() { return run_tests(suites); } 439 | -------------------------------------------------------------------------------- /test/test_pearcldiver.c: -------------------------------------------------------------------------------- 1 | #include "../src/lib/ccurl.h" 2 | #include "../src/lib/curl.h" 3 | #include "../src/lib/pearcldiver.h" 4 | #include "../src/lib/pearl_diver.h" 5 | #include "../src/lib/util/converter.h" 6 | 7 | #include "cunit_include.h" 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #define SIZE_IN_BYTES 49 16 | // static const char *tryte_nines = 17 | // "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"; 18 | static const char* real_transaction = 19 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 20 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 21 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 22 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 23 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 24 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 25 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 26 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 27 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 28 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 29 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 30 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 31 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 32 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 33 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 34 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 35 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 36 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 37 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 38 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 39 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 40 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 41 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 42 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 43 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 44 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 45 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 46 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 47 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 48 | "99999999999999999999999999999999999999999ZDWNRTMICEUJKUZIZGXKNUXGTFQTGNXHY" 49 | "HYYQYLWPPWKRWFVTIOBFGMVLKGCOGHF9LINGNLPHQBO9UHSE99999999999999999999999999" 50 | "9999999999999999999999999999CAAUHVD99999999999999999999HRNCLJOVIU999QYHADT" 51 | "TFLUMTDSUAYKUUBWCWACGEPWZQUHQDWSGMFFKNHAIUUVQHPXOTHFFGLUUMYRMK999999999999" 52 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 53 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 54 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 55 | "999999999"; 56 | // static const char *real_trans_w_hash = 57 | // "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999ZDWNRTMICEUJKUZIZGXKNUXGTFQTGNXHYHYYQYLWPPWKRWFVTIOBFGMVLKGCOGHF9LINGNLPHQBO9UHSE999999999999999999999999999999999999999999999999999999CAAUHVD99999999999999999999HRNCLJOVIU999QYHADTTFLUMTDSUAYKUUBWCWACGEPWZQUHQDWSGMFFKNHAIUUVQHPXOTHFFGLUUMYRMKPYHODCQSKTYJBNXYLMDXGTAIDMXNNXZPCJZD9PAXVITTAPLDDDAVZXHVY9QABYMTFGODIGFV9JZFW9999UNBHOV9VMEMRMBPJLEIJLUMXNFTSOMQ9JLNPAKOPIXALNXQHOMNRJPSRJOQYYWWXZJJX9FYOSKB999999XBKFGDZLRGMOMLDTQZOQ9DVUCNWCAXKOWCQDLLGMZAZKYYKIIQBT9X9RRMTMPPOAN9UJYKKBGNSWAZVHJ"; 58 | 59 | static int init_suite(void) { 60 | init_converter(); 61 | return 0; 62 | } 63 | static int clean_suite(void) { return 0; } 64 | static void init_cl_test(void) {} 65 | static void teardown_cl_test(void) {} 66 | 67 | bool test_last_n_nines(char* hash, int length, int numNines) { 68 | int i; 69 | for (i = 1; i <= numNines; i++) { 70 | if (hash[length - i] != '9') 71 | return false; 72 | } 73 | return true; 74 | } 75 | 76 | static void test_search(void) { 77 | PearCLDiver pdcl; 78 | Curl curl; 79 | clock_t start, diff; 80 | int nonce_size = 13; 81 | char *digest, *trans; 82 | 83 | char *mytrits, hash_trits[HASH_LENGTH]; 84 | 85 | if (init_pearcl(&pdcl) != 0) { 86 | CU_FAIL("E: Could not initialize opencl\n"); 87 | return; 88 | } 89 | init_curl(&curl); 90 | 91 | mytrits = trits_from_trytes(real_transaction, TRYTE_LENGTH); 92 | 93 | // puts(trytes_from_trits(mytrits+TRANSACTION_LENGTH-HASH_LENGTH, 0, 94 | // HASH_LENGTH)); 95 | 96 | while (nonce_size < 19) { 97 | fprintf(stderr, "Testing mwm of %d: ", nonce_size); 98 | start = clock(); 99 | pearcl_search(&pdcl, mytrits, TRANSACTION_LENGTH, nonce_size, -1); 100 | diff = clock() - start; 101 | 102 | // printf("I took this many seconds: %ld", diff / CLOCKS_PER_SEC); 103 | trans = trytes_from_trits(mytrits, 0, TRANSACTION_LENGTH); 104 | // hash = trytes_from_trits(mytrits + TRANSACTION_LENGTH - HASH_LENGTH, 0, 105 | // HASH_LENGTH); 106 | 107 | absorb(&curl, mytrits, 0, TRANSACTION_LENGTH); 108 | squeeze(&curl, hash_trits, 0, HASH_LENGTH); 109 | reset(&curl); 110 | digest = trytes_from_trits(hash_trits, 0, HASH_LENGTH); 111 | 112 | // puts(trans); 113 | puts(digest); 114 | CU_ASSERT_FATAL(test_last_n_nines(digest, HASH_LENGTH / 3, nonce_size / 3)); 115 | nonce_size++; 116 | } 117 | free(mytrits); 118 | free(digest); 119 | } 120 | 121 | static CU_TestInfo tests[] = { 122 | {"Test Search ", test_search}, CU_TEST_INFO_NULL, 123 | }; 124 | 125 | static CU_SuiteInfo suites[] = { 126 | {"CLContext Test Suite", init_suite, clean_suite, init_cl_test, 127 | teardown_cl_test, tests}, 128 | CU_SUITE_INFO_NULL, 129 | }; 130 | 131 | int main() { return run_tests(suites); } 132 | -------------------------------------------------------------------------------- /test/test_pearldiver.c: -------------------------------------------------------------------------------- 1 | //#include "acunit/i.h" 2 | #include "../src/lib/ccurl.h" 3 | #include "../src/lib/curl.h" 4 | #include "../src/lib/hash.h" 5 | #include "../src/lib/pearl_diver.h" 6 | #include "../src/lib/util/converter.h" 7 | 8 | #include "cunit_include.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | // static const char *tryte_nines = 16 | // "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"; 17 | static const char* real_transaction = 18 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 19 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 20 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 21 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 22 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 23 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 24 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 25 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 26 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 27 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 28 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 29 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 30 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 31 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 32 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 33 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 34 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 35 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 36 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 37 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 38 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 39 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 40 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 41 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 42 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 43 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 44 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 45 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 46 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 47 | "99999999999999999999999999999999999999999ZDWNRTMICEUJKUZIZGXKNUXGTFQTGNXHY" 48 | "HYYQYLWPPWKRWFVTIOBFGMVLKGCOGHF9LINGNLPHQBO9UHSE99999999999999999999999999" 49 | "9999999999999999999999999999CAAUHVD99999999999999999999HRNCLJOVIU999QYHADT" 50 | "TFLUMTDSUAYKUUBWCWACGEPWZQUHQDWSGMFFKNHAIUUVQHPXOTHFFGLUUMYRMK999999999999" 51 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 52 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 53 | "99999999999999999999999999999999999999999999999999999999999999999999999999" 54 | "999999999"; 55 | // static const char *real_trans_w_hash = 56 | // "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999ZDWNRTMICEUJKUZIZGXKNUXGTFQTGNXHYHYYQYLWPPWKRWFVTIOBFGMVLKGCOGHF9LINGNLPHQBO9UHSE999999999999999999999999999999999999999999999999999999CAAUHVD99999999999999999999HRNCLJOVIU999QYHADTTFLUMTDSUAYKUUBWCWACGEPWZQUHQDWSGMFFKNHAIUUVQHPXOTHFFGLUUMYRMKPYHODCQSKTYJBNXYLMDXGTAIDMXNNXZPCJZD9PAXVITTAPLDDDAVZXHVY9QABYMTFGODIGFV9JZFW9999UNBHOV9VMEMRMBPJLEIJLUMXNFTSOMQ9JLNPAKOPIXALNXQHOMNRJPSRJOQYYWWXZJJX9FYOSKB999999XBKFGDZLRGMOMLDTQZOQ9DVUCNWCAXKOWCQDLLGMZAZKYYKIIQBT9X9RRMTMPPOAN9UJYKKBGNSWAZVHJ"; 57 | 58 | void runtests(); 59 | void getRandomTrits(char* RandomTrits, int length); 60 | int init_suites(void) { 61 | init_converter(); 62 | return 0; 63 | } 64 | int clean_suites(void) { return 0; } 65 | 66 | /************** Test case functions ****************/ 67 | 68 | bool test_last_n_nines(char* hash, int length, int numNines) { 69 | int i; 70 | for (i = 1; i <= numNines; i++) { 71 | if (hash[length - i] != '9') 72 | return false; 73 | } 74 | return true; 75 | } 76 | 77 | void test_pearl_diver_search(void) { 78 | Curl curl; 79 | PearlDiver pearl_diver; 80 | int nonce_size = 13; 81 | clock_t start, diff; 82 | char *hash, *trans; 83 | char* mytrits; 84 | char hash_trits[HASH_LENGTH]; 85 | 86 | mytrits = trits_from_trytes(real_transaction, TRYTE_LENGTH); 87 | 88 | start = clock(); 89 | pd_search(&pearl_diver, mytrits, TRANSACTION_LENGTH, nonce_size, 8); 90 | diff = clock() - start; 91 | trans = trytes_from_trits(mytrits, 0, TRANSACTION_LENGTH); 92 | hash = trytes_from_trits(mytrits + TRANSACTION_LENGTH - HASH_LENGTH, 0, 93 | HASH_LENGTH); 94 | init_curl(&curl); 95 | absorb(&curl, mytrits, 0, TRANSACTION_LENGTH); 96 | squeeze(&curl, hash_trits, 0, HASH_LENGTH); 97 | 98 | printf("\nTime taken: %ldms\n", diff * 1000 / CLOCKS_PER_SEC); 99 | hash = trytes_from_trits(hash_trits, 0, HASH_LENGTH); 100 | CU_ASSERT(test_last_n_nines(hash, HASH_LENGTH / 3, nonce_size / 3)); 101 | free(mytrits); 102 | free(hash); 103 | free(trans); 104 | } 105 | 106 | void* dosearch(void* ctx) { 107 | PearlDiver* pearl_diver = (PearlDiver*)ctx; 108 | Curl curl; 109 | init_curl(&curl); 110 | char hash_trits[HASH_LENGTH]; 111 | 112 | int nonce_size = 13; 113 | char mytrits[TRANSACTION_LENGTH]; 114 | getRandomTrits(mytrits, TRANSACTION_LENGTH); 115 | 116 | pd_search(pearl_diver, mytrits, TRANSACTION_LENGTH, nonce_size, 1); 117 | 118 | absorb(&curl, mytrits, 0, TRANSACTION_LENGTH); 119 | squeeze(&curl, hash_trits, 0, HASH_LENGTH); 120 | 121 | CU_ASSERT(pearl_diver->status != PD_FOUND); 122 | CU_ASSERT(pearl_diver->status == PD_INTERRUPTED); 123 | return 0; 124 | } 125 | void test_pearl_diver_interrupt(void) { 126 | PearlDiver pearl_diver; 127 | 128 | pthread_t tid; 129 | pthread_create(&tid, NULL, &dosearch, (void*)&pearl_diver); 130 | 131 | sleep(1); 132 | 133 | interrupt(&pearl_diver); 134 | 135 | pthread_join(tid, NULL); 136 | } 137 | 138 | void test_export_pow(void) { 139 | char *hash, *output; 140 | char hash_trits[HASH_LENGTH]; 141 | int mwm = 13; 142 | 143 | for (int i = 1; i <= 13; i++) { 144 | output = ccurl_pow((char*)real_transaction, i); 145 | } 146 | output[TRANSACTION_LENGTH / 3] = 0; 147 | char* outtrits = trits_from_trytes(output, TRANSACTION_LENGTH / 3); 148 | 149 | Curl curl; 150 | init_curl(&curl); 151 | 152 | absorb(&curl, outtrits, 0, TRANSACTION_LENGTH); 153 | squeeze(&curl, hash_trits, 0, HASH_LENGTH); 154 | hash = trytes_from_trits(hash_trits, 0, HASH_LENGTH); 155 | hash[HASH_LENGTH / 3] = 0; 156 | 157 | CU_ASSERT_FATAL(test_last_n_nines(hash, HASH_LENGTH / 3, mwm / 3)); 158 | free(outtrits); 159 | free(hash); 160 | } 161 | 162 | void getRandomTrits(char* RandomTrits, int length) { 163 | int i = 0; 164 | srand(time(NULL)); 165 | while (i < length) { 166 | RandomTrits[i] = rand() % 3 - 1; 167 | i++; 168 | } 169 | } 170 | 171 | static CU_TestInfo tests[] = { 172 | {"PearlDiver Search Test", test_pearl_diver_search}, 173 | {"PearlDiver Interrupt Test", test_pearl_diver_interrupt}, 174 | {"PearlDiver test curl_pow export", test_export_pow}, 175 | CU_TEST_INFO_NULL, 176 | }; 177 | 178 | static CU_SuiteInfo suites[] = { 179 | {"suitename1", init_suites, clean_suites, NULL, NULL, tests}, 180 | CU_SUITE_INFO_NULL, 181 | }; 182 | 183 | int main() { return run_tests(suites); } 184 | --------------------------------------------------------------------------------