├── .gitignore ├── .idea └── cmake.xml ├── CMakeLists.txt ├── LICENSE ├── README.md ├── docs └── Doxyfile.in ├── ed25519.podspec ├── ed25519cpp.pc.in ├── external └── ed25519 │ ├── include │ ├── ed25519.h │ ├── fe.h │ ├── fixedint.h │ ├── ge.h │ ├── precomp_data.h │ ├── sc.h │ └── sha512.h │ ├── license.txt │ ├── readme.md │ └── src │ ├── add_scalar.c │ ├── fe.c │ ├── ge.c │ ├── key_exchange.c │ ├── keypair.c │ ├── sc.c │ ├── seed.c │ ├── sha512.c │ ├── sign.c │ └── verify.c ├── include ├── ed25519.hpp └── ed25519 │ └── c++17 │ └── variant.hpp ├── lib ├── CMakeLists.txt └── cmake │ ├── Config.cmake.in │ └── ed25519cpp.cmake ├── platforms └── swift │ ├── sdk │ └── Classes │ │ ├── ed25519_wrapper.h │ │ └── ed25519_wrapper.mm │ └── test │ └── Ed25519-Swift-pod │ ├── Ed25519-Swift-pod.xcodeproj │ └── project.pbxproj │ ├── Ed25519-Swift-pod.xcworkspace │ └── xcuserdata │ │ └── denn.xcuserdatad │ │ └── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ ├── Ed25519-Swift-pod │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ └── MainMenu.xib │ ├── Ed25519_Swift_pod.entitlements │ └── Info.plist │ ├── Ed25519-Swift-podTests │ ├── Ed25519_Swift_podTests.swift │ └── Info.plist │ └── Podfile ├── src ├── base58.cpp ├── digest.cpp ├── ed25519.cpp ├── external │ ├── btc_base58.cpp │ ├── btc_base58.hpp │ ├── ed25519_ext.cpp │ ├── ed25519_ext.hpp │ ├── sha3.cpp │ └── sha3.hpp └── utils.cpp └── test ├── CMakeLists.txt ├── api ├── CMakeLists.txt └── api_test.cpp ├── digest ├── CMakeLists.txt └── digest.cpp └── performance ├── CMakeLists.txt └── sigantures.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/* 2 | !.idea/cmake.xml 3 | 4 | # Prerequisites 5 | *.d 6 | 7 | # Compiled Object files 8 | *.slo 9 | *.lo 10 | *.o 11 | *.obj 12 | 13 | # Precompiled Headers 14 | *.gch 15 | *.pch 16 | 17 | # Compiled Dynamic libraries 18 | *.so 19 | *.dylib 20 | *.dll 21 | 22 | # Fortran module files 23 | *.mod 24 | *.smod 25 | 26 | # Compiled Static libraries 27 | *.lai 28 | *.la 29 | *.a 30 | *.lib 31 | 32 | # Executables 33 | *.exe 34 | *.out 35 | *.app 36 | 37 | # Builds 38 | CMakeCache.txt 39 | CMakeFiles 40 | CMakeScripts 41 | CTestTestfile.cmake 42 | *build* 43 | cmake-build-* 44 | Index 45 | Build 46 | Pods 47 | Podfile.lock 48 | *.xcworkspacedata 49 | .version 50 | .vscode -------------------------------------------------------------------------------- /.idea/cmake.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.22) 2 | 3 | set(PROJECT_LIB ed25519cpp) 4 | 5 | project(${PROJECT_LIB} VERSION 1.4.0) 6 | set(CMAKE_CXX_STANDARD 17) 7 | 8 | option(DEHANCER_TARGET_ARCH "") 9 | option(BUILD_TESTING "Enable creation of Eigen tests." OFF) 10 | # first we can indicate the documentation build as an option and set it to ON by default 11 | option(BUILD_DOC "Build documentation" OFF) 12 | 13 | 14 | if (WIN32) 15 | 16 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -EHsc -Wno-deprecated-declarations") 17 | add_definitions(/MT /DWIN32=1 /D_ITERATOR_DEBUG_LEVEL=0) 18 | string(TOLOWER ${CMAKE_BUILD_TYPE} BUILD_TYPE) 19 | if (${BUILD_TYPE} STREQUAL "debug") 20 | add_definitions(/MTd) 21 | endif() 22 | 23 | else() 24 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") 25 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") 26 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g") 27 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=default") 28 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-command-line-argument") 29 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -ffast-math") 30 | endif () 31 | 32 | 33 | set (EXTERNAL_INSTALL_LOCATION ${CMAKE_BINARY_DIR}/external) 34 | 35 | # 36 | # Packages 37 | # 38 | find_package(PkgConfig REQUIRED) 39 | find_program(CCACHE_FOUND ccache) 40 | 41 | if(CCACHE_FOUND) 42 | set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) 43 | set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) 44 | endif(CCACHE_FOUND) 45 | 46 | message(STATUS ${CMAKE_CURRENT_SOURCE_DIR} ) 47 | 48 | if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") 49 | 50 | message(STATUS "Using Clang" ) 51 | 52 | elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") 53 | 54 | message(STATUS "Using gcc" ) 55 | 56 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -W -Wall -Wextra -Wvariadic-macros -static-libgcc -static-libstdc++ ") 57 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") 58 | 59 | if (${CMAKE_SYSTEM_NAME} STREQUAL Linux) 60 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DX86_LINUX") 61 | endif() 62 | 63 | elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") 64 | 65 | message( FATAL_ERROR "The project does not support Intel compiler" ) 66 | 67 | elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") 68 | 69 | message( FATAL_ERROR "The project does not support MSVC compiler" ) 70 | 71 | endif() 72 | 73 | # check if Doxygen is installed 74 | if(BUILD_DOC) 75 | find_package(Doxygen) 76 | if (DOXYGEN_FOUND) 77 | # set input and output files 78 | set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in) 79 | set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) 80 | 81 | # request to configure the file 82 | configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY) 83 | message("Doxygen build started") 84 | 85 | # note the option ALL which allows to build the docs together with the application 86 | add_custom_target( doc_doxygen ALL 87 | COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT} 88 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 89 | COMMENT "Generating API documentation with Doxygen" 90 | VERBATIM ) 91 | else (DOXYGEN_FOUND) 92 | message("Doxygen need to be installed to generate the doxygen documentation") 93 | endif (DOXYGEN_FOUND) 94 | endif() 95 | 96 | 97 | # 98 | # Google Test 99 | # 100 | if (BUILD_TESTING) 101 | 102 | find_package(GTest) 103 | 104 | if (NOT GTest_FOUND) 105 | 106 | string(STRIP "${CMAKE_C_FLAGS} -D_ITERATOR_DEBUG_LEVEL=0" C_FLAGS) 107 | string(STRIP "${CMAKE_CXX_FLAGS} -D_ITERATOR_DEBUG_LEVEL=0" CXX_FLAGS) 108 | 109 | set(CMAKE_OSX_ARCHITECTURES "${CMAKE_OSX_ARCHITECTURES}" CACHE STRING "" FORCE) 110 | 111 | include(FetchContent) 112 | 113 | FetchContent_Declare( 114 | googletest 115 | GIT_REPOSITORY https://github.com/google/googletest.git 116 | GIT_TAG v1.14.0 117 | SOURCE_DIR "${CMAKE_BINARY_DIR}/googletest-src" 118 | BINARY_DIR "${CMAKE_BINARY_DIR}/googletest-build" 119 | INSTALL_COMMAND 120 | OVERRIDE_FIND_PACKAGE 121 | ) 122 | 123 | FetchContent_GetProperties(googletest) 124 | 125 | if(NOT googletest_POPULATED) 126 | FetchContent_Populate(googletest) 127 | add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR} EXCLUDE_FROM_ALL) 128 | endif() 129 | 130 | endif () 131 | 132 | endif () 133 | 134 | # 135 | # Details 136 | # 137 | include_directories( 138 | ${EXTERNAL_INSTALL_LOCATION}/include 139 | ${CMAKE_SOURCE_DIR}/include 140 | ${CMAKE_SOURCE_DIR}/external 141 | ${SQLITE3_INCLUDE_DIRS} 142 | ) 143 | 144 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/lib) 145 | 146 | if (BUILD_TESTING) 147 | add_subdirectory(test) 148 | enable_testing () 149 | endif () 150 | 151 | # Install package 152 | # 153 | if (NOT CMAKE_INSTALL_LIBDIR) 154 | set(CMAKE_INSTALL_LIBDIR lib) 155 | endif () 156 | if (NOT CMAKE_INSTALL_INCLUDEDIR) 157 | set(CMAKE_INSTALL_INCLUDEDIR include) 158 | endif () 159 | 160 | set(prefix ${CMAKE_INSTALL_PREFIX}) 161 | set(exec_prefix "\${prefix}") 162 | set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}") 163 | set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") 164 | 165 | configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ed25519cpp.pc.in ${CMAKE_CURRENT_BINARY_DIR}/ed25519cpp.pc @ONLY) 166 | 167 | install(FILES 168 | ${CMAKE_CURRENT_BINARY_DIR}/ed25519cpp.pc 169 | DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig 170 | ) 171 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Denis 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # ed25519cpp - Ed25519 C++17 implementation 3 | 4 | This is a portable implementation of [Ed25519](http://ed25519.cr.yp.to/) based 5 | on the SUPERCOP "ref10" implementation. The ed25519cpp wraps c-based implementing modern c++17 dialect. Additionally there is some extension which make easier the work with base58-encoded strings and pair of keys based on ed25519. 6 | 7 | ## Home pages explains ed25519 8 | 1. https://ed25519.cr.yp.to/ 9 | 1. https://en.wikipedia.org/wiki/EdDSA 10 | 11 | ## Requirements 12 | 1. c++17 13 | 1. cmake 14 | 1. boost unitest installed includes (>=1.66, exclude 1.68!) 15 | 16 | ## Build 17 | git clone https://github.com/dnevera/ed25519cpp/ 18 | cd ./ed25519cpp; mkdir build; cd ./build 19 | git clone https://github.com/dnevera/base64cpp 20 | cd ./base64cpp; mkdir build; cd ./build 21 | 22 | # mac os M1 universal bin 23 | cmake -DCMAKE_OSX_ARCHITECTURES=arm64;x86_64 .. 24 | cmake --build . && cmake --build . --target=install 25 | 26 | # or mac os Intel 27 | cmake -DCMAKE_OSX_ARCHITECTURES=x86_64 .. 28 | cmake --build . && cmake --build . --target=install 29 | ctest -C Debug -V 30 | 31 | ## Build ios 32 | # https://blog.tomtasche.at/2019/05/how-to-include-cmake-project-in-xcode.html 33 | 34 | git clone https://github.com/dehancer/ios-cmake 35 | cmake -G Xcode \ 36 | -DCMAKE_TOOLCHAIN_FILE=~/Develop/Dehancer/Dehancer-Plugins/ios-cmake/ios.toolchain.cmake\ 37 | -DENABLE_BITCODE=ON 38 | -DPLATFORM=OS64COMBINED -DBUILD_TESTING=OFF \ 39 | -DCMAKE_INSTALL_PREFIX=~/Develop/local/ios/dehancer 40 | cmake --build . --config Release && cmake --install . --config Release 41 | 42 | ## Tested 43 | 1. Centos7 (gcc v7.0) 44 | 1. Ubuntu 18.04 45 | 1. OSX 10.13, XCode10 46 | 47 | ## [API](https://htmlpreview.github.io/?https://github.com/dnevera/ed25519cpp/blob/master/docs/html/namespaces.html) 48 | 49 | 50 | ## Examples 51 | ### Random seed generator 52 | 53 | ```c++ 54 | #include "ed25519.hpp" 55 | 56 | 57 | ed25519::Seed seed; 58 | std::cout << "Seed base58 string: "<< seed.encode() << std::endl; 59 | 60 | ``` 61 | 62 | ### Create random keys pair 63 | 64 | ```c++ 65 | #include "ed25519.hpp" 66 | 67 | if (auto pair = ed25519::keys::Pair::Random()){ 68 | std::cout << "ed25519 random keys pair: "<< pair->get_public_key.encode() << "/" << pair->get_private_key().encode() << std::endl; 69 | } 70 | 71 | 72 | ``` 73 | 74 | ### Create keys pair from private key 75 | 76 | ```c++ 77 | #include "ed25519.hpp" 78 | 79 | auto error_handler = [](const std::error_code code){ 80 | BOOST_TEST_MESSAGE("Test error: " + ed25519::StringFormat("code: %i, message: %s", code.value(), + code.message().c_str())); 81 | }; 82 | 83 | if (auto pair = ed25519::keys::Pair::FromPrivateKey(secret_pair->get_private_key().encode(), error_handler)){ 84 | std::cout << "ed25519 random keys pair: "<< pair->get_public_key.encode() << "/" << pair->get_private_key().encode() << std::endl; 85 | } 86 | else{ 87 | // handling error 88 | } 89 | 90 | 91 | ``` 92 | 93 | ### Create keys pair with secret phrase 94 | 95 | ```c++ 96 | #include "ed25519.hpp" 97 | 98 | 99 | if (auto pair = ed25519::keys::Pair::WithSecret("some secret phrase", error_handler)){ 100 | std::cout << "ed25519 random keys pair: "<< pair->get_public_key.encode() << "/" << pair->get_private_key().encode() << std::endl; 101 | } 102 | else{ 103 | // handling error 104 | } 105 | 106 | 107 | ``` 108 | 109 | ### Sign message 110 | 111 | ```c++ 112 | #include "ed25519.hpp" 113 | 114 | // create pair 115 | auto pair = ed25519::keys::Pair::WithSecret("some secret phrase"); 116 | 117 | // some message 118 | std::string message = "some message or token string"; 119 | 120 | // sign message return uniq_ptr siganture 121 | auto signature = pair->sign(message); 122 | 123 | if (signature->verify(message, pair->get_public_key())) { 124 | // handle verified 125 | } 126 | 127 | // 128 | // It is not available to create empty signature: 129 | // auto signature = ed25519::keys::Pair::Siganture() 130 | // only copy operations or restore from base58-encoded string 131 | // 132 | auto another_signature = ed25519::Signature::Decode(signature->encode()); 133 | 134 | // 135 | // Handle errors when restoration 136 | // 137 | 138 | if (auto signature = ed25519::Signature::Decode("...some wrong encoded string ...", error_handler)){ 139 | // handle verified 140 | } 141 | else { 142 | // handle error 143 | } 144 | 145 | ``` 146 | 147 | ### Create digest hash from variant types 148 | 149 | ```c++ 150 | 151 | auto digest = Digest([pair](auto &calculator) { 152 | 153 | // 154 | // set big endian 155 | // little endian is default 156 | // 157 | 158 | calculator.set_endian(Digest::Calculator::endian::big); 159 | 160 | std::cout << "Calculator endian: " << calculator.get_endian() << std::endl; 161 | 162 | calculator.append(true); 163 | 164 | calculator.append(1); 165 | 166 | calculator.append((int)(1.12f * 100)); 167 | 168 | std::string title = "123"; 169 | 170 | calculator.append(title); 171 | 172 | std::vector v(title.begin(), title.end()); 173 | 174 | calculator.append(v); 175 | 176 | }); 177 | 178 | // 179 | // Encode to base58 180 | // 181 | auto base58 = digest.encode(); 182 | 183 | // 184 | // Sign digest 185 | // 186 | auto siganture = pair->sign(digest); 187 | 188 | if (siganture->verify(digest, pair->get_public_key())) { 189 | // 190 | // handle verified digest 191 | // 192 | } 193 | 194 | // 195 | // Restore from base58-encded string 196 | // 197 | auto digest_restored = Digest::Decode(digest.encode(), error_handler); 198 | 199 | if (digest_restored && siganture->verify(*digest_restored, pair->get_public_key())) { 200 | // 201 | // handle restored and verified 202 | // 203 | } 204 | ``` 205 | 206 | 207 | ### Windows 208 | # Requrements: 209 | # Visual Studio, English Language Pack! 210 | # https://vcpkg.info/ 211 | # GitBash 212 | 213 | cd C: 214 | git clone https://github.com/microsoft/vcpkg 215 | cd /c/vcpkg/ 216 | ./bootstrap-vcpkg.sh 217 | /c/vcpkg/vcpkg integrate install 218 | /c/vcpkg/vcpkg install gtest 219 | 220 | # cmake integration 221 | -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -------------------------------------------------------------------------------- /docs/Doxyfile.in: -------------------------------------------------------------------------------- 1 | OUTPUT_DIRECTORY = @CMAKE_CURRENT_SOURCE_DIR@/docs/ 2 | INPUT = @CMAKE_CURRENT_SOURCE_DIR@/include @CMAKE_CURRENT_SOURCE_DIR@/README.md 3 | EXTRACT_STATIC = YES 4 | EXTRACT_ALL = YES 5 | EXTRACT_LOCAL_CLASSES = YES 6 | RECURSIVE = YES 7 | BRIEF_MEMBER_DESC = YES 8 | INHERIT_DOCS = YES 9 | INLINE_INFO = YES 10 | SORT_MEMBER_DOCS = YES 11 | 12 | MARKDOWN_SUPPORT = YES 13 | USE_MDFILE_AS_MAINPAGE = README.md -------------------------------------------------------------------------------- /ed25519.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | s.name = "ed25519" 4 | s.version = "0.5.0" 5 | s.summary = "ed25519 is a public-key signature system framework for swift" 6 | s.description = "ed25519 features: Fast single-signature verification; fast batch verification; very fast signing; high security level; small size of keys and signatures" 7 | 8 | s.homepage = "https://ed25519.cr.yp.to/" 9 | 10 | s.license = { :type => "MIT", :file => "LICENSE" } 11 | s.authors = { "denis svinarchuk" => "denn.nevera@gmail.com" } 12 | s.social_media_url = "https://mile.global" 13 | 14 | s.platform = :ios 15 | s.platform = :osx 16 | 17 | s.ios.deployment_target = "11.0" 18 | s.osx.deployment_target = "10.14" 19 | 20 | s.swift_version = "4.2" 21 | 22 | s.source = { :git => "https://github.com/dnevera/ed25519cpp", :tag => "#{s.version}" } 23 | 24 | s.source_files = "platforms/swift/sdk/Classes/*.{h,m,mm}", 25 | "src/*.cpp", 26 | "src/external/*.{cpp,hpp}", 27 | "include/**/*.hpp", 28 | "external/ed25519/src/*.{c,h}", 29 | "external/ed25519/include/*.{h}" 30 | 31 | s.exclude_files = "test", "docs", "build", "cmake-build-debug" 32 | 33 | s.public_header_files = "platforms/swift/sdk/Classes/*.{h,hpp}" 34 | 35 | s.frameworks = "Foundation" 36 | s.libraries = 'c++' 37 | 38 | s.requires_arc = true 39 | s.compiler_flags = '-Wno-format', '-x objective-c++', '-DNDEBUG', '-DUSE_DEC_FIXEDPOINT', '-DR128_STDC_ONLY' 40 | 41 | s.xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => 'CSA=1' , 'OTHER_CFLAGS' => '', 42 | 'HEADER_SEARCH_PATHS' => '"/usr/local/include" "${PODS_ROOT}" "${PODS_ROOT}/src" "${PODS_ROOT}/../../../src" "${PODS_ROOT}/../../ed25519cpp/src"', 43 | 'CLANG_CXX_LANGUAGE_STANDARD' => 'c++17', 44 | 'CLANG_CXX_LIBRARY' => 'libc++'} 45 | 46 | end 47 | -------------------------------------------------------------------------------- /ed25519cpp.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: ed25519cpp 7 | Description: ED25519 Curve CPP Wrapper 8 | Version: @PROJECT_VERSION@ 9 | URL: https://github.com/dnevera/ed25519cpp 10 | Requires.private: @requires_private@ 11 | Libs: -L${libdir} -led25519cpp 12 | Libs.private: @libs_private@ 13 | CFlags: -I${includedir} 14 | -------------------------------------------------------------------------------- /external/ed25519/include/ed25519.h: -------------------------------------------------------------------------------- 1 | #ifndef ED25519_H 2 | #define ED25519_H 3 | 4 | #include 5 | 6 | #if defined(_WIN32) 7 | #if defined(ED25519_BUILD_DLL) 8 | #define ED25519_DECLSPEC __declspec(dllexport) 9 | #elif defined(ED25519_DLL) 10 | #define ED25519_DECLSPEC __declspec(dllimport) 11 | #else 12 | #define ED25519_DECLSPEC 13 | #endif 14 | #else 15 | #define ED25519_DECLSPEC 16 | #endif 17 | 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | #ifndef ED25519_NO_SEED 24 | int ED25519_DECLSPEC ed25519_create_seed(unsigned char *seed); 25 | #endif 26 | 27 | void ED25519_DECLSPEC ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed); 28 | void ED25519_DECLSPEC ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key); 29 | int ED25519_DECLSPEC ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key); 30 | void ED25519_DECLSPEC ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key, const unsigned char *scalar); 31 | void ED25519_DECLSPEC ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key); 32 | 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /external/ed25519/include/fe.h: -------------------------------------------------------------------------------- 1 | #ifndef FE_H 2 | #define FE_H 3 | 4 | #include "fixedint.h" 5 | 6 | 7 | /* 8 | fe means field element. 9 | Here the field is \Z/(2^255-19). 10 | An element t, entries t[0]...t[9], represents the integer 11 | t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9]. 12 | Bounds on each t[i] vary depending on context. 13 | */ 14 | 15 | 16 | typedef int32_t fe[10]; 17 | 18 | 19 | void fe_0(fe h); 20 | void fe_1(fe h); 21 | 22 | void fe_frombytes(fe h, const unsigned char *s); 23 | void fe_tobytes(unsigned char *s, const fe h); 24 | 25 | void fe_copy(fe h, const fe f); 26 | int fe_isnegative(const fe f); 27 | int fe_isnonzero(const fe f); 28 | void fe_cmov(fe f, const fe g, unsigned int b); 29 | void fe_cswap(fe f, fe g, unsigned int b); 30 | 31 | void fe_neg(fe h, const fe f); 32 | void fe_add(fe h, const fe f, const fe g); 33 | void fe_invert(fe out, const fe z); 34 | void fe_sq(fe h, const fe f); 35 | void fe_sq2(fe h, const fe f); 36 | void fe_mul(fe h, const fe f, const fe g); 37 | void fe_mul121666(fe h, fe f); 38 | void fe_pow22523(fe out, const fe z); 39 | void fe_sub(fe h, const fe f, const fe g); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /external/ed25519/include/fixedint.h: -------------------------------------------------------------------------------- 1 | /* 2 | Portable header to provide the 32 and 64 bits type. 3 | 4 | Not a compatible replacement for , do not blindly use it as such. 5 | */ 6 | 7 | #if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__WATCOMC__) && (defined(_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_) || defined(__UINT_FAST64_TYPE__)) )) && !defined(FIXEDINT_H_INCLUDED) 8 | #include 9 | #define FIXEDINT_H_INCLUDED 10 | 11 | #if defined(__WATCOMC__) && __WATCOMC__ >= 1250 && !defined(UINT64_C) 12 | #include 13 | #define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX)) 14 | #endif 15 | #endif 16 | 17 | 18 | #ifndef FIXEDINT_H_INCLUDED 19 | #define FIXEDINT_H_INCLUDED 20 | 21 | #include 22 | 23 | /* (u)int32_t */ 24 | #ifndef uint32_t 25 | #if (ULONG_MAX == 0xffffffffUL) 26 | typedef unsigned long uint32_t; 27 | #elif (UINT_MAX == 0xffffffffUL) 28 | typedef unsigned int uint32_t; 29 | #elif (USHRT_MAX == 0xffffffffUL) 30 | typedef unsigned short uint32_t; 31 | #endif 32 | #endif 33 | 34 | 35 | #ifndef int32_t 36 | #if (LONG_MAX == 0x7fffffffL) 37 | typedef signed long int32_t; 38 | #elif (INT_MAX == 0x7fffffffL) 39 | typedef signed int int32_t; 40 | #elif (SHRT_MAX == 0x7fffffffL) 41 | typedef signed short int32_t; 42 | #endif 43 | #endif 44 | 45 | 46 | /* (u)int64_t */ 47 | #if (defined(__STDC__) && defined(__STDC_VERSION__) && __STDC__ && __STDC_VERSION__ >= 199901L) 48 | typedef long long int64_t; 49 | typedef unsigned long long uint64_t; 50 | 51 | #define UINT64_C(v) v ##ULL 52 | #define INT64_C(v) v ##LL 53 | #elif defined(__GNUC__) 54 | __extension__ typedef long long int64_t; 55 | __extension__ typedef unsigned long long uint64_t; 56 | 57 | #define UINT64_C(v) v ##ULL 58 | #define INT64_C(v) v ##LL 59 | #elif defined(__MWERKS__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__APPLE_CC__) || defined(_LONG_LONG) || defined(_CRAYC) 60 | typedef long long int64_t; 61 | typedef unsigned long long uint64_t; 62 | 63 | #define UINT64_C(v) v ##ULL 64 | #define INT64_C(v) v ##LL 65 | #elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined(__BORLANDC__) && __BORLANDC__ > 0x460) || defined(__alpha) || defined(__DECC) 66 | typedef __int64 int64_t; 67 | typedef unsigned __int64 uint64_t; 68 | 69 | #define UINT64_C(v) v ##UI64 70 | #define INT64_C(v) v ##I64 71 | #endif 72 | #endif 73 | -------------------------------------------------------------------------------- /external/ed25519/include/ge.h: -------------------------------------------------------------------------------- 1 | #ifndef GE_H 2 | #define GE_H 3 | 4 | #include "fe.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | 11 | /* 12 | ge means group element. 13 | 14 | Here the group is the set of pairs (x,y) of field elements (see fe.h) 15 | satisfying -x^2 + y^2 = 1 + d x^2y^2 16 | where d = -121665/121666. 17 | 18 | Representations: 19 | ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z 20 | ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT 21 | ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T 22 | ge_precomp (Duif): (y+x,y-x,2dxy) 23 | */ 24 | 25 | typedef struct { 26 | fe X; 27 | fe Y; 28 | fe Z; 29 | } ge_p2; 30 | 31 | typedef struct { 32 | fe X; 33 | fe Y; 34 | fe Z; 35 | fe T; 36 | } ge_p3; 37 | 38 | typedef struct { 39 | fe X; 40 | fe Y; 41 | fe Z; 42 | fe T; 43 | } ge_p1p1; 44 | 45 | typedef struct { 46 | fe yplusx; 47 | fe yminusx; 48 | fe xy2d; 49 | } ge_precomp; 50 | 51 | typedef struct { 52 | fe YplusX; 53 | fe YminusX; 54 | fe Z; 55 | fe T2d; 56 | } ge_cached; 57 | 58 | void ge_p3_tobytes(unsigned char *s, const ge_p3 *h); 59 | void ge_tobytes(unsigned char *s, const ge_p2 *h); 60 | int ge_frombytes_negate_vartime(ge_p3 *h, const unsigned char *s); 61 | 62 | void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q); 63 | void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q); 64 | void ge_double_scalarmult_vartime(ge_p2 *r, const unsigned char *a, const ge_p3 *A, const unsigned char *b); 65 | void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q); 66 | void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q); 67 | void ge_scalarmult_base(ge_p3 *h, const unsigned char *a); 68 | 69 | void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p); 70 | void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p); 71 | void ge_p2_0(ge_p2 *h); 72 | void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p); 73 | void ge_p3_0(ge_p3 *h); 74 | void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p); 75 | void ge_p3_to_cached(ge_cached *r, const ge_p3 *p); 76 | void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p); 77 | 78 | 79 | #ifdef __cplusplus 80 | } 81 | #endif 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /external/ed25519/include/sc.h: -------------------------------------------------------------------------------- 1 | #ifndef SC_H 2 | #define SC_H 3 | 4 | /* 5 | The set of scalars is \Z/l 6 | where l = 2^252 + 27742317777372353535851937790883648493. 7 | */ 8 | 9 | void sc_reduce(unsigned char *s); 10 | void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, const unsigned char *c); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /external/ed25519/include/sha512.h: -------------------------------------------------------------------------------- 1 | #ifndef SHA512_H 2 | #define SHA512_H 3 | 4 | #include 5 | 6 | #include "fixedint.h" 7 | 8 | /* state */ 9 | typedef struct sha512_context_ { 10 | uint64_t length, state[8]; 11 | size_t curlen; 12 | unsigned char buf[128]; 13 | } sha512_context; 14 | 15 | 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | int sha512_init(sha512_context * md); 22 | int sha512_final(sha512_context * md, unsigned char *out); 23 | int sha512_update(sha512_context * md, const unsigned char *in, size_t inlen); 24 | int sha512(const unsigned char *message, size_t message_len, unsigned char *out); 25 | 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /external/ed25519/license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Orson Peters 2 | 3 | This software is provided 'as-is', without any express or implied warranty. In no event will the 4 | authors be held liable for any damages arising from the use of this software. 5 | 6 | Permission is granted to anyone to use this software for any purpose, including commercial 7 | applications, and to alter it and redistribute it freely, subject to the following restrictions: 8 | 9 | 1. The origin of this software must not be misrepresented; you must not claim that you wrote the 10 | original software. If you use this software in a product, an acknowledgment in the product 11 | documentation would be appreciated but is not required. 12 | 13 | 2. Altered source versions must be plainly marked as such, and must not be misrepresented as 14 | being the original software. 15 | 16 | 3. This notice may not be removed or altered from any source distribution. 17 | -------------------------------------------------------------------------------- /external/ed25519/readme.md: -------------------------------------------------------------------------------- 1 | Ed25519 2 | ======= 3 | 4 | This is a portable implementation of [Ed25519](http://ed25519.cr.yp.to/) based 5 | on the SUPERCOP "ref10" implementation. Additionally there is key exchanging 6 | and scalar addition included to further aid building a PKI using Ed25519. All 7 | code is licensed under the permissive zlib license. 8 | 9 | All code is pure ANSI C without any dependencies, except for the random seed 10 | generation which uses standard OS cryptography APIs (`CryptGenRandom` on 11 | Windows, `/dev/urandom` on nix). If you wish to be entirely portable define 12 | `ED25519_NO_SEED`. This disables the `ed25519_create_seed` function, so if your 13 | application requires key generation you must supply your own seeding function 14 | (which is simply a 256 bit (32 byte) cryptographic random number generator). 15 | 16 | 17 | Performance 18 | ----------- 19 | 20 | On a Windows machine with an Intel Pentium B970 @ 2.3GHz I got the following 21 | speeds (running on only one a single core): 22 | 23 | Seed generation: 64us (15625 per second) 24 | Key generation: 88us (11364 per second) 25 | Message signing (short message): 87us (11494 per second) 26 | Message verifying (short message): 228us (4386 per second) 27 | Scalar addition: 100us (10000 per second) 28 | Key exchange: 220us (4545 per second) 29 | 30 | The speeds on other machines may vary. Sign/verify times will be higher with 31 | longer messages. The implementation significantly benefits from 64 bit 32 | architectures, if possible compile as 64 bit. 33 | 34 | 35 | Usage 36 | ----- 37 | 38 | Simply add all .c and .h files in the `src/` folder to your project and include 39 | `ed25519.h` in any file you want to use the API. If you prefer to use a shared 40 | library, only copy `ed25519.h` and define `ED25519_DLL` before importing. A 41 | windows DLL is pre-built. 42 | 43 | There are no defined types for seeds, private keys, public keys, shared secrets 44 | or signatures. Instead simple `unsigned char` buffers are used with the 45 | following sizes: 46 | 47 | ```c 48 | unsigned char seed[32]; 49 | unsigned char signature[64]; 50 | unsigned char public_key[32]; 51 | unsigned char private_key[64]; 52 | unsigned char scalar[32]; 53 | unsigned char shared_secret[32]; 54 | ``` 55 | 56 | API 57 | --- 58 | 59 | ```c 60 | int ed25519_create_seed(unsigned char *seed); 61 | ``` 62 | 63 | Creates a 32 byte random seed in `seed` for key generation. `seed` must be a 64 | writable 32 byte buffer. Returns 0 on success, and nonzero on failure. 65 | 66 | ```c 67 | void ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, 68 | const unsigned char *seed); 69 | ``` 70 | 71 | Creates a new key Pair from the given seed. `public_key` must be a writable 32 72 | byte buffer, `private_key` must be a writable 64 byte buffer and `seed` must be 73 | a 32 byte buffer. 74 | 75 | ```c 76 | void ed25519_sign(unsigned char *signature, 77 | const unsigned char *message, size_t message_len, 78 | const unsigned char *public_key, const unsigned char *private_key); 79 | ``` 80 | 81 | Creates a signature of the given message with the given key Pair. `signature` 82 | must be a writable 64 byte buffer. `message` must have at least `message_len` 83 | bytes to be read. 84 | 85 | ```c 86 | int ed25519_verify(const unsigned char *signature, 87 | const unsigned char *message, size_t message_len, 88 | const unsigned char *public_key); 89 | ``` 90 | 91 | Verifies the signature on the given message using `public_key`. `signature` 92 | must be a readable 64 byte buffer. `message` must have at least `message_len` 93 | bytes to be read. Returns 1 if the signature matches, 0 otherwise. 94 | 95 | ```c 96 | void ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key, 97 | const unsigned char *scalar); 98 | ``` 99 | 100 | Adds `scalar` to the given key Pair where scalar is a 32 byte buffer (possibly 101 | generated with `ed25519_create_seed`), generating a new key Pair. You can 102 | calculate the public key sum without knowing the private key and vice versa by 103 | passing in `NULL` for the key you don't know. This is useful for enforcing 104 | randomness on a key Pair by a third party while only knowing the public key, 105 | among other things. Warning: the last bit of the scalar is ignored - if 106 | comparing scalars make sure to clear it with `scalar[31] &= 127`. 107 | 108 | 109 | ```c 110 | void ed25519_key_exchange(unsigned char *shared_secret, 111 | const unsigned char *public_key, const unsigned char *private_key); 112 | ``` 113 | 114 | Performs a key exchange on the given public key and private key, producing a 115 | shared secret. It is recommended to hash the shared secret before using it. 116 | `shared_secret` must be a 32 byte writable buffer where the shared secret will 117 | be stored. 118 | 119 | Example 120 | ------- 121 | 122 | ```c 123 | unsigned char seed[32], public_key[32], private_key[64], signature[64]; 124 | unsigned char other_public_key[32], other_private_key[64], shared_secret[32]; 125 | const unsigned char message[] = "TEST MESSAGE"; 126 | 127 | /* create a random seed, and a key Pair out of that seed */ 128 | if (ed25519_create_seed(seed)) { 129 | printf("error while generating seed\n"); 130 | exit(1); 131 | } 132 | 133 | ed25519_create_keypair(public_key, private_key, seed); 134 | 135 | /* create signature on the message with the key Pair */ 136 | ed25519_sign(signature, message, strlen(message), public_key, private_key); 137 | 138 | /* verify the signature */ 139 | if (ed25519_verify(signature, message, strlen(message), public_key)) { 140 | printf("valid signature\n"); 141 | } else { 142 | printf("invalid signature\n"); 143 | } 144 | 145 | /* create a dummy keypair to use for a key exchange, normally you'd only have 146 | the public key and receive it through some communication channel */ 147 | if (ed25519_create_seed(seed)) { 148 | printf("error while generating seed\n"); 149 | exit(1); 150 | } 151 | 152 | ed25519_create_keypair(other_public_key, other_private_key, seed); 153 | 154 | /* do a key exchange with other_public_key */ 155 | ed25519_key_exchange(shared_secret, other_public_key, private_key); 156 | 157 | /* 158 | the magic here is that ed25519_key_exchange(shared_secret, public_key, 159 | other_private_key); would result in the same shared_secret 160 | */ 161 | 162 | ``` 163 | 164 | License 165 | ------- 166 | All code is released under the zlib license. See license.txt for details. 167 | -------------------------------------------------------------------------------- /external/ed25519/src/add_scalar.c: -------------------------------------------------------------------------------- 1 | #include "../include/ed25519.h" 2 | #include "../include/ge.h" 3 | #include "../include/sc.h" 4 | #include "../include/sha512.h" 5 | 6 | 7 | /* see http://crypto.stackexchange.com/a/6215/4697 */ 8 | void ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key, const unsigned char *scalar) { 9 | const unsigned char SC_1[32] = {1}; /* scalar with value 1 */ 10 | 11 | unsigned char n[32]; 12 | ge_p3 nB; 13 | ge_p1p1 A_p1p1; 14 | ge_p3 A; 15 | ge_p3 public_key_unpacked; 16 | ge_cached T; 17 | 18 | sha512_context hash; 19 | unsigned char hashbuf[64]; 20 | 21 | int i; 22 | 23 | /* copy the scalar and clear highest bit */ 24 | for (i = 0; i < 31; ++i) { 25 | n[i] = scalar[i]; 26 | } 27 | n[31] = scalar[31] & 127; 28 | 29 | /* private key: a = n + t */ 30 | if (private_key) { 31 | sc_muladd(private_key, SC_1, n, private_key); 32 | 33 | // https://github.com/orlp/ed25519/issues/3 34 | sha512_init(&hash); 35 | sha512_update(&hash, private_key + 32, 32); 36 | sha512_update(&hash, scalar, 32); 37 | sha512_final(&hash, hashbuf); 38 | for (i = 0; i < 32; ++i) { 39 | private_key[32 + i] = hashbuf[i]; 40 | } 41 | } 42 | 43 | /* public key: A = nB + T */ 44 | if (public_key) { 45 | /* if we know the private key we don't need a point addition, which is faster */ 46 | /* using a "timing attack" you could find out wether or not we know the private 47 | key, but this information seems rather useless - if this is important pass 48 | public_key and private_key seperately in 2 function calls */ 49 | if (private_key) { 50 | ge_scalarmult_base(&A, private_key); 51 | } else { 52 | /* unpack public key into T */ 53 | ge_frombytes_negate_vartime(&public_key_unpacked, public_key); 54 | fe_neg(public_key_unpacked.X, public_key_unpacked.X); /* undo negate */ 55 | fe_neg(public_key_unpacked.T, public_key_unpacked.T); /* undo negate */ 56 | ge_p3_to_cached(&T, &public_key_unpacked); 57 | 58 | /* calculate n*B */ 59 | ge_scalarmult_base(&nB, n); 60 | 61 | /* A = n*B + T */ 62 | ge_add(&A_p1p1, &nB, &T); 63 | ge_p1p1_to_p3(&A, &A_p1p1); 64 | } 65 | 66 | /* pack public key */ 67 | ge_p3_tobytes(public_key, &A); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /external/ed25519/src/ge.c: -------------------------------------------------------------------------------- 1 | #include "../include/ge.h" 2 | #include "../include/precomp_data.h" 3 | 4 | 5 | /* 6 | r = p + q 7 | */ 8 | 9 | void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { 10 | fe t0; 11 | fe_add(r->X, p->Y, p->X); 12 | fe_sub(r->Y, p->Y, p->X); 13 | fe_mul(r->Z, r->X, q->YplusX); 14 | fe_mul(r->Y, r->Y, q->YminusX); 15 | fe_mul(r->T, q->T2d, p->T); 16 | fe_mul(r->X, p->Z, q->Z); 17 | fe_add(t0, r->X, r->X); 18 | fe_sub(r->X, r->Z, r->Y); 19 | fe_add(r->Y, r->Z, r->Y); 20 | fe_add(r->Z, t0, r->T); 21 | fe_sub(r->T, t0, r->T); 22 | } 23 | 24 | 25 | static void slide(signed char *r, const unsigned char *a) { 26 | int i; 27 | int b; 28 | int k; 29 | 30 | for (i = 0; i < 256; ++i) { 31 | r[i] = 1 & (a[i >> 3] >> (i & 7)); 32 | } 33 | 34 | for (i = 0; i < 256; ++i) 35 | if (r[i]) { 36 | for (b = 1; b <= 6 && i + b < 256; ++b) { 37 | if (r[i + b]) { 38 | if (r[i] + (r[i + b] << b) <= 15) { 39 | r[i] += r[i + b] << b; 40 | r[i + b] = 0; 41 | } else if (r[i] - (r[i + b] << b) >= -15) { 42 | r[i] -= r[i + b] << b; 43 | 44 | for (k = i + b; k < 256; ++k) { 45 | if (!r[k]) { 46 | r[k] = 1; 47 | break; 48 | } 49 | 50 | r[k] = 0; 51 | } 52 | } else { 53 | break; 54 | } 55 | } 56 | } 57 | } 58 | } 59 | 60 | /* 61 | r = a * A + b * B 62 | where a = a[0]+256*a[1]+...+256^31 a[31]. 63 | and b = b[0]+256*b[1]+...+256^31 b[31]. 64 | B is the Ed25519 base point (x,4/5) with x positive. 65 | */ 66 | 67 | void ge_double_scalarmult_vartime(ge_p2 *r, const unsigned char *a, const ge_p3 *A, const unsigned char *b) { 68 | signed char aslide[256]; 69 | signed char bslide[256]; 70 | ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */ 71 | ge_p1p1 t; 72 | ge_p3 u; 73 | ge_p3 A2; 74 | int i; 75 | slide(aslide, a); 76 | slide(bslide, b); 77 | ge_p3_to_cached(&Ai[0], A); 78 | ge_p3_dbl(&t, A); 79 | ge_p1p1_to_p3(&A2, &t); 80 | ge_add(&t, &A2, &Ai[0]); 81 | ge_p1p1_to_p3(&u, &t); 82 | ge_p3_to_cached(&Ai[1], &u); 83 | ge_add(&t, &A2, &Ai[1]); 84 | ge_p1p1_to_p3(&u, &t); 85 | ge_p3_to_cached(&Ai[2], &u); 86 | ge_add(&t, &A2, &Ai[2]); 87 | ge_p1p1_to_p3(&u, &t); 88 | ge_p3_to_cached(&Ai[3], &u); 89 | ge_add(&t, &A2, &Ai[3]); 90 | ge_p1p1_to_p3(&u, &t); 91 | ge_p3_to_cached(&Ai[4], &u); 92 | ge_add(&t, &A2, &Ai[4]); 93 | ge_p1p1_to_p3(&u, &t); 94 | ge_p3_to_cached(&Ai[5], &u); 95 | ge_add(&t, &A2, &Ai[5]); 96 | ge_p1p1_to_p3(&u, &t); 97 | ge_p3_to_cached(&Ai[6], &u); 98 | ge_add(&t, &A2, &Ai[6]); 99 | ge_p1p1_to_p3(&u, &t); 100 | ge_p3_to_cached(&Ai[7], &u); 101 | ge_p2_0(r); 102 | 103 | for (i = 255; i >= 0; --i) { 104 | if (aslide[i] || bslide[i]) { 105 | break; 106 | } 107 | } 108 | 109 | for (; i >= 0; --i) { 110 | ge_p2_dbl(&t, r); 111 | 112 | if (aslide[i] > 0) { 113 | ge_p1p1_to_p3(&u, &t); 114 | ge_add(&t, &u, &Ai[aslide[i] / 2]); 115 | } else if (aslide[i] < 0) { 116 | ge_p1p1_to_p3(&u, &t); 117 | ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]); 118 | } 119 | 120 | if (bslide[i] > 0) { 121 | ge_p1p1_to_p3(&u, &t); 122 | ge_madd(&t, &u, &Bi[bslide[i] / 2]); 123 | } else if (bslide[i] < 0) { 124 | ge_p1p1_to_p3(&u, &t); 125 | ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]); 126 | } 127 | 128 | ge_p1p1_to_p2(r, &t); 129 | } 130 | } 131 | 132 | 133 | static const fe d = { 134 | -10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116 135 | }; 136 | 137 | static const fe sqrtm1 = { 138 | -32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482 139 | }; 140 | 141 | int ge_frombytes_negate_vartime(ge_p3 *h, const unsigned char *s) { 142 | fe u; 143 | fe v; 144 | fe v3; 145 | fe vxx; 146 | fe check; 147 | fe_frombytes(h->Y, s); 148 | fe_1(h->Z); 149 | fe_sq(u, h->Y); 150 | fe_mul(v, u, d); 151 | fe_sub(u, u, h->Z); /* u = y^2-1 */ 152 | fe_add(v, v, h->Z); /* v = dy^2+1 */ 153 | fe_sq(v3, v); 154 | fe_mul(v3, v3, v); /* v3 = v^3 */ 155 | fe_sq(h->X, v3); 156 | fe_mul(h->X, h->X, v); 157 | fe_mul(h->X, h->X, u); /* x = uv^7 */ 158 | fe_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */ 159 | fe_mul(h->X, h->X, v3); 160 | fe_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */ 161 | fe_sq(vxx, h->X); 162 | fe_mul(vxx, vxx, v); 163 | fe_sub(check, vxx, u); /* vx^2-u */ 164 | 165 | if (fe_isnonzero(check)) { 166 | fe_add(check, vxx, u); /* vx^2+u */ 167 | 168 | if (fe_isnonzero(check)) { 169 | return -1; 170 | } 171 | 172 | fe_mul(h->X, h->X, sqrtm1); 173 | } 174 | 175 | if (fe_isnegative(h->X) == (s[31] >> 7)) { 176 | fe_neg(h->X, h->X); 177 | } 178 | 179 | fe_mul(h->T, h->X, h->Y); 180 | return 0; 181 | } 182 | 183 | 184 | /* 185 | r = p + q 186 | */ 187 | 188 | void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { 189 | fe t0; 190 | fe_add(r->X, p->Y, p->X); 191 | fe_sub(r->Y, p->Y, p->X); 192 | fe_mul(r->Z, r->X, q->yplusx); 193 | fe_mul(r->Y, r->Y, q->yminusx); 194 | fe_mul(r->T, q->xy2d, p->T); 195 | fe_add(t0, p->Z, p->Z); 196 | fe_sub(r->X, r->Z, r->Y); 197 | fe_add(r->Y, r->Z, r->Y); 198 | fe_add(r->Z, t0, r->T); 199 | fe_sub(r->T, t0, r->T); 200 | } 201 | 202 | 203 | /* 204 | r = p - q 205 | */ 206 | 207 | void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { 208 | fe t0; 209 | 210 | fe_add(r->X, p->Y, p->X); 211 | fe_sub(r->Y, p->Y, p->X); 212 | fe_mul(r->Z, r->X, q->yminusx); 213 | fe_mul(r->Y, r->Y, q->yplusx); 214 | fe_mul(r->T, q->xy2d, p->T); 215 | fe_add(t0, p->Z, p->Z); 216 | fe_sub(r->X, r->Z, r->Y); 217 | fe_add(r->Y, r->Z, r->Y); 218 | fe_sub(r->Z, t0, r->T); 219 | fe_add(r->T, t0, r->T); 220 | } 221 | 222 | 223 | /* 224 | r = p 225 | */ 226 | 227 | void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) { 228 | fe_mul(r->X, p->X, p->T); 229 | fe_mul(r->Y, p->Y, p->Z); 230 | fe_mul(r->Z, p->Z, p->T); 231 | } 232 | 233 | 234 | 235 | /* 236 | r = p 237 | */ 238 | 239 | void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) { 240 | fe_mul(r->X, p->X, p->T); 241 | fe_mul(r->Y, p->Y, p->Z); 242 | fe_mul(r->Z, p->Z, p->T); 243 | fe_mul(r->T, p->X, p->Y); 244 | } 245 | 246 | 247 | void ge_p2_0(ge_p2 *h) { 248 | fe_0(h->X); 249 | fe_1(h->Y); 250 | fe_1(h->Z); 251 | } 252 | 253 | 254 | 255 | /* 256 | r = 2 * p 257 | */ 258 | 259 | void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) { 260 | fe t0; 261 | 262 | fe_sq(r->X, p->X); 263 | fe_sq(r->Z, p->Y); 264 | fe_sq2(r->T, p->Z); 265 | fe_add(r->Y, p->X, p->Y); 266 | fe_sq(t0, r->Y); 267 | fe_add(r->Y, r->Z, r->X); 268 | fe_sub(r->Z, r->Z, r->X); 269 | fe_sub(r->X, t0, r->Y); 270 | fe_sub(r->T, r->T, r->Z); 271 | } 272 | 273 | 274 | void ge_p3_0(ge_p3 *h) { 275 | fe_0(h->X); 276 | fe_1(h->Y); 277 | fe_1(h->Z); 278 | fe_0(h->T); 279 | } 280 | 281 | 282 | /* 283 | r = 2 * p 284 | */ 285 | 286 | void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) { 287 | ge_p2 q; 288 | ge_p3_to_p2(&q, p); 289 | ge_p2_dbl(r, &q); 290 | } 291 | 292 | 293 | 294 | /* 295 | r = p 296 | */ 297 | 298 | static const fe d2 = { 299 | -21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199 300 | }; 301 | 302 | void ge_p3_to_cached(ge_cached *r, const ge_p3 *p) { 303 | fe_add(r->YplusX, p->Y, p->X); 304 | fe_sub(r->YminusX, p->Y, p->X); 305 | fe_copy(r->Z, p->Z); 306 | fe_mul(r->T2d, p->T, d2); 307 | } 308 | 309 | 310 | /* 311 | r = p 312 | */ 313 | 314 | void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) { 315 | fe_copy(r->X, p->X); 316 | fe_copy(r->Y, p->Y); 317 | fe_copy(r->Z, p->Z); 318 | } 319 | 320 | 321 | void ge_p3_tobytes(unsigned char *s, const ge_p3 *h) { 322 | fe recip; 323 | fe x; 324 | fe y; 325 | fe_invert(recip, h->Z); 326 | fe_mul(x, h->X, recip); 327 | fe_mul(y, h->Y, recip); 328 | fe_tobytes(s, y); 329 | s[31] ^= fe_isnegative(x) << 7; 330 | } 331 | 332 | 333 | static unsigned char equal(signed char b, signed char c) { 334 | unsigned char ub = b; 335 | unsigned char uc = c; 336 | unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ 337 | uint64_t y = x; /* 0: yes; 1..255: no */ 338 | y -= 1; /* large: yes; 0..254: no */ 339 | y >>= 63; /* 1: yes; 0: no */ 340 | return (unsigned char) y; 341 | } 342 | 343 | static unsigned char negative(signed char b) { 344 | uint64_t x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ 345 | x >>= 63; /* 1: yes; 0: no */ 346 | return (unsigned char) x; 347 | } 348 | 349 | static void cmov(ge_precomp *t, const ge_precomp *u, unsigned char b) { 350 | fe_cmov(t->yplusx, u->yplusx, b); 351 | fe_cmov(t->yminusx, u->yminusx, b); 352 | fe_cmov(t->xy2d, u->xy2d, b); 353 | } 354 | 355 | 356 | static void select(ge_precomp *t, int pos, signed char b) { 357 | ge_precomp minust; 358 | unsigned char bnegative = negative(b); 359 | unsigned char babs = b - (((-bnegative) & b) << 1); 360 | fe_1(t->yplusx); 361 | fe_1(t->yminusx); 362 | fe_0(t->xy2d); 363 | cmov(t, &base[pos][0], equal(babs, 1)); 364 | cmov(t, &base[pos][1], equal(babs, 2)); 365 | cmov(t, &base[pos][2], equal(babs, 3)); 366 | cmov(t, &base[pos][3], equal(babs, 4)); 367 | cmov(t, &base[pos][4], equal(babs, 5)); 368 | cmov(t, &base[pos][5], equal(babs, 6)); 369 | cmov(t, &base[pos][6], equal(babs, 7)); 370 | cmov(t, &base[pos][7], equal(babs, 8)); 371 | fe_copy(minust.yplusx, t->yminusx); 372 | fe_copy(minust.yminusx, t->yplusx); 373 | fe_neg(minust.xy2d, t->xy2d); 374 | cmov(t, &minust, bnegative); 375 | } 376 | 377 | /* 378 | h = a * B 379 | where a = a[0]+256*a[1]+...+256^31 a[31] 380 | B is the Ed25519 base point (x,4/5) with x positive. 381 | 382 | Preconditions: 383 | a[31] <= 127 384 | */ 385 | 386 | void ge_scalarmult_base(ge_p3 *h, const unsigned char *a) { 387 | signed char e[64]; 388 | signed char carry; 389 | ge_p1p1 r; 390 | ge_p2 s; 391 | ge_precomp t; 392 | int i; 393 | 394 | for (i = 0; i < 32; ++i) { 395 | e[2 * i + 0] = (a[i] >> 0) & 15; 396 | e[2 * i + 1] = (a[i] >> 4) & 15; 397 | } 398 | 399 | /* each e[i] is between 0 and 15 */ 400 | /* e[63] is between 0 and 7 */ 401 | carry = 0; 402 | 403 | for (i = 0; i < 63; ++i) { 404 | e[i] += carry; 405 | carry = e[i] + 8; 406 | carry >>= 4; 407 | e[i] -= carry << 4; 408 | } 409 | 410 | e[63] += carry; 411 | /* each e[i] is between -8 and 8 */ 412 | ge_p3_0(h); 413 | 414 | for (i = 1; i < 64; i += 2) { 415 | select(&t, i / 2, e[i]); 416 | ge_madd(&r, h, &t); 417 | ge_p1p1_to_p3(h, &r); 418 | } 419 | 420 | ge_p3_dbl(&r, h); 421 | ge_p1p1_to_p2(&s, &r); 422 | ge_p2_dbl(&r, &s); 423 | ge_p1p1_to_p2(&s, &r); 424 | ge_p2_dbl(&r, &s); 425 | ge_p1p1_to_p2(&s, &r); 426 | ge_p2_dbl(&r, &s); 427 | ge_p1p1_to_p3(h, &r); 428 | 429 | for (i = 0; i < 64; i += 2) { 430 | select(&t, i / 2, e[i]); 431 | ge_madd(&r, h, &t); 432 | ge_p1p1_to_p3(h, &r); 433 | } 434 | } 435 | 436 | 437 | /* 438 | r = p - q 439 | */ 440 | 441 | void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { 442 | fe t0; 443 | 444 | fe_add(r->X, p->Y, p->X); 445 | fe_sub(r->Y, p->Y, p->X); 446 | fe_mul(r->Z, r->X, q->YminusX); 447 | fe_mul(r->Y, r->Y, q->YplusX); 448 | fe_mul(r->T, q->T2d, p->T); 449 | fe_mul(r->X, p->Z, q->Z); 450 | fe_add(t0, r->X, r->X); 451 | fe_sub(r->X, r->Z, r->Y); 452 | fe_add(r->Y, r->Z, r->Y); 453 | fe_sub(r->Z, t0, r->T); 454 | fe_add(r->T, t0, r->T); 455 | } 456 | 457 | 458 | void ge_tobytes(unsigned char *s, const ge_p2 *h) { 459 | fe recip; 460 | fe x; 461 | fe y; 462 | fe_invert(recip, h->Z); 463 | fe_mul(x, h->X, recip); 464 | fe_mul(y, h->Y, recip); 465 | fe_tobytes(s, y); 466 | s[31] ^= fe_isnegative(x) << 7; 467 | } 468 | -------------------------------------------------------------------------------- /external/ed25519/src/key_exchange.c: -------------------------------------------------------------------------------- 1 | #include "../include/ed25519.h" 2 | #include "../include/fe.h" 3 | 4 | void ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key) { 5 | unsigned char e[32]; 6 | unsigned int i; 7 | 8 | fe x1; 9 | fe x2; 10 | fe z2; 11 | fe x3; 12 | fe z3; 13 | fe tmp0; 14 | fe tmp1; 15 | 16 | int pos; 17 | unsigned int swap; 18 | unsigned int b; 19 | 20 | /* copy the private key and make sure it's valid */ 21 | for (i = 0; i < 32; ++i) { 22 | e[i] = private_key[i]; 23 | } 24 | 25 | e[0] &= 248; 26 | e[31] &= 63; 27 | e[31] |= 64; 28 | 29 | /* unpack the public key and convert edwards to montgomery */ 30 | /* due to CodesInChaos: montgomeryX = (edwardsY + 1)*inverse(1 - edwardsY) mod p */ 31 | fe_frombytes(x1, public_key); 32 | fe_1(tmp1); 33 | fe_add(tmp0, x1, tmp1); 34 | fe_sub(tmp1, tmp1, x1); 35 | fe_invert(tmp1, tmp1); 36 | fe_mul(x1, tmp0, tmp1); 37 | 38 | fe_1(x2); 39 | fe_0(z2); 40 | fe_copy(x3, x1); 41 | fe_1(z3); 42 | 43 | swap = 0; 44 | for (pos = 254; pos >= 0; --pos) { 45 | b = e[pos / 8] >> (pos & 7); 46 | b &= 1; 47 | swap ^= b; 48 | fe_cswap(x2, x3, swap); 49 | fe_cswap(z2, z3, swap); 50 | swap = b; 51 | 52 | /* from montgomery.h */ 53 | fe_sub(tmp0, x3, z3); 54 | fe_sub(tmp1, x2, z2); 55 | fe_add(x2, x2, z2); 56 | fe_add(z2, x3, z3); 57 | fe_mul(z3, tmp0, x2); 58 | fe_mul(z2, z2, tmp1); 59 | fe_sq(tmp0, tmp1); 60 | fe_sq(tmp1, x2); 61 | fe_add(x3, z3, z2); 62 | fe_sub(z2, z3, z2); 63 | fe_mul(x2, tmp1, tmp0); 64 | fe_sub(tmp1, tmp1, tmp0); 65 | fe_sq(z2, z2); 66 | fe_mul121666(z3, tmp1); 67 | fe_sq(x3, x3); 68 | fe_add(tmp0, tmp0, z3); 69 | fe_mul(z3, x1, z2); 70 | fe_mul(z2, tmp1, tmp0); 71 | } 72 | 73 | fe_cswap(x2, x3, swap); 74 | fe_cswap(z2, z3, swap); 75 | 76 | fe_invert(z2, z2); 77 | fe_mul(x2, x2, z2); 78 | fe_tobytes(shared_secret, x2); 79 | } 80 | -------------------------------------------------------------------------------- /external/ed25519/src/keypair.c: -------------------------------------------------------------------------------- 1 | #include "../include/ed25519.h" 2 | #include "../include/sha512.h" 3 | #include "../include/ge.h" 4 | 5 | 6 | void ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed) { 7 | ge_p3 A; 8 | 9 | sha512(seed, 32, private_key); 10 | private_key[0] &= 248; 11 | private_key[31] &= 63; 12 | private_key[31] |= 64; 13 | 14 | ge_scalarmult_base(&A, private_key); 15 | ge_p3_tobytes(public_key, &A); 16 | } 17 | -------------------------------------------------------------------------------- /external/ed25519/src/sc.c: -------------------------------------------------------------------------------- 1 | #include "../include/fixedint.h" 2 | #include "../include/sc.h" 3 | 4 | static uint64_t load_3(const unsigned char *in) { 5 | uint64_t result; 6 | 7 | result = (uint64_t) in[0]; 8 | result |= ((uint64_t) in[1]) << 8; 9 | result |= ((uint64_t) in[2]) << 16; 10 | 11 | return result; 12 | } 13 | 14 | static uint64_t load_4(const unsigned char *in) { 15 | uint64_t result; 16 | 17 | result = (uint64_t) in[0]; 18 | result |= ((uint64_t) in[1]) << 8; 19 | result |= ((uint64_t) in[2]) << 16; 20 | result |= ((uint64_t) in[3]) << 24; 21 | 22 | return result; 23 | } 24 | 25 | /* 26 | Input: 27 | s[0]+256*s[1]+...+256^63*s[63] = s 28 | 29 | Output: 30 | s[0]+256*s[1]+...+256^31*s[31] = s mod l 31 | where l = 2^252 + 27742317777372353535851937790883648493. 32 | Overwrites s in place. 33 | */ 34 | 35 | void sc_reduce(unsigned char *s) { 36 | int64_t s0 = 2097151 & load_3(s); 37 | int64_t s1 = 2097151 & (load_4(s + 2) >> 5); 38 | int64_t s2 = 2097151 & (load_3(s + 5) >> 2); 39 | int64_t s3 = 2097151 & (load_4(s + 7) >> 7); 40 | int64_t s4 = 2097151 & (load_4(s + 10) >> 4); 41 | int64_t s5 = 2097151 & (load_3(s + 13) >> 1); 42 | int64_t s6 = 2097151 & (load_4(s + 15) >> 6); 43 | int64_t s7 = 2097151 & (load_3(s + 18) >> 3); 44 | int64_t s8 = 2097151 & load_3(s + 21); 45 | int64_t s9 = 2097151 & (load_4(s + 23) >> 5); 46 | int64_t s10 = 2097151 & (load_3(s + 26) >> 2); 47 | int64_t s11 = 2097151 & (load_4(s + 28) >> 7); 48 | int64_t s12 = 2097151 & (load_4(s + 31) >> 4); 49 | int64_t s13 = 2097151 & (load_3(s + 34) >> 1); 50 | int64_t s14 = 2097151 & (load_4(s + 36) >> 6); 51 | int64_t s15 = 2097151 & (load_3(s + 39) >> 3); 52 | int64_t s16 = 2097151 & load_3(s + 42); 53 | int64_t s17 = 2097151 & (load_4(s + 44) >> 5); 54 | int64_t s18 = 2097151 & (load_3(s + 47) >> 2); 55 | int64_t s19 = 2097151 & (load_4(s + 49) >> 7); 56 | int64_t s20 = 2097151 & (load_4(s + 52) >> 4); 57 | int64_t s21 = 2097151 & (load_3(s + 55) >> 1); 58 | int64_t s22 = 2097151 & (load_4(s + 57) >> 6); 59 | int64_t s23 = (load_4(s + 60) >> 3); 60 | int64_t carry0; 61 | int64_t carry1; 62 | int64_t carry2; 63 | int64_t carry3; 64 | int64_t carry4; 65 | int64_t carry5; 66 | int64_t carry6; 67 | int64_t carry7; 68 | int64_t carry8; 69 | int64_t carry9; 70 | int64_t carry10; 71 | int64_t carry11; 72 | int64_t carry12; 73 | int64_t carry13; 74 | int64_t carry14; 75 | int64_t carry15; 76 | int64_t carry16; 77 | 78 | s11 += s23 * 666643; 79 | s12 += s23 * 470296; 80 | s13 += s23 * 654183; 81 | s14 -= s23 * 997805; 82 | s15 += s23 * 136657; 83 | s16 -= s23 * 683901; 84 | s23 = 0; 85 | s10 += s22 * 666643; 86 | s11 += s22 * 470296; 87 | s12 += s22 * 654183; 88 | s13 -= s22 * 997805; 89 | s14 += s22 * 136657; 90 | s15 -= s22 * 683901; 91 | s22 = 0; 92 | s9 += s21 * 666643; 93 | s10 += s21 * 470296; 94 | s11 += s21 * 654183; 95 | s12 -= s21 * 997805; 96 | s13 += s21 * 136657; 97 | s14 -= s21 * 683901; 98 | s21 = 0; 99 | s8 += s20 * 666643; 100 | s9 += s20 * 470296; 101 | s10 += s20 * 654183; 102 | s11 -= s20 * 997805; 103 | s12 += s20 * 136657; 104 | s13 -= s20 * 683901; 105 | s20 = 0; 106 | s7 += s19 * 666643; 107 | s8 += s19 * 470296; 108 | s9 += s19 * 654183; 109 | s10 -= s19 * 997805; 110 | s11 += s19 * 136657; 111 | s12 -= s19 * 683901; 112 | s19 = 0; 113 | s6 += s18 * 666643; 114 | s7 += s18 * 470296; 115 | s8 += s18 * 654183; 116 | s9 -= s18 * 997805; 117 | s10 += s18 * 136657; 118 | s11 -= s18 * 683901; 119 | s18 = 0; 120 | carry6 = (s6 + (1 << 20)) >> 21; 121 | s7 += carry6; 122 | s6 -= carry6 << 21; 123 | carry8 = (s8 + (1 << 20)) >> 21; 124 | s9 += carry8; 125 | s8 -= carry8 << 21; 126 | carry10 = (s10 + (1 << 20)) >> 21; 127 | s11 += carry10; 128 | s10 -= carry10 << 21; 129 | carry12 = (s12 + (1 << 20)) >> 21; 130 | s13 += carry12; 131 | s12 -= carry12 << 21; 132 | carry14 = (s14 + (1 << 20)) >> 21; 133 | s15 += carry14; 134 | s14 -= carry14 << 21; 135 | carry16 = (s16 + (1 << 20)) >> 21; 136 | s17 += carry16; 137 | s16 -= carry16 << 21; 138 | carry7 = (s7 + (1 << 20)) >> 21; 139 | s8 += carry7; 140 | s7 -= carry7 << 21; 141 | carry9 = (s9 + (1 << 20)) >> 21; 142 | s10 += carry9; 143 | s9 -= carry9 << 21; 144 | carry11 = (s11 + (1 << 20)) >> 21; 145 | s12 += carry11; 146 | s11 -= carry11 << 21; 147 | carry13 = (s13 + (1 << 20)) >> 21; 148 | s14 += carry13; 149 | s13 -= carry13 << 21; 150 | carry15 = (s15 + (1 << 20)) >> 21; 151 | s16 += carry15; 152 | s15 -= carry15 << 21; 153 | s5 += s17 * 666643; 154 | s6 += s17 * 470296; 155 | s7 += s17 * 654183; 156 | s8 -= s17 * 997805; 157 | s9 += s17 * 136657; 158 | s10 -= s17 * 683901; 159 | s17 = 0; 160 | s4 += s16 * 666643; 161 | s5 += s16 * 470296; 162 | s6 += s16 * 654183; 163 | s7 -= s16 * 997805; 164 | s8 += s16 * 136657; 165 | s9 -= s16 * 683901; 166 | s16 = 0; 167 | s3 += s15 * 666643; 168 | s4 += s15 * 470296; 169 | s5 += s15 * 654183; 170 | s6 -= s15 * 997805; 171 | s7 += s15 * 136657; 172 | s8 -= s15 * 683901; 173 | s15 = 0; 174 | s2 += s14 * 666643; 175 | s3 += s14 * 470296; 176 | s4 += s14 * 654183; 177 | s5 -= s14 * 997805; 178 | s6 += s14 * 136657; 179 | s7 -= s14 * 683901; 180 | s14 = 0; 181 | s1 += s13 * 666643; 182 | s2 += s13 * 470296; 183 | s3 += s13 * 654183; 184 | s4 -= s13 * 997805; 185 | s5 += s13 * 136657; 186 | s6 -= s13 * 683901; 187 | s13 = 0; 188 | s0 += s12 * 666643; 189 | s1 += s12 * 470296; 190 | s2 += s12 * 654183; 191 | s3 -= s12 * 997805; 192 | s4 += s12 * 136657; 193 | s5 -= s12 * 683901; 194 | s12 = 0; 195 | carry0 = (s0 + (1 << 20)) >> 21; 196 | s1 += carry0; 197 | s0 -= carry0 << 21; 198 | carry2 = (s2 + (1 << 20)) >> 21; 199 | s3 += carry2; 200 | s2 -= carry2 << 21; 201 | carry4 = (s4 + (1 << 20)) >> 21; 202 | s5 += carry4; 203 | s4 -= carry4 << 21; 204 | carry6 = (s6 + (1 << 20)) >> 21; 205 | s7 += carry6; 206 | s6 -= carry6 << 21; 207 | carry8 = (s8 + (1 << 20)) >> 21; 208 | s9 += carry8; 209 | s8 -= carry8 << 21; 210 | carry10 = (s10 + (1 << 20)) >> 21; 211 | s11 += carry10; 212 | s10 -= carry10 << 21; 213 | carry1 = (s1 + (1 << 20)) >> 21; 214 | s2 += carry1; 215 | s1 -= carry1 << 21; 216 | carry3 = (s3 + (1 << 20)) >> 21; 217 | s4 += carry3; 218 | s3 -= carry3 << 21; 219 | carry5 = (s5 + (1 << 20)) >> 21; 220 | s6 += carry5; 221 | s5 -= carry5 << 21; 222 | carry7 = (s7 + (1 << 20)) >> 21; 223 | s8 += carry7; 224 | s7 -= carry7 << 21; 225 | carry9 = (s9 + (1 << 20)) >> 21; 226 | s10 += carry9; 227 | s9 -= carry9 << 21; 228 | carry11 = (s11 + (1 << 20)) >> 21; 229 | s12 += carry11; 230 | s11 -= carry11 << 21; 231 | s0 += s12 * 666643; 232 | s1 += s12 * 470296; 233 | s2 += s12 * 654183; 234 | s3 -= s12 * 997805; 235 | s4 += s12 * 136657; 236 | s5 -= s12 * 683901; 237 | s12 = 0; 238 | carry0 = s0 >> 21; 239 | s1 += carry0; 240 | s0 -= carry0 << 21; 241 | carry1 = s1 >> 21; 242 | s2 += carry1; 243 | s1 -= carry1 << 21; 244 | carry2 = s2 >> 21; 245 | s3 += carry2; 246 | s2 -= carry2 << 21; 247 | carry3 = s3 >> 21; 248 | s4 += carry3; 249 | s3 -= carry3 << 21; 250 | carry4 = s4 >> 21; 251 | s5 += carry4; 252 | s4 -= carry4 << 21; 253 | carry5 = s5 >> 21; 254 | s6 += carry5; 255 | s5 -= carry5 << 21; 256 | carry6 = s6 >> 21; 257 | s7 += carry6; 258 | s6 -= carry6 << 21; 259 | carry7 = s7 >> 21; 260 | s8 += carry7; 261 | s7 -= carry7 << 21; 262 | carry8 = s8 >> 21; 263 | s9 += carry8; 264 | s8 -= carry8 << 21; 265 | carry9 = s9 >> 21; 266 | s10 += carry9; 267 | s9 -= carry9 << 21; 268 | carry10 = s10 >> 21; 269 | s11 += carry10; 270 | s10 -= carry10 << 21; 271 | carry11 = s11 >> 21; 272 | s12 += carry11; 273 | s11 -= carry11 << 21; 274 | s0 += s12 * 666643; 275 | s1 += s12 * 470296; 276 | s2 += s12 * 654183; 277 | s3 -= s12 * 997805; 278 | s4 += s12 * 136657; 279 | s5 -= s12 * 683901; 280 | s12 = 0; 281 | carry0 = s0 >> 21; 282 | s1 += carry0; 283 | s0 -= carry0 << 21; 284 | carry1 = s1 >> 21; 285 | s2 += carry1; 286 | s1 -= carry1 << 21; 287 | carry2 = s2 >> 21; 288 | s3 += carry2; 289 | s2 -= carry2 << 21; 290 | carry3 = s3 >> 21; 291 | s4 += carry3; 292 | s3 -= carry3 << 21; 293 | carry4 = s4 >> 21; 294 | s5 += carry4; 295 | s4 -= carry4 << 21; 296 | carry5 = s5 >> 21; 297 | s6 += carry5; 298 | s5 -= carry5 << 21; 299 | carry6 = s6 >> 21; 300 | s7 += carry6; 301 | s6 -= carry6 << 21; 302 | carry7 = s7 >> 21; 303 | s8 += carry7; 304 | s7 -= carry7 << 21; 305 | carry8 = s8 >> 21; 306 | s9 += carry8; 307 | s8 -= carry8 << 21; 308 | carry9 = s9 >> 21; 309 | s10 += carry9; 310 | s9 -= carry9 << 21; 311 | carry10 = s10 >> 21; 312 | s11 += carry10; 313 | s10 -= carry10 << 21; 314 | 315 | s[0] = (unsigned char) (s0 >> 0); 316 | s[1] = (unsigned char) (s0 >> 8); 317 | s[2] = (unsigned char) ((s0 >> 16) | (s1 << 5)); 318 | s[3] = (unsigned char) (s1 >> 3); 319 | s[4] = (unsigned char) (s1 >> 11); 320 | s[5] = (unsigned char) ((s1 >> 19) | (s2 << 2)); 321 | s[6] = (unsigned char) (s2 >> 6); 322 | s[7] = (unsigned char) ((s2 >> 14) | (s3 << 7)); 323 | s[8] = (unsigned char) (s3 >> 1); 324 | s[9] = (unsigned char) (s3 >> 9); 325 | s[10] = (unsigned char) ((s3 >> 17) | (s4 << 4)); 326 | s[11] = (unsigned char) (s4 >> 4); 327 | s[12] = (unsigned char) (s4 >> 12); 328 | s[13] = (unsigned char) ((s4 >> 20) | (s5 << 1)); 329 | s[14] = (unsigned char) (s5 >> 7); 330 | s[15] = (unsigned char) ((s5 >> 15) | (s6 << 6)); 331 | s[16] = (unsigned char) (s6 >> 2); 332 | s[17] = (unsigned char) (s6 >> 10); 333 | s[18] = (unsigned char) ((s6 >> 18) | (s7 << 3)); 334 | s[19] = (unsigned char) (s7 >> 5); 335 | s[20] = (unsigned char) (s7 >> 13); 336 | s[21] = (unsigned char) (s8 >> 0); 337 | s[22] = (unsigned char) (s8 >> 8); 338 | s[23] = (unsigned char) ((s8 >> 16) | (s9 << 5)); 339 | s[24] = (unsigned char) (s9 >> 3); 340 | s[25] = (unsigned char) (s9 >> 11); 341 | s[26] = (unsigned char) ((s9 >> 19) | (s10 << 2)); 342 | s[27] = (unsigned char) (s10 >> 6); 343 | s[28] = (unsigned char) ((s10 >> 14) | (s11 << 7)); 344 | s[29] = (unsigned char) (s11 >> 1); 345 | s[30] = (unsigned char) (s11 >> 9); 346 | s[31] = (unsigned char) (s11 >> 17); 347 | } 348 | 349 | 350 | 351 | /* 352 | Input: 353 | a[0]+256*a[1]+...+256^31*a[31] = a 354 | b[0]+256*b[1]+...+256^31*b[31] = b 355 | c[0]+256*c[1]+...+256^31*c[31] = c 356 | 357 | Output: 358 | s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l 359 | where l = 2^252 + 27742317777372353535851937790883648493. 360 | */ 361 | 362 | void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, const unsigned char *c) { 363 | int64_t a0 = 2097151 & load_3(a); 364 | int64_t a1 = 2097151 & (load_4(a + 2) >> 5); 365 | int64_t a2 = 2097151 & (load_3(a + 5) >> 2); 366 | int64_t a3 = 2097151 & (load_4(a + 7) >> 7); 367 | int64_t a4 = 2097151 & (load_4(a + 10) >> 4); 368 | int64_t a5 = 2097151 & (load_3(a + 13) >> 1); 369 | int64_t a6 = 2097151 & (load_4(a + 15) >> 6); 370 | int64_t a7 = 2097151 & (load_3(a + 18) >> 3); 371 | int64_t a8 = 2097151 & load_3(a + 21); 372 | int64_t a9 = 2097151 & (load_4(a + 23) >> 5); 373 | int64_t a10 = 2097151 & (load_3(a + 26) >> 2); 374 | int64_t a11 = (load_4(a + 28) >> 7); 375 | int64_t b0 = 2097151 & load_3(b); 376 | int64_t b1 = 2097151 & (load_4(b + 2) >> 5); 377 | int64_t b2 = 2097151 & (load_3(b + 5) >> 2); 378 | int64_t b3 = 2097151 & (load_4(b + 7) >> 7); 379 | int64_t b4 = 2097151 & (load_4(b + 10) >> 4); 380 | int64_t b5 = 2097151 & (load_3(b + 13) >> 1); 381 | int64_t b6 = 2097151 & (load_4(b + 15) >> 6); 382 | int64_t b7 = 2097151 & (load_3(b + 18) >> 3); 383 | int64_t b8 = 2097151 & load_3(b + 21); 384 | int64_t b9 = 2097151 & (load_4(b + 23) >> 5); 385 | int64_t b10 = 2097151 & (load_3(b + 26) >> 2); 386 | int64_t b11 = (load_4(b + 28) >> 7); 387 | int64_t c0 = 2097151 & load_3(c); 388 | int64_t c1 = 2097151 & (load_4(c + 2) >> 5); 389 | int64_t c2 = 2097151 & (load_3(c + 5) >> 2); 390 | int64_t c3 = 2097151 & (load_4(c + 7) >> 7); 391 | int64_t c4 = 2097151 & (load_4(c + 10) >> 4); 392 | int64_t c5 = 2097151 & (load_3(c + 13) >> 1); 393 | int64_t c6 = 2097151 & (load_4(c + 15) >> 6); 394 | int64_t c7 = 2097151 & (load_3(c + 18) >> 3); 395 | int64_t c8 = 2097151 & load_3(c + 21); 396 | int64_t c9 = 2097151 & (load_4(c + 23) >> 5); 397 | int64_t c10 = 2097151 & (load_3(c + 26) >> 2); 398 | int64_t c11 = (load_4(c + 28) >> 7); 399 | int64_t s0; 400 | int64_t s1; 401 | int64_t s2; 402 | int64_t s3; 403 | int64_t s4; 404 | int64_t s5; 405 | int64_t s6; 406 | int64_t s7; 407 | int64_t s8; 408 | int64_t s9; 409 | int64_t s10; 410 | int64_t s11; 411 | int64_t s12; 412 | int64_t s13; 413 | int64_t s14; 414 | int64_t s15; 415 | int64_t s16; 416 | int64_t s17; 417 | int64_t s18; 418 | int64_t s19; 419 | int64_t s20; 420 | int64_t s21; 421 | int64_t s22; 422 | int64_t s23; 423 | int64_t carry0; 424 | int64_t carry1; 425 | int64_t carry2; 426 | int64_t carry3; 427 | int64_t carry4; 428 | int64_t carry5; 429 | int64_t carry6; 430 | int64_t carry7; 431 | int64_t carry8; 432 | int64_t carry9; 433 | int64_t carry10; 434 | int64_t carry11; 435 | int64_t carry12; 436 | int64_t carry13; 437 | int64_t carry14; 438 | int64_t carry15; 439 | int64_t carry16; 440 | int64_t carry17; 441 | int64_t carry18; 442 | int64_t carry19; 443 | int64_t carry20; 444 | int64_t carry21; 445 | int64_t carry22; 446 | 447 | s0 = c0 + a0 * b0; 448 | s1 = c1 + a0 * b1 + a1 * b0; 449 | s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0; 450 | s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0; 451 | s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0; 452 | s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0; 453 | s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0; 454 | s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + a6 * b1 + a7 * b0; 455 | s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + a6 * b2 + a7 * b1 + a8 * b0; 456 | s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0; 457 | s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0; 458 | s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0; 459 | s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1; 460 | s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 + a9 * b4 + a10 * b3 + a11 * b2; 461 | s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 + a10 * b4 + a11 * b3; 462 | s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 + a11 * b4; 463 | s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5; 464 | s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6; 465 | s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7; 466 | s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8; 467 | s20 = a9 * b11 + a10 * b10 + a11 * b9; 468 | s21 = a10 * b11 + a11 * b10; 469 | s22 = a11 * b11; 470 | s23 = 0; 471 | carry0 = (s0 + (1 << 20)) >> 21; 472 | s1 += carry0; 473 | s0 -= carry0 << 21; 474 | carry2 = (s2 + (1 << 20)) >> 21; 475 | s3 += carry2; 476 | s2 -= carry2 << 21; 477 | carry4 = (s4 + (1 << 20)) >> 21; 478 | s5 += carry4; 479 | s4 -= carry4 << 21; 480 | carry6 = (s6 + (1 << 20)) >> 21; 481 | s7 += carry6; 482 | s6 -= carry6 << 21; 483 | carry8 = (s8 + (1 << 20)) >> 21; 484 | s9 += carry8; 485 | s8 -= carry8 << 21; 486 | carry10 = (s10 + (1 << 20)) >> 21; 487 | s11 += carry10; 488 | s10 -= carry10 << 21; 489 | carry12 = (s12 + (1 << 20)) >> 21; 490 | s13 += carry12; 491 | s12 -= carry12 << 21; 492 | carry14 = (s14 + (1 << 20)) >> 21; 493 | s15 += carry14; 494 | s14 -= carry14 << 21; 495 | carry16 = (s16 + (1 << 20)) >> 21; 496 | s17 += carry16; 497 | s16 -= carry16 << 21; 498 | carry18 = (s18 + (1 << 20)) >> 21; 499 | s19 += carry18; 500 | s18 -= carry18 << 21; 501 | carry20 = (s20 + (1 << 20)) >> 21; 502 | s21 += carry20; 503 | s20 -= carry20 << 21; 504 | carry22 = (s22 + (1 << 20)) >> 21; 505 | s23 += carry22; 506 | s22 -= carry22 << 21; 507 | carry1 = (s1 + (1 << 20)) >> 21; 508 | s2 += carry1; 509 | s1 -= carry1 << 21; 510 | carry3 = (s3 + (1 << 20)) >> 21; 511 | s4 += carry3; 512 | s3 -= carry3 << 21; 513 | carry5 = (s5 + (1 << 20)) >> 21; 514 | s6 += carry5; 515 | s5 -= carry5 << 21; 516 | carry7 = (s7 + (1 << 20)) >> 21; 517 | s8 += carry7; 518 | s7 -= carry7 << 21; 519 | carry9 = (s9 + (1 << 20)) >> 21; 520 | s10 += carry9; 521 | s9 -= carry9 << 21; 522 | carry11 = (s11 + (1 << 20)) >> 21; 523 | s12 += carry11; 524 | s11 -= carry11 << 21; 525 | carry13 = (s13 + (1 << 20)) >> 21; 526 | s14 += carry13; 527 | s13 -= carry13 << 21; 528 | carry15 = (s15 + (1 << 20)) >> 21; 529 | s16 += carry15; 530 | s15 -= carry15 << 21; 531 | carry17 = (s17 + (1 << 20)) >> 21; 532 | s18 += carry17; 533 | s17 -= carry17 << 21; 534 | carry19 = (s19 + (1 << 20)) >> 21; 535 | s20 += carry19; 536 | s19 -= carry19 << 21; 537 | carry21 = (s21 + (1 << 20)) >> 21; 538 | s22 += carry21; 539 | s21 -= carry21 << 21; 540 | s11 += s23 * 666643; 541 | s12 += s23 * 470296; 542 | s13 += s23 * 654183; 543 | s14 -= s23 * 997805; 544 | s15 += s23 * 136657; 545 | s16 -= s23 * 683901; 546 | s23 = 0; 547 | s10 += s22 * 666643; 548 | s11 += s22 * 470296; 549 | s12 += s22 * 654183; 550 | s13 -= s22 * 997805; 551 | s14 += s22 * 136657; 552 | s15 -= s22 * 683901; 553 | s22 = 0; 554 | s9 += s21 * 666643; 555 | s10 += s21 * 470296; 556 | s11 += s21 * 654183; 557 | s12 -= s21 * 997805; 558 | s13 += s21 * 136657; 559 | s14 -= s21 * 683901; 560 | s21 = 0; 561 | s8 += s20 * 666643; 562 | s9 += s20 * 470296; 563 | s10 += s20 * 654183; 564 | s11 -= s20 * 997805; 565 | s12 += s20 * 136657; 566 | s13 -= s20 * 683901; 567 | s20 = 0; 568 | s7 += s19 * 666643; 569 | s8 += s19 * 470296; 570 | s9 += s19 * 654183; 571 | s10 -= s19 * 997805; 572 | s11 += s19 * 136657; 573 | s12 -= s19 * 683901; 574 | s19 = 0; 575 | s6 += s18 * 666643; 576 | s7 += s18 * 470296; 577 | s8 += s18 * 654183; 578 | s9 -= s18 * 997805; 579 | s10 += s18 * 136657; 580 | s11 -= s18 * 683901; 581 | s18 = 0; 582 | carry6 = (s6 + (1 << 20)) >> 21; 583 | s7 += carry6; 584 | s6 -= carry6 << 21; 585 | carry8 = (s8 + (1 << 20)) >> 21; 586 | s9 += carry8; 587 | s8 -= carry8 << 21; 588 | carry10 = (s10 + (1 << 20)) >> 21; 589 | s11 += carry10; 590 | s10 -= carry10 << 21; 591 | carry12 = (s12 + (1 << 20)) >> 21; 592 | s13 += carry12; 593 | s12 -= carry12 << 21; 594 | carry14 = (s14 + (1 << 20)) >> 21; 595 | s15 += carry14; 596 | s14 -= carry14 << 21; 597 | carry16 = (s16 + (1 << 20)) >> 21; 598 | s17 += carry16; 599 | s16 -= carry16 << 21; 600 | carry7 = (s7 + (1 << 20)) >> 21; 601 | s8 += carry7; 602 | s7 -= carry7 << 21; 603 | carry9 = (s9 + (1 << 20)) >> 21; 604 | s10 += carry9; 605 | s9 -= carry9 << 21; 606 | carry11 = (s11 + (1 << 20)) >> 21; 607 | s12 += carry11; 608 | s11 -= carry11 << 21; 609 | carry13 = (s13 + (1 << 20)) >> 21; 610 | s14 += carry13; 611 | s13 -= carry13 << 21; 612 | carry15 = (s15 + (1 << 20)) >> 21; 613 | s16 += carry15; 614 | s15 -= carry15 << 21; 615 | s5 += s17 * 666643; 616 | s6 += s17 * 470296; 617 | s7 += s17 * 654183; 618 | s8 -= s17 * 997805; 619 | s9 += s17 * 136657; 620 | s10 -= s17 * 683901; 621 | s17 = 0; 622 | s4 += s16 * 666643; 623 | s5 += s16 * 470296; 624 | s6 += s16 * 654183; 625 | s7 -= s16 * 997805; 626 | s8 += s16 * 136657; 627 | s9 -= s16 * 683901; 628 | s16 = 0; 629 | s3 += s15 * 666643; 630 | s4 += s15 * 470296; 631 | s5 += s15 * 654183; 632 | s6 -= s15 * 997805; 633 | s7 += s15 * 136657; 634 | s8 -= s15 * 683901; 635 | s15 = 0; 636 | s2 += s14 * 666643; 637 | s3 += s14 * 470296; 638 | s4 += s14 * 654183; 639 | s5 -= s14 * 997805; 640 | s6 += s14 * 136657; 641 | s7 -= s14 * 683901; 642 | s14 = 0; 643 | s1 += s13 * 666643; 644 | s2 += s13 * 470296; 645 | s3 += s13 * 654183; 646 | s4 -= s13 * 997805; 647 | s5 += s13 * 136657; 648 | s6 -= s13 * 683901; 649 | s13 = 0; 650 | s0 += s12 * 666643; 651 | s1 += s12 * 470296; 652 | s2 += s12 * 654183; 653 | s3 -= s12 * 997805; 654 | s4 += s12 * 136657; 655 | s5 -= s12 * 683901; 656 | s12 = 0; 657 | carry0 = (s0 + (1 << 20)) >> 21; 658 | s1 += carry0; 659 | s0 -= carry0 << 21; 660 | carry2 = (s2 + (1 << 20)) >> 21; 661 | s3 += carry2; 662 | s2 -= carry2 << 21; 663 | carry4 = (s4 + (1 << 20)) >> 21; 664 | s5 += carry4; 665 | s4 -= carry4 << 21; 666 | carry6 = (s6 + (1 << 20)) >> 21; 667 | s7 += carry6; 668 | s6 -= carry6 << 21; 669 | carry8 = (s8 + (1 << 20)) >> 21; 670 | s9 += carry8; 671 | s8 -= carry8 << 21; 672 | carry10 = (s10 + (1 << 20)) >> 21; 673 | s11 += carry10; 674 | s10 -= carry10 << 21; 675 | carry1 = (s1 + (1 << 20)) >> 21; 676 | s2 += carry1; 677 | s1 -= carry1 << 21; 678 | carry3 = (s3 + (1 << 20)) >> 21; 679 | s4 += carry3; 680 | s3 -= carry3 << 21; 681 | carry5 = (s5 + (1 << 20)) >> 21; 682 | s6 += carry5; 683 | s5 -= carry5 << 21; 684 | carry7 = (s7 + (1 << 20)) >> 21; 685 | s8 += carry7; 686 | s7 -= carry7 << 21; 687 | carry9 = (s9 + (1 << 20)) >> 21; 688 | s10 += carry9; 689 | s9 -= carry9 << 21; 690 | carry11 = (s11 + (1 << 20)) >> 21; 691 | s12 += carry11; 692 | s11 -= carry11 << 21; 693 | s0 += s12 * 666643; 694 | s1 += s12 * 470296; 695 | s2 += s12 * 654183; 696 | s3 -= s12 * 997805; 697 | s4 += s12 * 136657; 698 | s5 -= s12 * 683901; 699 | s12 = 0; 700 | carry0 = s0 >> 21; 701 | s1 += carry0; 702 | s0 -= carry0 << 21; 703 | carry1 = s1 >> 21; 704 | s2 += carry1; 705 | s1 -= carry1 << 21; 706 | carry2 = s2 >> 21; 707 | s3 += carry2; 708 | s2 -= carry2 << 21; 709 | carry3 = s3 >> 21; 710 | s4 += carry3; 711 | s3 -= carry3 << 21; 712 | carry4 = s4 >> 21; 713 | s5 += carry4; 714 | s4 -= carry4 << 21; 715 | carry5 = s5 >> 21; 716 | s6 += carry5; 717 | s5 -= carry5 << 21; 718 | carry6 = s6 >> 21; 719 | s7 += carry6; 720 | s6 -= carry6 << 21; 721 | carry7 = s7 >> 21; 722 | s8 += carry7; 723 | s7 -= carry7 << 21; 724 | carry8 = s8 >> 21; 725 | s9 += carry8; 726 | s8 -= carry8 << 21; 727 | carry9 = s9 >> 21; 728 | s10 += carry9; 729 | s9 -= carry9 << 21; 730 | carry10 = s10 >> 21; 731 | s11 += carry10; 732 | s10 -= carry10 << 21; 733 | carry11 = s11 >> 21; 734 | s12 += carry11; 735 | s11 -= carry11 << 21; 736 | s0 += s12 * 666643; 737 | s1 += s12 * 470296; 738 | s2 += s12 * 654183; 739 | s3 -= s12 * 997805; 740 | s4 += s12 * 136657; 741 | s5 -= s12 * 683901; 742 | s12 = 0; 743 | carry0 = s0 >> 21; 744 | s1 += carry0; 745 | s0 -= carry0 << 21; 746 | carry1 = s1 >> 21; 747 | s2 += carry1; 748 | s1 -= carry1 << 21; 749 | carry2 = s2 >> 21; 750 | s3 += carry2; 751 | s2 -= carry2 << 21; 752 | carry3 = s3 >> 21; 753 | s4 += carry3; 754 | s3 -= carry3 << 21; 755 | carry4 = s4 >> 21; 756 | s5 += carry4; 757 | s4 -= carry4 << 21; 758 | carry5 = s5 >> 21; 759 | s6 += carry5; 760 | s5 -= carry5 << 21; 761 | carry6 = s6 >> 21; 762 | s7 += carry6; 763 | s6 -= carry6 << 21; 764 | carry7 = s7 >> 21; 765 | s8 += carry7; 766 | s7 -= carry7 << 21; 767 | carry8 = s8 >> 21; 768 | s9 += carry8; 769 | s8 -= carry8 << 21; 770 | carry9 = s9 >> 21; 771 | s10 += carry9; 772 | s9 -= carry9 << 21; 773 | carry10 = s10 >> 21; 774 | s11 += carry10; 775 | s10 -= carry10 << 21; 776 | 777 | s[0] = (unsigned char) (s0 >> 0); 778 | s[1] = (unsigned char) (s0 >> 8); 779 | s[2] = (unsigned char) ((s0 >> 16) | (s1 << 5)); 780 | s[3] = (unsigned char) (s1 >> 3); 781 | s[4] = (unsigned char) (s1 >> 11); 782 | s[5] = (unsigned char) ((s1 >> 19) | (s2 << 2)); 783 | s[6] = (unsigned char) (s2 >> 6); 784 | s[7] = (unsigned char) ((s2 >> 14) | (s3 << 7)); 785 | s[8] = (unsigned char) (s3 >> 1); 786 | s[9] = (unsigned char) (s3 >> 9); 787 | s[10] = (unsigned char) ((s3 >> 17) | (s4 << 4)); 788 | s[11] = (unsigned char) (s4 >> 4); 789 | s[12] = (unsigned char) (s4 >> 12); 790 | s[13] = (unsigned char) ((s4 >> 20) | (s5 << 1)); 791 | s[14] = (unsigned char) (s5 >> 7); 792 | s[15] = (unsigned char) ((s5 >> 15) | (s6 << 6)); 793 | s[16] = (unsigned char) (s6 >> 2); 794 | s[17] = (unsigned char) (s6 >> 10); 795 | s[18] = (unsigned char) ((s6 >> 18) | (s7 << 3)); 796 | s[19] = (unsigned char) (s7 >> 5); 797 | s[20] = (unsigned char) (s7 >> 13); 798 | s[21] = (unsigned char) (s8 >> 0); 799 | s[22] = (unsigned char) (s8 >> 8); 800 | s[23] = (unsigned char) ((s8 >> 16) | (s9 << 5)); 801 | s[24] = (unsigned char) (s9 >> 3); 802 | s[25] = (unsigned char) (s9 >> 11); 803 | s[26] = (unsigned char) ((s9 >> 19) | (s10 << 2)); 804 | s[27] = (unsigned char) (s10 >> 6); 805 | s[28] = (unsigned char) ((s10 >> 14) | (s11 << 7)); 806 | s[29] = (unsigned char) (s11 >> 1); 807 | s[30] = (unsigned char) (s11 >> 9); 808 | s[31] = (unsigned char) (s11 >> 17); 809 | } 810 | -------------------------------------------------------------------------------- /external/ed25519/src/seed.c: -------------------------------------------------------------------------------- 1 | #include "../include/ed25519.h" 2 | 3 | #ifndef ED25519_NO_SEED 4 | 5 | #ifdef _WIN32 6 | #include 7 | #include 8 | #else 9 | #include 10 | #endif 11 | 12 | int ed25519_create_seed(unsigned char *seed) { 13 | #ifdef _WIN32 14 | HCRYPTPROV prov; 15 | 16 | if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { 17 | return 1; 18 | } 19 | 20 | if (!CryptGenRandom(prov, 32, seed)) { 21 | CryptReleaseContext(prov, 0); 22 | return 1; 23 | } 24 | 25 | CryptReleaseContext(prov, 0); 26 | #else 27 | FILE *f = fopen("/dev/urandom", "rb"); 28 | 29 | if (f == NULL) { 30 | return 1; 31 | } 32 | 33 | fread(seed, 1, 32, f); 34 | fclose(f); 35 | #endif 36 | 37 | return 0; 38 | } 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /external/ed25519/src/sha512.c: -------------------------------------------------------------------------------- 1 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis 2 | * 3 | * LibTomCrypt is a library that provides various cryptographic 4 | * algorithms in a highly modular and flexible manner. 5 | * 6 | * The library is free for all purposes without any express 7 | * guarantee it works. 8 | * 9 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org 10 | */ 11 | 12 | #include "../include/fixedint.h" 13 | #include "../include/sha512.h" 14 | 15 | /* the K array */ 16 | static const uint64_t K[80] = { 17 | UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd), 18 | UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc), 19 | UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019), 20 | UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118), 21 | UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe), 22 | UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2), 23 | UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1), 24 | UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694), 25 | UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3), 26 | UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65), 27 | UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483), 28 | UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5), 29 | UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210), 30 | UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4), 31 | UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725), 32 | UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70), 33 | UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926), 34 | UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df), 35 | UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8), 36 | UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b), 37 | UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001), 38 | UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30), 39 | UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910), 40 | UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8), 41 | UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53), 42 | UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8), 43 | UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb), 44 | UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3), 45 | UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60), 46 | UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec), 47 | UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9), 48 | UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b), 49 | UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207), 50 | UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178), 51 | UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6), 52 | UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b), 53 | UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493), 54 | UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c), 55 | UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a), 56 | UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817) 57 | }; 58 | 59 | /* Various logical functions */ 60 | 61 | #define ROR64c(x, y) \ 62 | ( ((((x)&UINT64_C(0xFFFFFFFFFFFFFFFF))>>((uint64_t)(y)&UINT64_C(63))) | \ 63 | ((x)<<((uint64_t)(64-((y)&UINT64_C(63)))))) & UINT64_C(0xFFFFFFFFFFFFFFFF)) 64 | 65 | #define STORE64H(x, y) \ 66 | { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ 67 | (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ 68 | (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ 69 | (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } 70 | 71 | #define LOAD64H(x, y) \ 72 | { x = (((uint64_t)((y)[0] & 255))<<56)|(((uint64_t)((y)[1] & 255))<<48) | \ 73 | (((uint64_t)((y)[2] & 255))<<40)|(((uint64_t)((y)[3] & 255))<<32) | \ 74 | (((uint64_t)((y)[4] & 255))<<24)|(((uint64_t)((y)[5] & 255))<<16) | \ 75 | (((uint64_t)((y)[6] & 255))<<8)|(((uint64_t)((y)[7] & 255))); } 76 | 77 | 78 | #define Ch(x,y,z) (z ^ (x & (y ^ z))) 79 | #define Maj(x,y,z) (((x | y) & z) | (x & y)) 80 | #define S(x, n) ROR64c(x, n) 81 | #define R(x, n) (((x) &UINT64_C(0xFFFFFFFFFFFFFFFF))>>((uint64_t)n)) 82 | #define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39)) 83 | #define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41)) 84 | #define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7)) 85 | #define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6)) 86 | #ifndef MIN 87 | #define MIN(x, y) ( ((x)<(y))?(x):(y) ) 88 | #endif 89 | 90 | /* compress 1024-bits */ 91 | static int sha512_compress(sha512_context *md, unsigned char *buf) 92 | { 93 | uint64_t S[8], W[80], t0, t1; 94 | int i; 95 | 96 | /* copy state into S */ 97 | for (i = 0; i < 8; i++) { 98 | S[i] = md->state[i]; 99 | } 100 | 101 | /* copy the state into 1024-bits into W[0..15] */ 102 | for (i = 0; i < 16; i++) { 103 | LOAD64H(W[i], buf + (8*i)); 104 | } 105 | 106 | /* fill W[16..79] */ 107 | for (i = 16; i < 80; i++) { 108 | W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; 109 | } 110 | 111 | /* Compress */ 112 | #define RND(a,b,c,d,e,f,g,h,i) \ 113 | t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ 114 | t1 = Sigma0(a) + Maj(a, b, c);\ 115 | d += t0; \ 116 | h = t0 + t1; 117 | 118 | for (i = 0; i < 80; i += 8) { 119 | RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0); 120 | RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1); 121 | RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2); 122 | RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3); 123 | RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4); 124 | RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5); 125 | RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6); 126 | RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7); 127 | } 128 | 129 | #undef RND 130 | 131 | 132 | 133 | /* feedback */ 134 | for (i = 0; i < 8; i++) { 135 | md->state[i] = md->state[i] + S[i]; 136 | } 137 | 138 | return 0; 139 | } 140 | 141 | 142 | /** 143 | Initialize the hash state 144 | @param md The hash state you wish to initialize 145 | @return 0 if successful 146 | */ 147 | int sha512_init(sha512_context * md) { 148 | if (md == NULL) return 1; 149 | 150 | md->curlen = 0; 151 | md->length = 0; 152 | md->state[0] = UINT64_C(0x6a09e667f3bcc908); 153 | md->state[1] = UINT64_C(0xbb67ae8584caa73b); 154 | md->state[2] = UINT64_C(0x3c6ef372fe94f82b); 155 | md->state[3] = UINT64_C(0xa54ff53a5f1d36f1); 156 | md->state[4] = UINT64_C(0x510e527fade682d1); 157 | md->state[5] = UINT64_C(0x9b05688c2b3e6c1f); 158 | md->state[6] = UINT64_C(0x1f83d9abfb41bd6b); 159 | md->state[7] = UINT64_C(0x5be0cd19137e2179); 160 | 161 | return 0; 162 | } 163 | 164 | /** 165 | Process a block of memory though the hash 166 | @param md The hash state 167 | @param in The data to hash 168 | @param inlen The length of the data (octets) 169 | @return 0 if successful 170 | */ 171 | int sha512_update (sha512_context * md, const unsigned char *in, size_t inlen) 172 | { 173 | size_t n; 174 | size_t i; 175 | int err; 176 | if (md == NULL) return 1; 177 | if (in == NULL) return 1; 178 | if (md->curlen > sizeof(md->buf)) { 179 | return 1; 180 | } 181 | while (inlen > 0) { 182 | if (md->curlen == 0 && inlen >= 128) { 183 | if ((err = sha512_compress (md, (unsigned char *)in)) != 0) { 184 | return err; 185 | } 186 | md->length += 128 * 8; 187 | in += 128; 188 | inlen -= 128; 189 | } else { 190 | n = MIN(inlen, (128 - md->curlen)); 191 | 192 | for (i = 0; i < n; i++) { 193 | md->buf[i + md->curlen] = in[i]; 194 | } 195 | 196 | 197 | md->curlen += n; 198 | in += n; 199 | inlen -= n; 200 | if (md->curlen == 128) { 201 | if ((err = sha512_compress (md, md->buf)) != 0) { 202 | return err; 203 | } 204 | md->length += 8*128; 205 | md->curlen = 0; 206 | } 207 | } 208 | } 209 | return 0; 210 | } 211 | 212 | /** 213 | Terminate the hash to get the digest 214 | @param md The hash state 215 | @param out [out] The destination of the hash (64 bytes) 216 | @return 0 if successful 217 | */ 218 | int sha512_final(sha512_context * md, unsigned char *out) 219 | { 220 | int i; 221 | 222 | if (md == NULL) return 1; 223 | if (out == NULL) return 1; 224 | 225 | if (md->curlen >= sizeof(md->buf)) { 226 | return 1; 227 | } 228 | 229 | /* increase the length of the message */ 230 | md->length += md->curlen * UINT64_C(8); 231 | 232 | /* append the '1' bit */ 233 | md->buf[md->curlen++] = (unsigned char)0x80; 234 | 235 | /* if the length is currently above 112 bytes we append zeros 236 | * then compress. Then we can fall back to padding zeros and length 237 | * encoding like normal. 238 | */ 239 | if (md->curlen > 112) { 240 | while (md->curlen < 128) { 241 | md->buf[md->curlen++] = (unsigned char)0; 242 | } 243 | sha512_compress(md, md->buf); 244 | md->curlen = 0; 245 | } 246 | 247 | /* pad upto 120 bytes of zeroes 248 | * note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash 249 | * > 2^64 bits of data... :-) 250 | */ 251 | while (md->curlen < 120) { 252 | md->buf[md->curlen++] = (unsigned char)0; 253 | } 254 | 255 | /* store length */ 256 | STORE64H(md->length, md->buf+120); 257 | sha512_compress(md, md->buf); 258 | 259 | /* copy output */ 260 | for (i = 0; i < 8; i++) { 261 | STORE64H(md->state[i], out+(8*i)); 262 | } 263 | 264 | return 0; 265 | } 266 | 267 | int sha512(const unsigned char *message, size_t message_len, unsigned char *out) 268 | { 269 | sha512_context ctx; 270 | int ret; 271 | if ((ret = sha512_init(&ctx))) return ret; 272 | if ((ret = sha512_update(&ctx, message, message_len))) return ret; 273 | if ((ret = sha512_final(&ctx, out))) return ret; 274 | return 0; 275 | } 276 | -------------------------------------------------------------------------------- /external/ed25519/src/sign.c: -------------------------------------------------------------------------------- 1 | #include "../include/ed25519.h" 2 | #include "../include/sha512.h" 3 | #include "../include/ge.h" 4 | #include "../include/sc.h" 5 | 6 | 7 | void ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key) { 8 | sha512_context hash; 9 | unsigned char hram[64]; 10 | unsigned char r[64]; 11 | ge_p3 R; 12 | 13 | 14 | sha512_init(&hash); 15 | sha512_update(&hash, private_key + 32, 32); 16 | sha512_update(&hash, message, message_len); 17 | sha512_final(&hash, r); 18 | 19 | sc_reduce(r); 20 | ge_scalarmult_base(&R, r); 21 | ge_p3_tobytes(signature, &R); 22 | 23 | sha512_init(&hash); 24 | sha512_update(&hash, signature, 32); 25 | sha512_update(&hash, public_key, 32); 26 | sha512_update(&hash, message, message_len); 27 | sha512_final(&hash, hram); 28 | 29 | sc_reduce(hram); 30 | sc_muladd(signature + 32, hram, private_key, r); 31 | } 32 | -------------------------------------------------------------------------------- /external/ed25519/src/verify.c: -------------------------------------------------------------------------------- 1 | #include "../include/ed25519.h" 2 | #include "../include/sha512.h" 3 | #include "../include/ge.h" 4 | #include "../include/sc.h" 5 | 6 | static int consttime_equal(const unsigned char *x, const unsigned char *y) { 7 | unsigned char r = 0; 8 | 9 | r = x[0] ^ y[0]; 10 | #define F(i) r |= x[i] ^ y[i] 11 | F(1); 12 | F(2); 13 | F(3); 14 | F(4); 15 | F(5); 16 | F(6); 17 | F(7); 18 | F(8); 19 | F(9); 20 | F(10); 21 | F(11); 22 | F(12); 23 | F(13); 24 | F(14); 25 | F(15); 26 | F(16); 27 | F(17); 28 | F(18); 29 | F(19); 30 | F(20); 31 | F(21); 32 | F(22); 33 | F(23); 34 | F(24); 35 | F(25); 36 | F(26); 37 | F(27); 38 | F(28); 39 | F(29); 40 | F(30); 41 | F(31); 42 | #undef F 43 | 44 | return !r; 45 | } 46 | 47 | int ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key) { 48 | unsigned char h[64]; 49 | unsigned char checker[32]; 50 | sha512_context hash; 51 | ge_p3 A; 52 | ge_p2 R; 53 | 54 | if (signature[63] & 224) { 55 | return 0; 56 | } 57 | 58 | if (ge_frombytes_negate_vartime(&A, public_key) != 0) { 59 | return 0; 60 | } 61 | 62 | sha512_init(&hash); 63 | sha512_update(&hash, signature, 32); 64 | sha512_update(&hash, public_key, 32); 65 | sha512_update(&hash, message, message_len); 66 | sha512_final(&hash, h); 67 | 68 | sc_reduce(h); 69 | ge_double_scalarmult_vartime(&R, h, &A, signature + 32); 70 | ge_tobytes(checker, &R); 71 | 72 | if (!consttime_equal(checker, signature)) { 73 | return 0; 74 | } 75 | 76 | return 1; 77 | } 78 | -------------------------------------------------------------------------------- /include/ed25519.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by denn on 2019-01-29. 3 | // 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "ed25519/c++17/variant.hpp" 19 | 20 | #define UNUSED(x) (void)(x) 21 | 22 | namespace ed25519 { 23 | 24 | using namespace mpark; 25 | 26 | /** 27 | * Common error handling closure. 28 | * */ 29 | typedef std::function ErrorHandler; 30 | 31 | /** 32 | * Default error handler 33 | */ 34 | static auto default_error_handler = [](const std::error_code &code) {UNUSED(code);}; 35 | 36 | /** 37 | * Base58 string to/from encoding/decoding 38 | * */ 39 | 40 | namespace size { 41 | constexpr const size_t hash = 32; 42 | constexpr const size_t double_hash = hash*2; 43 | 44 | constexpr const size_t public_key = hash; 45 | constexpr const size_t digest = hash; 46 | constexpr const size_t seed = hash; 47 | 48 | constexpr const size_t private_key = double_hash; 49 | constexpr const size_t signature = double_hash; 50 | } 51 | 52 | enum error:int { 53 | BADFORMAT = 1000, 54 | UNEXPECTED_SIZE = 1001, 55 | EMPTY = 1002, 56 | }; 57 | 58 | class error_category: public std::error_category 59 | { 60 | public: 61 | error_category(const std::string &message); 62 | error_category():mess_(""){}; 63 | const char* name() const noexcept override; 64 | std::string message(int ev) const override; 65 | 66 | private: 67 | std::string mess_; 68 | }; 69 | 70 | namespace base58 { 71 | 72 | uint_least32_t crc32(unsigned char *buf, size_t len); 73 | 74 | /** 75 | * Encode binary data to base58 string 76 | * @param data - encode data 77 | * @return base58 string 78 | */ 79 | std::string encode(const std::vector& data); 80 | 81 | /** 82 | * Decode base58-encoded string to binary data 83 | * @param str encoded string 84 | * @param data binary crypted data 85 | * @return false if decoding is failed 86 | */ 87 | bool decode(const std::string& str, std::vector& data); 88 | 89 | /** 90 | * Validate base58-encoded string 91 | * @param str encoded string 92 | * @return false if decoding is failed 93 | */ 94 | bool validate(const std::string &str); 95 | 96 | /** 97 | * Decode base58 string to binary format 98 | * @param base58 -encoded string 99 | * @param error error handler 100 | * @return binary buffer 101 | */ 102 | template 103 | bool decode( 104 | const std::string &base58, 105 | std::array &data, 106 | const ErrorHandler &error = default_error_handler){ 107 | 108 | std::vector v; 109 | 110 | if (!decode(base58.c_str(), v)) 111 | { 112 | std::error_code ec(static_cast(error::BADFORMAT),error_category()); 113 | error(ec); 114 | 115 | return false; 116 | } 117 | 118 | if (v.size() != N) 119 | { 120 | std::stringstream errorMessage; 121 | errorMessage << "size of decoded vector is not equal to expected size: " << v.size() << " <> " << N; 122 | std::error_code ec(static_cast(error::UNEXPECTED_SIZE),error_category(errorMessage.str())); 123 | error(ec); 124 | 125 | return false; 126 | } 127 | 128 | std::copy_n(v.begin(), N, data.begin()); 129 | 130 | return true; 131 | } 132 | 133 | /** 134 | * Encode binary data to base58 string 135 | * @tparam N - size of data 136 | * @param data decoded data 137 | * @return base58-encoded string 138 | */ 139 | template 140 | std::string encode( 141 | const std::array &data) { 142 | 143 | // add 4-byte hash check to the end 144 | 145 | std::vector vch; 146 | vch.assign(data.begin(), data.end()); 147 | 148 | uint_least32_t crc32_ = crc32(&vch[0], vch.size()); 149 | 150 | // little endian 151 | vch.push_back(static_cast(crc32_ & 0xff)); 152 | vch.push_back(static_cast((crc32_ >> 8) & 0xff)); 153 | vch.push_back(static_cast((crc32_ >> 16) & 0xff)); 154 | vch.push_back(static_cast((crc32_ >> 24) & 0xff)); 155 | 156 | return encode(vch); 157 | } 158 | } 159 | 160 | /** 161 | * Common base58 encoding/decoding protocol 162 | * */ 163 | class Base58 { 164 | public: 165 | 166 | /** 167 | * Encode key data to base58 string 168 | * @return encoded base58 string 169 | */ 170 | virtual std::string encode() const = 0; 171 | 172 | /** 173 | * 174 | * Decode string from base58 string 175 | * 176 | * @param base58_string - encoded string 177 | * @param error - handle error if key couldn't ber read from string 178 | * @return true or false 179 | */ 180 | virtual bool decode(const std::string &base58_string, const ErrorHandler &error = default_error_handler) = 0; 181 | 182 | /** 183 | * Validate base58 string without creating object instance 184 | * @return true if string is base58 encoded 185 | */ 186 | virtual bool validate() const = 0; 187 | 188 | virtual ~Base58() = default; 189 | }; 190 | 191 | namespace keys { 192 | class Public; 193 | class Pair; 194 | } 195 | 196 | class Digest; 197 | 198 | /** 199 | * Base58 binary data structure 200 | * @tparam N - size of encoded data 201 | */ 202 | template 203 | class Data: public std::array, public Base58 { 204 | typedef std::array binary_data; 205 | 206 | public: 207 | using binary_data::binary_data; 208 | 209 | /** 210 | * Restore data from base58-encoded string 211 | * @param base58 encoded signature 212 | * @param error handler 213 | * @return nullopt or new data hash object 214 | */ 215 | inline static std::optional> Decode(const std::string &base58, const ErrorHandler &error = default_error_handler) { 216 | auto s = Data(); 217 | if (s.decode(base58,error)){ 218 | return std::make_optional(s); 219 | } 220 | return std::nullopt; 221 | } 222 | 223 | Data():binary_data() { clean(); } 224 | 225 | /** 226 | * Clean data memory 227 | */ 228 | void clean() { binary_data::fill(0); } 229 | 230 | /** 231 | * Encode from binary to base58 encoded string 232 | * @return encoded string 233 | */ 234 | [[nodiscard]] std::string encode() const override { 235 | return base58::encode(*this); 236 | } 237 | 238 | /** 239 | * Decode base58 encoded string to binary represenation 240 | * @param base58 encoded string 241 | * @param error - error handler 242 | * @return false if decoding is failed 243 | */ 244 | bool decode(const std::string &base58, const ErrorHandler &error = default_error_handler) override { 245 | return base58::decode(base58, *this, error); 246 | } 247 | 248 | bool validate() const override { 249 | if (N == this->size()) { 250 | 251 | if (encode().empty()) 252 | return false; 253 | 254 | return base58::validate(encode()); 255 | } 256 | else { 257 | return false; 258 | } 259 | } 260 | 261 | /** 262 | * Validate string before create encoded data. 263 | * @param string base58-encoded string 264 | * @return validation result 265 | */ 266 | static bool validate(const std::string &string) { 267 | return base58::validate(string); 268 | } 269 | }; 270 | 271 | 272 | template 273 | class ProtectedData: public Data { 274 | public: 275 | inline const unsigned char* data() const { return Data::data();}; 276 | protected: 277 | inline unsigned char* data() { return Data::data();}; 278 | bool decode(const std::string &base58, const ErrorHandler &error = default_error_handler) override { 279 | return Data::decode(base58, error); 280 | } 281 | friend class keys::Pair; 282 | }; 283 | 284 | /** 285 | * Digest hash class 286 | */ 287 | class Digest :public Data{ 288 | public: 289 | 290 | struct Calculator{ 291 | 292 | enum endian { 293 | little = 0, 294 | big = 1 295 | }; 296 | 297 | typedef variant< 298 | bool, 299 | unsigned char, 300 | short int, 301 | int, 302 | std::string, 303 | std::vector, 304 | Data, 305 | Data 306 | > variant_t; 307 | 308 | virtual void append(const variant_t &value) = 0; 309 | virtual void set_endian(endian) = 0; 310 | virtual endian get_endian() = 0; 311 | 312 | friend class keys::Pair; 313 | }; 314 | 315 | typedef std::function context; 316 | 317 | friend struct Digest::Calculator; 318 | friend class keys::Public; 319 | /** 320 | * Create new digest from variant types 321 | * @param handler - calculator handler 322 | */ 323 | explicit Digest(const context& handler); 324 | 325 | Digest(); 326 | 327 | /** 328 | * Restore digest from base58-encoded string 329 | * @param base58 encoded signature 330 | * @param error handler 331 | * @return nullopt or new digest hash object 332 | */ 333 | static std::optional Decode(const std::string &base58, const ErrorHandler &error = default_error_handler); 334 | }; 335 | 336 | 337 | /** 338 | * Sigature hash class 339 | */ 340 | class Signature : public ProtectedData { 341 | public: 342 | 343 | /** 344 | * Restore signature from base58-encoded string 345 | * @param base58 encoded signature 346 | * @param error handler 347 | * @return nullopt or new signature hash object 348 | */ 349 | static std::optional Decode(const std::string &base58, const ErrorHandler &error = default_error_handler); 350 | 351 | /** 352 | * Verify message with public key 353 | * @param message data 354 | * @param key public key 355 | * @return true if message was signed by private key of the pair 356 | */ 357 | [[nodiscard]] bool verify(const std::vector& message, const keys::Public& key) const ; 358 | 359 | /** 360 | * Verify message with public key 361 | * @param message string 362 | * @param key public key 363 | * @return true if message was signed by private key of the pair 364 | */ 365 | [[nodiscard]] bool verify(const std::string& message, const keys::Public& key) const ; 366 | 367 | /** 368 | * Verify message with public key 369 | * @param digest data 370 | * @param key public key 371 | * @return true if message was signed by private key of the pair 372 | */ 373 | [[nodiscard]] bool verify(const Digest& digest, const keys::Public& key) const ; 374 | 375 | virtual ~Signature() = default; 376 | 377 | protected: 378 | Signature():ProtectedData(){}; 379 | friend class keys::Pair; 380 | }; 381 | 382 | /** 383 | * Seed generator 384 | */ 385 | class Seed: public Data{ 386 | 387 | typedef Data seed_data; 388 | 389 | public: 390 | using seed_data::seed_data; 391 | 392 | /** 393 | * Create seed from secret phrase 394 | * @param phrase secret phrase string 395 | */ 396 | explicit Seed(const std::string &phrase); 397 | 398 | /** 399 | * Create random seed 400 | */ 401 | Seed(); 402 | }; 403 | namespace keys { 404 | 405 | template 406 | class Key: public ProtectedData {}; 407 | 408 | /** 409 | * Public key representaion 410 | */ 411 | class Public: public Key{ 412 | public: 413 | static std::optional Decode(const std::string &base58, const ErrorHandler &error = default_error_handler); 414 | }; 415 | 416 | /** 417 | * Private key representation 418 | */ 419 | class Private: public Key{ 420 | public: 421 | static std::optional Decode(const std::string &base58, const ErrorHandler &error = default_error_handler); 422 | private: 423 | bool decode(const std::string &base58, const ErrorHandler &error = default_error_handler) override { 424 | return Data::decode(base58, error); 425 | } 426 | friend class keys::Pair; 427 | }; 428 | 429 | /** 430 | * Pair key representation 431 | */ 432 | class Pair { 433 | 434 | public: 435 | /** 436 | * Get paired public key for the private 437 | * @return copy of public key 438 | */ 439 | [[nodiscard]] const Public &get_public_key() const { return publicKey_; }; 440 | [[nodiscard]] const Private &get_private_key() const { return privateKey_; }; 441 | 442 | /** 443 | * Create random pair 444 | * @return always exists private key 445 | */ 446 | static std::optional Random(); 447 | 448 | /** 449 | * Create random pair 450 | * @return always exists private key 451 | */ 452 | static std::optional FromPrivateKey(const std::string &privateKey, const ErrorHandler &error = default_error_handler); 453 | 454 | /** 455 | * Optional constructor from secret phrase 456 | * @param phrase secret phrase string 457 | * @param error error handler 458 | * @return nullopt or private key 459 | */ 460 | static std::optional WithSecret(const std::string &phrase, 461 | const ErrorHandler &error = default_error_handler); 462 | 463 | /** 464 | * Clean pair 465 | */ 466 | void clean(); 467 | 468 | /** 469 | * Vlidate pair 470 | * @return validation result 471 | */ 472 | bool validate(); 473 | 474 | /** 475 | * Sign a message 476 | * @param message data 477 | * @return signature hash 478 | */ 479 | std::unique_ptr sign(const std::vector& message); 480 | 481 | /** 482 | * Sign a message 483 | * @param message string 484 | * @return signature hash 485 | */ 486 | std::unique_ptr sign(const std::string &message); 487 | 488 | /** 489 | * Sign a digest 490 | * @param digest data 491 | * @return signature hash 492 | */ 493 | std::unique_ptr sign(const Digest& digest); 494 | 495 | ~Pair() { 496 | clean(); 497 | } 498 | 499 | private: 500 | Pair(); 501 | Public publicKey_; 502 | Private privateKey_; 503 | }; 504 | } 505 | 506 | std::string StringFormat(const char* format, ...); 507 | } 508 | -------------------------------------------------------------------------------- /lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories( 2 | ../include 3 | ../external/ed25519/include 4 | ../ 5 | ../src/ 6 | ../src/external 7 | ) 8 | 9 | FILE(GLOB PUBLIC_INCLUDE_FILES 10 | ../include/*.hpp 11 | ) 12 | 13 | list(FILTER ${PUBLIC_INCLUDE_FILES} EXCLUDE REGEX "gtest") 14 | 15 | 16 | FILE(GLOB PUBLIC_INCLUDE_CPP17_FILES 17 | ../include/ed25519/c++17/*.hpp 18 | ) 19 | 20 | FILE(GLOB INCLUDE_FILES 21 | ${PUBLIC_INCLUDE_FILES} 22 | ) 23 | 24 | FILE(GLOB SOURCES 25 | ../src/*.cpp 26 | ../src/external/*.cpp 27 | ../external/ed25519/src/*.c 28 | ) 29 | 30 | add_library(${PROJECT_LIB} ${SOURCES}) 31 | 32 | target_link_libraries ( 33 | ${PROJECT_LIB} PUBLIC 34 | ${Boost_LIBRARIES} 35 | ) 36 | 37 | target_include_directories( 38 | ${PROJECT_LIB} 39 | PUBLIC 40 | ../include 41 | ) 42 | 43 | set(config_install_dir "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") 44 | set(generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated") 45 | 46 | # Configuration 47 | set(version_config "${generated_dir}/${PROJECT_NAME}ConfigVersion.cmake") 48 | set(project_config "${generated_dir}/${PROJECT_NAME}Config.cmake") 49 | set(TARGETS_EXPORT_NAME "${PROJECT_NAME}") 50 | set(namespace "${PROJECT_NAME}::") 51 | 52 | include(CMakePackageConfigHelpers) 53 | 54 | write_basic_package_version_file( 55 | "${version_config}" COMPATIBILITY SameMajorVersion 56 | ) 57 | 58 | configure_package_config_file( 59 | "cmake/Config.cmake.in" 60 | "${project_config}" 61 | INSTALL_DESTINATION "${config_install_dir}" 62 | ) 63 | 64 | install(TARGETS ${PROJECT_LIB} 65 | DESTINATION lib 66 | ) 67 | install(FILES ${PUBLIC_INCLUDE_FILES} 68 | DESTINATION include 69 | ) 70 | install(FILES ${PUBLIC_INCLUDE_CPP17_FILES} DESTINATION include/ed25519/c++17) 71 | install(FILES ${project_config} ${version_config} DESTINATION lib/cmake/${PROJECT_LIB}) 72 | install(FILES cmake/${PROJECT_LIB}.cmake DESTINATION lib/cmake/${PROJECT_LIB}) -------------------------------------------------------------------------------- /lib/cmake/Config.cmake.in: -------------------------------------------------------------------------------- 1 | @PACKAGE_INIT@ 2 | 3 | set(@PROJECT_NAME@_INCLUDE_PATH @CMAKE_INSTALL_PREFIX@/include) 4 | include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake") 5 | check_required_components("@PROJECT_NAME@") 6 | -------------------------------------------------------------------------------- /lib/cmake/ed25519cpp.cmake: -------------------------------------------------------------------------------- 1 | add_library(${PROJECT_LIB} STATIC IMPORTED) 2 | 3 | 4 | find_library(${PROJECT_LIB}_LIBRARY_PATH ${PROJECT_LIB} HINTS "${CMAKE_CURRENT_LIST_DIR}/../../") 5 | set_target_properties(${PROJECT_LIB} PROPERTIES IMPORTED_LOCATION "${ed25519cpp_LIBRARY_PATH}") 6 | 7 | include_directories( 8 | "${ed25519cpp_INCLUDE_PATH}" 9 | ) 10 | 11 | message(STATUS "CMAKE_CURRENT_LIST_DIR" ${CMAKE_CURRENT_LIST_DIR}) 12 | message(STATUS "CMAKE_INSTALL_PREFIX " ${CMAKE_INSTALL_PREFIX}) 13 | message(STATUS "milecsa_LIBRARY_PATH " ${ed25519cpp_LIB_LIBRARY_PATH}) 14 | message(STATUS "milecsa_INCLUDE_PATH " ${ed25519cpp_LIB_INCLUDE_PATH}) 15 | -------------------------------------------------------------------------------- /platforms/swift/sdk/Classes/ed25519_wrapper.h: -------------------------------------------------------------------------------- 1 | // 2 | // MileWalletBridge.h 3 | // mile-ios-sdk 4 | // 5 | // Created by denis svinarchuk on 18.06.2018. 6 | // Copyright © 2018 Mile Core. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #define NSEd25519ErrorDomain @"NSEd25519ErrorDomain" 12 | 13 | @protocol ProtectedBase58 14 | - (_Nullable instancetype) initWithBase58:(nonnull NSString *)base58 error:(NSError * _Nullable*_Nullable)error; 15 | - (nonnull NSString *) encode; 16 | @end 17 | 18 | @protocol Base58 19 | - (BOOL) decode:(nonnull NSString *)base58 error:(NSError * _Nullable*_Nullable)error; 20 | @end 21 | 22 | @interface Seed : NSObject 23 | - (nonnull instancetype) initWithSecret:(nonnull NSString *)phrase; 24 | - (nonnull instancetype) init; 25 | @end 26 | 27 | @interface PublicKey : NSObject 28 | @end 29 | 30 | @interface PrivateKey : NSObject 31 | @end 32 | 33 | @interface Digest : NSObject 34 | @end 35 | 36 | @interface DigestCalculator : NSObject 37 | - (nonnull instancetype) appendBool:(bool)value; 38 | - (nonnull instancetype) appendUInt8:(uint8)value; 39 | - (nonnull instancetype) appendInt16:(int16_t)value; 40 | - (nonnull instancetype) appendPublicKey:(PublicKey *_Nonnull)value; 41 | - (nonnull instancetype) appendPrivateKey:(PrivateKey *_Nonnull)value; 42 | - (nonnull instancetype) appendSeed:(Seed *_Nonnull)value; 43 | - (nonnull instancetype) appendDigest:(Digest *_Nonnull)value; 44 | - (nonnull instancetype) appendInteger:(NSInteger)value; 45 | - (nonnull instancetype) appendString:(NSString * _Nonnull )value; 46 | @end 47 | 48 | typedef void (^DigestCalculatorType)(DigestCalculator*_Nonnull); 49 | 50 | @interface Digest() 51 | - (nonnull instancetype) initWithCalculator:(DigestCalculatorType _Nonnull )calculator; 52 | @end 53 | 54 | @interface Signature : NSObject 55 | - (BOOL) verifyWithPublic:(nonnull PublicKey*)publicKey message:(nonnull NSData *)message ; 56 | - (BOOL) verifyWithPublic:(nonnull PublicKey*)publicKey string:(nonnull NSString *)string ; 57 | - (BOOL) verifyWithPublic:(nonnull PublicKey*)publicKey digest:(nonnull Digest *)digest ; 58 | @end 59 | 60 | @interface Pair: NSObject 61 | 62 | @property (readonly,atomic) PublicKey * _Nonnull publicKey; 63 | @property (readonly,atomic) PrivateKey * _Nonnull privateKey; 64 | 65 | /** 66 | * Create new wallet pair: public and private keys 67 | * 68 | * @return wallet pair keys 69 | */ 70 | +(nonnull instancetype)Random; 71 | 72 | /** 73 | * Create new wallet pair with as secret phrase 74 | * 75 | * @param phrase - secret phrase 76 | * @param error - handle error if pair could not be created 77 | * @return wallet pair keys 78 | */ 79 | - (nullable instancetype)initWithSecretPhrase:(nonnull NSString*)phrase 80 | error:(NSError *_Null_unspecified __autoreleasing *_Null_unspecified)error; 81 | 82 | 83 | /** 84 | * Restore wallet pair from private key 85 | * 86 | * @param privateKey - wallet private key 87 | * @param error - handle error if pair could not be created 88 | * @return wallet pair keys 89 | */ 90 | - (nullable instancetype)initFromPrivateKey:(nonnull NSString*)privateKey 91 | error:(NSError *_Null_unspecified __autoreleasing *_Null_unspecified)error; 92 | 93 | - (nonnull Signature*) signMessage:(nonnull NSData*)message; 94 | - (nonnull Signature*) signString:(nonnull NSString*)string; 95 | - (nonnull Signature*) signDigest:(nonnull Digest*)digest; 96 | @end 97 | -------------------------------------------------------------------------------- /platforms/swift/sdk/Classes/ed25519_wrapper.mm: -------------------------------------------------------------------------------- 1 | // 2 | // MileWalletBridge.m 3 | // mile-ios-sdk 4 | // 5 | // Created by denis svinarchuk on 18.06.2018. 6 | // Copyright © 2018 Mile Core. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #import "ed25519_wrapper.h" 14 | 15 | @interface DigestCalculator() 16 | - (instancetype) initWithC:(ed25519::Digest::Calculator *)c; 17 | @end 18 | 19 | @interface PublicKey () 20 | - (std::optional) data; 21 | - (instancetype) initWithKey:(std::optional) key; 22 | @end 23 | 24 | @interface PrivateKey () 25 | - (std::optional) data; 26 | - (instancetype) initWithKey:(std::optional) key; 27 | @end 28 | 29 | @interface Seed () 30 | - (std::optional) data; 31 | @end 32 | 33 | @interface Digest () 34 | - (std::optional) data; 35 | @end 36 | 37 | @interface Signature () 38 | - (instancetype) initWithSignature:(std::optional) signature; 39 | @end 40 | 41 | inline NSError *error2NSError(const std::error_code &code){ 42 | 43 | NSDictionary *userInfo = @{ 44 | NSLocalizedDescriptionKey: NSLocalizedString([NSString stringWithUTF8String:code.message().c_str()], nil), 45 | NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"ed25512 error", nil) 46 | }; 47 | 48 | return [NSError errorWithDomain:NSEd25519ErrorDomain code:(NSInteger)(code.value()) 49 | userInfo:userInfo]; 50 | } 51 | 52 | 53 | @implementation Seed 54 | { 55 | ed25519::Seed* seed; 56 | } 57 | 58 | - (void)dealloc 59 | { 60 | delete seed; 61 | } 62 | 63 | - (std::optional) data { 64 | return *seed; 65 | } 66 | 67 | - (_Nullable instancetype) initWithBase58:(nonnull NSString *)base58 error:(NSError * _Nullable*_Nullable)error { 68 | self = [[Seed alloc] init]; 69 | if (self){ 70 | if([self decode:base58 error:error]) { 71 | return self; 72 | } 73 | else { 74 | return nil; 75 | } 76 | } 77 | return self; 78 | } 79 | 80 | - (instancetype) init { 81 | self = [super init]; 82 | if (self) { 83 | seed = new ed25519::Seed(); 84 | } 85 | return self; 86 | } 87 | 88 | - (instancetype) initWithSecret:(NSString *)phrase { 89 | self = [super init]; 90 | if (self) { 91 | seed = new ed25519::Seed([phrase UTF8String]); 92 | } 93 | return self; 94 | } 95 | 96 | - (BOOL)decode:(NSString *)base58 error:(NSError **)error { 97 | return seed->decode([base58 UTF8String], 98 | [error](const std::error_code &code){ 99 | if (error) 100 | *error = error2NSError(code); 101 | }); 102 | } 103 | 104 | - (NSString *)encode { 105 | return [NSString stringWithUTF8String:seed->encode().c_str()]; 106 | } 107 | 108 | @end 109 | 110 | 111 | @implementation PublicKey 112 | { 113 | std::optional key; 114 | } 115 | 116 | - (instancetype) initWithKey:(std::optional) inkey{ 117 | self = [[PublicKey alloc] init]; 118 | if (self){ 119 | key = inkey; 120 | } 121 | return self; 122 | } 123 | 124 | - (std::optional) data { 125 | return key; 126 | } 127 | 128 | - (_Nullable instancetype) initWithBase58:(nonnull NSString *)base58 error:(NSError * _Nullable*_Nullable)error { 129 | self = [[PublicKey alloc] init]; 130 | if (self){ 131 | key = ed25519::keys::Public::Decode([base58 UTF8String], 132 | [error](const std::error_code &code){ 133 | if (error) 134 | *error = error2NSError(code); 135 | }); 136 | if (key) { 137 | return self; 138 | } 139 | return nil; 140 | 141 | } 142 | return self; 143 | } 144 | 145 | 146 | - (NSString *)encode { 147 | return [NSString stringWithUTF8String:key->encode().c_str()]; 148 | } 149 | 150 | @end 151 | 152 | @implementation PrivateKey 153 | { 154 | std::optional key; 155 | } 156 | 157 | - (instancetype) initWithKey:(std::optional) inkey{ 158 | self = [[PrivateKey alloc] init]; 159 | if (self){ 160 | key = inkey; 161 | } 162 | return self; 163 | } 164 | 165 | - (std::optional) data { 166 | return key; 167 | } 168 | 169 | - (_Nullable instancetype) initWithBase58:(nonnull NSString *)base58 error:(NSError * _Nullable*_Nullable)error { 170 | self = [[PrivateKey alloc] init]; 171 | if (self){ 172 | key = ed25519::keys::Private::Decode([base58 UTF8String], 173 | [error](const std::error_code &code){ 174 | if (error) 175 | *error = error2NSError(code); 176 | }); 177 | if (key) { 178 | return self; 179 | } 180 | return nil; 181 | 182 | } 183 | return self; 184 | } 185 | 186 | 187 | - (NSString *)encode { 188 | return [NSString stringWithUTF8String:key->encode().c_str()]; 189 | } 190 | 191 | @end 192 | 193 | @implementation Digest 194 | { 195 | std::optional digest; 196 | } 197 | 198 | - (std::optional) data { 199 | return digest; 200 | } 201 | 202 | - (instancetype) initWithCalculator:(DigestCalculatorType)calculator{ 203 | 204 | self = [[Digest alloc] init]; 205 | if (self){ 206 | 207 | ed25519::Digest d = ed25519::Digest([&calculator](ed25519::Digest::Calculator &_calculator){ 208 | DigestCalculator *digest_calculator = [[DigestCalculator alloc] initWithC:&_calculator]; 209 | calculator(digest_calculator); 210 | }); 211 | 212 | digest = std::make_optional(d); 213 | return self; 214 | } 215 | return self; 216 | 217 | } 218 | 219 | - (nonnull NSString *)encode { 220 | return [NSString stringWithUTF8String:digest->encode().c_str()]; 221 | } 222 | 223 | - (instancetype _Nullable)initWithBase58:(nonnull NSString *)base58 error:(NSError *__autoreleasing _Nullable * _Nullable)error { 224 | self = [[Digest alloc] init]; 225 | if (self){ 226 | digest = ed25519::Digest::Decode([base58 UTF8String], 227 | [error](const std::error_code &code){ 228 | if (error) 229 | *error = error2NSError(code); 230 | }); 231 | if (digest) { 232 | return self; 233 | } 234 | return nil; 235 | 236 | } 237 | return self; 238 | } 239 | 240 | - (BOOL)decode:(nonnull NSString *)base58 error:(NSError *__autoreleasing _Nullable * _Nullable)error { 241 | return digest->decode([base58 UTF8String], 242 | [error](const std::error_code &code){ 243 | if (error) 244 | *error = error2NSError(code); 245 | }); 246 | } 247 | 248 | @end 249 | 250 | @implementation DigestCalculator 251 | { 252 | ed25519::Digest::Calculator *calculator; 253 | } 254 | 255 | - (instancetype) initWithC:(ed25519::Digest::Calculator *)c{ 256 | self = [super init]; 257 | if (self){ 258 | calculator = c; 259 | } 260 | return self; 261 | } 262 | 263 | - (instancetype) appendInteger:(NSInteger)integer{ 264 | calculator->append((int)integer); 265 | return self; 266 | } 267 | 268 | - (instancetype) appendString:(NSString*)string { 269 | calculator->append(std::string([string UTF8String])); 270 | return self; 271 | } 272 | 273 | - (nonnull instancetype) appendBool:(bool)value { 274 | calculator->append(value); 275 | return self; 276 | } 277 | 278 | - (nonnull instancetype) appendUInt8:(uint8)value { 279 | calculator->append(value); 280 | return self; 281 | } 282 | 283 | - (nonnull instancetype) appendInt16:(int16_t)value { 284 | calculator->append(value); 285 | return self; 286 | } 287 | 288 | - (nonnull instancetype) appendPublicKey:(PublicKey *_Nonnull)value { 289 | calculator->append(*[value data]); 290 | return self; 291 | } 292 | 293 | - (nonnull instancetype) appendPrivateKey:(PrivateKey *_Nonnull)value { 294 | calculator->append(*[value data]); 295 | return self; 296 | } 297 | 298 | - (nonnull instancetype) appendSeed:(Seed *_Nonnull)value{ 299 | calculator->append(*[value data]); 300 | return self; 301 | } 302 | 303 | - (nonnull instancetype) appendDigest:(Digest *_Nonnull)value{ 304 | calculator->append(*[value data]); 305 | return self; 306 | } 307 | 308 | @end 309 | 310 | @implementation Signature 311 | { 312 | std::optional signature; 313 | } 314 | 315 | - (instancetype) initWithSignature:(std::optional) inSignature{ 316 | self = [[Signature alloc] init]; 317 | if (self){ 318 | signature = inSignature; 319 | } 320 | return self; 321 | } 322 | 323 | - (_Nullable instancetype) initWithBase58:(nonnull NSString *)base58 error:(NSError * _Nullable*_Nullable)error { 324 | self = [[Signature alloc] init]; 325 | if (self){ 326 | signature = ed25519::Signature::Decode([base58 UTF8String], 327 | [error](const std::error_code &code){ 328 | if (error) 329 | *error = error2NSError(code); 330 | }); 331 | if (signature) { 332 | return self; 333 | } 334 | return nil; 335 | 336 | } 337 | return self; 338 | } 339 | 340 | - (nonnull NSString *)encode { 341 | return [NSString stringWithUTF8String:signature->encode().c_str()]; 342 | } 343 | 344 | 345 | - (BOOL) verifyWithPublic:(nonnull PublicKey*)publicKey message:(nonnull NSData *)message { 346 | size_t len = [message length]; 347 | 348 | std::vector v; v.resize(len,0); 349 | 350 | [message getBytes:v.data() length:len]; 351 | 352 | return signature->verify(v, *[publicKey data]); 353 | } 354 | 355 | - (BOOL) verifyWithPublic:(nonnull PublicKey*)publicKey string:(nonnull NSString *)string { 356 | return signature->verify([string UTF8String], *[publicKey data]); 357 | } 358 | 359 | - (BOOL) verifyWithPublic:(nonnull PublicKey*)publicKey digest:(nonnull Digest *)digest { 360 | return signature->verify(*[digest data], *[publicKey data]); 361 | } 362 | 363 | @end 364 | 365 | @implementation Pair 366 | { 367 | std::optional pair; 368 | PublicKey *pk; 369 | PrivateKey *pvk; 370 | } 371 | 372 | - (PublicKey*) publicKey { 373 | return pk; 374 | } 375 | 376 | - (PrivateKey*) privateKey { 377 | return pvk; 378 | } 379 | 380 | - (instancetype) init { 381 | self = [super init]; 382 | return self; 383 | } 384 | 385 | +(instancetype)Random { 386 | Pair *p = [[Pair alloc ] init]; 387 | p->pair = ed25519::keys::Pair::Random(); 388 | p->pk = [[PublicKey alloc] initWithKey:p->pair->get_public_key()]; 389 | p->pvk = [[PrivateKey alloc] initWithKey:p->pair->get_private_key()]; 390 | return p; 391 | } 392 | 393 | - (nullable instancetype)initWithSecretPhrase:(nonnull NSString*)phrase 394 | error:(NSError *_Null_unspecified __autoreleasing *_Null_unspecified)error { 395 | pair = ed25519::keys 396 | ::Pair::WithSecret([phrase UTF8String], 397 | 398 | [error](const std::error_code &code){ 399 | if (error) 400 | *error = error2NSError(code); 401 | }); 402 | 403 | if (pair) { 404 | 405 | self = [super init]; 406 | pk = [[PublicKey alloc] initWithKey:pair->get_public_key()]; 407 | pvk = [[PrivateKey alloc] initWithKey:pair->get_private_key()]; 408 | 409 | return self; 410 | } 411 | 412 | return nil; 413 | } 414 | 415 | - (nullable instancetype)initFromPrivateKey:(nonnull NSString*)privateKey 416 | error:(NSError *_Null_unspecified __autoreleasing *_Null_unspecified)error{ 417 | 418 | pair = ed25519 ::keys::Pair 419 | ::FromPrivateKey ([privateKey UTF8String], 420 | 421 | [error](const std::error_code &code){ 422 | if (error) 423 | *error = error2NSError(code); 424 | }); 425 | 426 | if (pair) { 427 | 428 | self = [super init]; 429 | pk = [[PublicKey alloc] initWithKey:pair->get_public_key()]; 430 | pvk = [[PrivateKey alloc] initWithKey:pair->get_private_key()]; 431 | 432 | return self; 433 | } 434 | 435 | return nil; 436 | } 437 | 438 | - (nonnull Signature*) signMessage:(nonnull NSData*)message { 439 | 440 | size_t len = [message length]; 441 | std::vector v; v.resize(len,0); 442 | [message getBytes:v.data() length:len]; 443 | 444 | return [[Signature alloc] initWithSignature:*std::move(pair->sign(v))]; 445 | } 446 | 447 | - (nonnull Signature*) signString:(nonnull NSString*)message{ 448 | return [[Signature alloc] initWithSignature:*std::move(pair->sign([message UTF8String]))]; 449 | } 450 | 451 | - (nonnull Signature*) signDigest:(nonnull Digest*)digest{ 452 | auto s = pair->sign(*[digest data]); 453 | return [[Signature alloc] initWithSignature:*std::move(s)]; 454 | } 455 | 456 | - (NSString *) description { 457 | return [NSString stringWithFormat:@"%@:%@", [pk encode], [pvk encode] ]; 458 | } 459 | 460 | @end 461 | -------------------------------------------------------------------------------- /platforms/swift/test/Ed25519-Swift-pod/Ed25519-Swift-pod.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 317778B2220722290046B034 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 317778B1220722290046B034 /* AppDelegate.swift */; }; 11 | 317778B42207222B0046B034 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 317778B32207222B0046B034 /* Assets.xcassets */; }; 12 | 317778B72207222B0046B034 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 317778B52207222B0046B034 /* MainMenu.xib */; }; 13 | 317778C32207222B0046B034 /* Ed25519_Swift_podTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 317778C22207222B0046B034 /* Ed25519_Swift_podTests.swift */; }; 14 | E339A147D0DD9ABB498016EB /* Pods_Ed25519_Swift_pod.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 958A1A450F7609B589EB37AA /* Pods_Ed25519_Swift_pod.framework */; }; 15 | /* End PBXBuildFile section */ 16 | 17 | /* Begin PBXContainerItemProxy section */ 18 | 317778BF2207222B0046B034 /* PBXContainerItemProxy */ = { 19 | isa = PBXContainerItemProxy; 20 | containerPortal = 317778A6220722290046B034 /* Project object */; 21 | proxyType = 1; 22 | remoteGlobalIDString = 317778AD220722290046B034; 23 | remoteInfo = "Ed25519-Swift-pod"; 24 | }; 25 | /* End PBXContainerItemProxy section */ 26 | 27 | /* Begin PBXFileReference section */ 28 | 317778AE220722290046B034 /* Ed25519-Swift-pod.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Ed25519-Swift-pod.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | 317778B1220722290046B034 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 30 | 317778B32207222B0046B034 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 31 | 317778B62207222B0046B034 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 32 | 317778B82207222B0046B034 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 33 | 317778B92207222B0046B034 /* Ed25519_Swift_pod.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Ed25519_Swift_pod.entitlements; sourceTree = ""; }; 34 | 317778BE2207222B0046B034 /* Ed25519-Swift-podTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Ed25519-Swift-podTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 35 | 317778C22207222B0046B034 /* Ed25519_Swift_podTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ed25519_Swift_podTests.swift; sourceTree = ""; }; 36 | 317778C42207222B0046B034 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 37 | 4A5CCC15E540B8B43B5143A0 /* Pods-Ed25519-Swift-pod.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Ed25519-Swift-pod.release.xcconfig"; path = "Target Support Files/Pods-Ed25519-Swift-pod/Pods-Ed25519-Swift-pod.release.xcconfig"; sourceTree = ""; }; 38 | 958A1A450F7609B589EB37AA /* Pods_Ed25519_Swift_pod.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Ed25519_Swift_pod.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 39 | 9FAB8248FC357F4CE524026B /* Pods-Ed25519-Swift-pod.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Ed25519-Swift-pod.debug.xcconfig"; path = "Target Support Files/Pods-Ed25519-Swift-pod/Pods-Ed25519-Swift-pod.debug.xcconfig"; sourceTree = ""; }; 40 | /* End PBXFileReference section */ 41 | 42 | /* Begin PBXFrameworksBuildPhase section */ 43 | 317778AB220722290046B034 /* Frameworks */ = { 44 | isa = PBXFrameworksBuildPhase; 45 | buildActionMask = 2147483647; 46 | files = ( 47 | E339A147D0DD9ABB498016EB /* Pods_Ed25519_Swift_pod.framework in Frameworks */, 48 | ); 49 | runOnlyForDeploymentPostprocessing = 0; 50 | }; 51 | 317778BB2207222B0046B034 /* Frameworks */ = { 52 | isa = PBXFrameworksBuildPhase; 53 | buildActionMask = 2147483647; 54 | files = ( 55 | ); 56 | runOnlyForDeploymentPostprocessing = 0; 57 | }; 58 | /* End PBXFrameworksBuildPhase section */ 59 | 60 | /* Begin PBXGroup section */ 61 | 317778A5220722290046B034 = { 62 | isa = PBXGroup; 63 | children = ( 64 | 317778B0220722290046B034 /* Ed25519-Swift-pod */, 65 | 317778C12207222B0046B034 /* Ed25519-Swift-podTests */, 66 | 317778AF220722290046B034 /* Products */, 67 | E2525C2C43B5995855135A84 /* Pods */, 68 | 35351175E097FAFB50BCF008 /* Frameworks */, 69 | ); 70 | sourceTree = ""; 71 | }; 72 | 317778AF220722290046B034 /* Products */ = { 73 | isa = PBXGroup; 74 | children = ( 75 | 317778AE220722290046B034 /* Ed25519-Swift-pod.app */, 76 | 317778BE2207222B0046B034 /* Ed25519-Swift-podTests.xctest */, 77 | ); 78 | name = Products; 79 | sourceTree = ""; 80 | }; 81 | 317778B0220722290046B034 /* Ed25519-Swift-pod */ = { 82 | isa = PBXGroup; 83 | children = ( 84 | 317778B1220722290046B034 /* AppDelegate.swift */, 85 | 317778B32207222B0046B034 /* Assets.xcassets */, 86 | 317778B52207222B0046B034 /* MainMenu.xib */, 87 | 317778B82207222B0046B034 /* Info.plist */, 88 | 317778B92207222B0046B034 /* Ed25519_Swift_pod.entitlements */, 89 | ); 90 | path = "Ed25519-Swift-pod"; 91 | sourceTree = ""; 92 | }; 93 | 317778C12207222B0046B034 /* Ed25519-Swift-podTests */ = { 94 | isa = PBXGroup; 95 | children = ( 96 | 317778C22207222B0046B034 /* Ed25519_Swift_podTests.swift */, 97 | 317778C42207222B0046B034 /* Info.plist */, 98 | ); 99 | path = "Ed25519-Swift-podTests"; 100 | sourceTree = ""; 101 | }; 102 | 35351175E097FAFB50BCF008 /* Frameworks */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | 958A1A450F7609B589EB37AA /* Pods_Ed25519_Swift_pod.framework */, 106 | ); 107 | name = Frameworks; 108 | sourceTree = ""; 109 | }; 110 | E2525C2C43B5995855135A84 /* Pods */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | 9FAB8248FC357F4CE524026B /* Pods-Ed25519-Swift-pod.debug.xcconfig */, 114 | 4A5CCC15E540B8B43B5143A0 /* Pods-Ed25519-Swift-pod.release.xcconfig */, 115 | ); 116 | path = Pods; 117 | sourceTree = ""; 118 | }; 119 | /* End PBXGroup section */ 120 | 121 | /* Begin PBXNativeTarget section */ 122 | 317778AD220722290046B034 /* Ed25519-Swift-pod */ = { 123 | isa = PBXNativeTarget; 124 | buildConfigurationList = 317778C72207222B0046B034 /* Build configuration list for PBXNativeTarget "Ed25519-Swift-pod" */; 125 | buildPhases = ( 126 | C93BEB65D0A4C1534AD5C746 /* [CP] Check Pods Manifest.lock */, 127 | 317778AA220722290046B034 /* Sources */, 128 | 317778AB220722290046B034 /* Frameworks */, 129 | 317778AC220722290046B034 /* Resources */, 130 | F434C47011B990DEF7469297 /* [CP] Embed Pods Frameworks */, 131 | ); 132 | buildRules = ( 133 | ); 134 | dependencies = ( 135 | ); 136 | name = "Ed25519-Swift-pod"; 137 | productName = "Ed25519-Swift-pod"; 138 | productReference = 317778AE220722290046B034 /* Ed25519-Swift-pod.app */; 139 | productType = "com.apple.product-type.application"; 140 | }; 141 | 317778BD2207222B0046B034 /* Ed25519-Swift-podTests */ = { 142 | isa = PBXNativeTarget; 143 | buildConfigurationList = 317778CA2207222B0046B034 /* Build configuration list for PBXNativeTarget "Ed25519-Swift-podTests" */; 144 | buildPhases = ( 145 | 317778BA2207222B0046B034 /* Sources */, 146 | 317778BB2207222B0046B034 /* Frameworks */, 147 | 317778BC2207222B0046B034 /* Resources */, 148 | ); 149 | buildRules = ( 150 | ); 151 | dependencies = ( 152 | 317778C02207222B0046B034 /* PBXTargetDependency */, 153 | ); 154 | name = "Ed25519-Swift-podTests"; 155 | productName = "Ed25519-Swift-podTests"; 156 | productReference = 317778BE2207222B0046B034 /* Ed25519-Swift-podTests.xctest */; 157 | productType = "com.apple.product-type.bundle.unit-test"; 158 | }; 159 | /* End PBXNativeTarget section */ 160 | 161 | /* Begin PBXProject section */ 162 | 317778A6220722290046B034 /* Project object */ = { 163 | isa = PBXProject; 164 | attributes = { 165 | LastSwiftUpdateCheck = 1010; 166 | LastUpgradeCheck = 1010; 167 | ORGANIZATIONNAME = Dehacer; 168 | TargetAttributes = { 169 | 317778AD220722290046B034 = { 170 | CreatedOnToolsVersion = 10.1; 171 | }; 172 | 317778BD2207222B0046B034 = { 173 | CreatedOnToolsVersion = 10.1; 174 | TestTargetID = 317778AD220722290046B034; 175 | }; 176 | }; 177 | }; 178 | buildConfigurationList = 317778A9220722290046B034 /* Build configuration list for PBXProject "Ed25519-Swift-pod" */; 179 | compatibilityVersion = "Xcode 9.3"; 180 | developmentRegion = en; 181 | hasScannedForEncodings = 0; 182 | knownRegions = ( 183 | en, 184 | Base, 185 | ); 186 | mainGroup = 317778A5220722290046B034; 187 | productRefGroup = 317778AF220722290046B034 /* Products */; 188 | projectDirPath = ""; 189 | projectRoot = ""; 190 | targets = ( 191 | 317778AD220722290046B034 /* Ed25519-Swift-pod */, 192 | 317778BD2207222B0046B034 /* Ed25519-Swift-podTests */, 193 | ); 194 | }; 195 | /* End PBXProject section */ 196 | 197 | /* Begin PBXResourcesBuildPhase section */ 198 | 317778AC220722290046B034 /* Resources */ = { 199 | isa = PBXResourcesBuildPhase; 200 | buildActionMask = 2147483647; 201 | files = ( 202 | 317778B42207222B0046B034 /* Assets.xcassets in Resources */, 203 | 317778B72207222B0046B034 /* MainMenu.xib in Resources */, 204 | ); 205 | runOnlyForDeploymentPostprocessing = 0; 206 | }; 207 | 317778BC2207222B0046B034 /* Resources */ = { 208 | isa = PBXResourcesBuildPhase; 209 | buildActionMask = 2147483647; 210 | files = ( 211 | ); 212 | runOnlyForDeploymentPostprocessing = 0; 213 | }; 214 | /* End PBXResourcesBuildPhase section */ 215 | 216 | /* Begin PBXShellScriptBuildPhase section */ 217 | C93BEB65D0A4C1534AD5C746 /* [CP] Check Pods Manifest.lock */ = { 218 | isa = PBXShellScriptBuildPhase; 219 | buildActionMask = 2147483647; 220 | files = ( 221 | ); 222 | inputFileListPaths = ( 223 | ); 224 | inputPaths = ( 225 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 226 | "${PODS_ROOT}/Manifest.lock", 227 | ); 228 | name = "[CP] Check Pods Manifest.lock"; 229 | outputFileListPaths = ( 230 | ); 231 | outputPaths = ( 232 | "$(DERIVED_FILE_DIR)/Pods-Ed25519-Swift-pod-checkManifestLockResult.txt", 233 | ); 234 | runOnlyForDeploymentPostprocessing = 0; 235 | shellPath = /bin/sh; 236 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 237 | showEnvVarsInLog = 0; 238 | }; 239 | F434C47011B990DEF7469297 /* [CP] Embed Pods Frameworks */ = { 240 | isa = PBXShellScriptBuildPhase; 241 | buildActionMask = 2147483647; 242 | files = ( 243 | ); 244 | inputFileListPaths = ( 245 | ); 246 | inputPaths = ( 247 | "${PODS_ROOT}/Target Support Files/Pods-Ed25519-Swift-pod/Pods-Ed25519-Swift-pod-frameworks.sh", 248 | "${BUILT_PRODUCTS_DIR}/ed25519/ed25519.framework", 249 | ); 250 | name = "[CP] Embed Pods Frameworks"; 251 | outputFileListPaths = ( 252 | ); 253 | outputPaths = ( 254 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ed25519.framework", 255 | ); 256 | runOnlyForDeploymentPostprocessing = 0; 257 | shellPath = /bin/sh; 258 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Ed25519-Swift-pod/Pods-Ed25519-Swift-pod-frameworks.sh\"\n"; 259 | showEnvVarsInLog = 0; 260 | }; 261 | /* End PBXShellScriptBuildPhase section */ 262 | 263 | /* Begin PBXSourcesBuildPhase section */ 264 | 317778AA220722290046B034 /* Sources */ = { 265 | isa = PBXSourcesBuildPhase; 266 | buildActionMask = 2147483647; 267 | files = ( 268 | 317778B2220722290046B034 /* AppDelegate.swift in Sources */, 269 | ); 270 | runOnlyForDeploymentPostprocessing = 0; 271 | }; 272 | 317778BA2207222B0046B034 /* Sources */ = { 273 | isa = PBXSourcesBuildPhase; 274 | buildActionMask = 2147483647; 275 | files = ( 276 | 317778C32207222B0046B034 /* Ed25519_Swift_podTests.swift in Sources */, 277 | ); 278 | runOnlyForDeploymentPostprocessing = 0; 279 | }; 280 | /* End PBXSourcesBuildPhase section */ 281 | 282 | /* Begin PBXTargetDependency section */ 283 | 317778C02207222B0046B034 /* PBXTargetDependency */ = { 284 | isa = PBXTargetDependency; 285 | target = 317778AD220722290046B034 /* Ed25519-Swift-pod */; 286 | targetProxy = 317778BF2207222B0046B034 /* PBXContainerItemProxy */; 287 | }; 288 | /* End PBXTargetDependency section */ 289 | 290 | /* Begin PBXVariantGroup section */ 291 | 317778B52207222B0046B034 /* MainMenu.xib */ = { 292 | isa = PBXVariantGroup; 293 | children = ( 294 | 317778B62207222B0046B034 /* Base */, 295 | ); 296 | name = MainMenu.xib; 297 | sourceTree = ""; 298 | }; 299 | /* End PBXVariantGroup section */ 300 | 301 | /* Begin XCBuildConfiguration section */ 302 | 317778C52207222B0046B034 /* Debug */ = { 303 | isa = XCBuildConfiguration; 304 | buildSettings = { 305 | ALWAYS_SEARCH_USER_PATHS = NO; 306 | CLANG_ANALYZER_NONNULL = YES; 307 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 308 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 309 | CLANG_CXX_LIBRARY = "libc++"; 310 | CLANG_ENABLE_MODULES = YES; 311 | CLANG_ENABLE_OBJC_ARC = YES; 312 | CLANG_ENABLE_OBJC_WEAK = YES; 313 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 314 | CLANG_WARN_BOOL_CONVERSION = YES; 315 | CLANG_WARN_COMMA = YES; 316 | CLANG_WARN_CONSTANT_CONVERSION = YES; 317 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 318 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 319 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 320 | CLANG_WARN_EMPTY_BODY = YES; 321 | CLANG_WARN_ENUM_CONVERSION = YES; 322 | CLANG_WARN_INFINITE_RECURSION = YES; 323 | CLANG_WARN_INT_CONVERSION = YES; 324 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 325 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 326 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 327 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 328 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 329 | CLANG_WARN_STRICT_PROTOTYPES = YES; 330 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 331 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 332 | CLANG_WARN_UNREACHABLE_CODE = YES; 333 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 334 | CODE_SIGN_IDENTITY = "Mac Developer"; 335 | COPY_PHASE_STRIP = NO; 336 | DEBUG_INFORMATION_FORMAT = dwarf; 337 | ENABLE_STRICT_OBJC_MSGSEND = YES; 338 | ENABLE_TESTABILITY = YES; 339 | GCC_C_LANGUAGE_STANDARD = gnu11; 340 | GCC_DYNAMIC_NO_PIC = NO; 341 | GCC_NO_COMMON_BLOCKS = YES; 342 | GCC_OPTIMIZATION_LEVEL = 0; 343 | GCC_PREPROCESSOR_DEFINITIONS = ( 344 | "DEBUG=1", 345 | "$(inherited)", 346 | ); 347 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 348 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 349 | GCC_WARN_UNDECLARED_SELECTOR = YES; 350 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 351 | GCC_WARN_UNUSED_FUNCTION = YES; 352 | GCC_WARN_UNUSED_VARIABLE = YES; 353 | MACOSX_DEPLOYMENT_TARGET = 10.14; 354 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 355 | MTL_FAST_MATH = YES; 356 | ONLY_ACTIVE_ARCH = YES; 357 | SDKROOT = macosx; 358 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 359 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 360 | }; 361 | name = Debug; 362 | }; 363 | 317778C62207222B0046B034 /* Release */ = { 364 | isa = XCBuildConfiguration; 365 | buildSettings = { 366 | ALWAYS_SEARCH_USER_PATHS = NO; 367 | CLANG_ANALYZER_NONNULL = YES; 368 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 369 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 370 | CLANG_CXX_LIBRARY = "libc++"; 371 | CLANG_ENABLE_MODULES = YES; 372 | CLANG_ENABLE_OBJC_ARC = YES; 373 | CLANG_ENABLE_OBJC_WEAK = YES; 374 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 375 | CLANG_WARN_BOOL_CONVERSION = YES; 376 | CLANG_WARN_COMMA = YES; 377 | CLANG_WARN_CONSTANT_CONVERSION = YES; 378 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 379 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 380 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 381 | CLANG_WARN_EMPTY_BODY = YES; 382 | CLANG_WARN_ENUM_CONVERSION = YES; 383 | CLANG_WARN_INFINITE_RECURSION = YES; 384 | CLANG_WARN_INT_CONVERSION = YES; 385 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 386 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 387 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 388 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 389 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 390 | CLANG_WARN_STRICT_PROTOTYPES = YES; 391 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 392 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 393 | CLANG_WARN_UNREACHABLE_CODE = YES; 394 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 395 | CODE_SIGN_IDENTITY = "Mac Developer"; 396 | COPY_PHASE_STRIP = NO; 397 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 398 | ENABLE_NS_ASSERTIONS = NO; 399 | ENABLE_STRICT_OBJC_MSGSEND = YES; 400 | GCC_C_LANGUAGE_STANDARD = gnu11; 401 | GCC_NO_COMMON_BLOCKS = YES; 402 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 403 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 404 | GCC_WARN_UNDECLARED_SELECTOR = YES; 405 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 406 | GCC_WARN_UNUSED_FUNCTION = YES; 407 | GCC_WARN_UNUSED_VARIABLE = YES; 408 | MACOSX_DEPLOYMENT_TARGET = 10.14; 409 | MTL_ENABLE_DEBUG_INFO = NO; 410 | MTL_FAST_MATH = YES; 411 | SDKROOT = macosx; 412 | SWIFT_COMPILATION_MODE = wholemodule; 413 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 414 | }; 415 | name = Release; 416 | }; 417 | 317778C82207222B0046B034 /* Debug */ = { 418 | isa = XCBuildConfiguration; 419 | baseConfigurationReference = 9FAB8248FC357F4CE524026B /* Pods-Ed25519-Swift-pod.debug.xcconfig */; 420 | buildSettings = { 421 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 422 | CODE_SIGN_ENTITLEMENTS = "Ed25519-Swift-pod/Ed25519_Swift_pod.entitlements"; 423 | CODE_SIGN_IDENTITY = "Mac Developer"; 424 | CODE_SIGN_STYLE = Automatic; 425 | COMBINE_HIDPI_IMAGES = YES; 426 | DEVELOPMENT_TEAM = TCA85S5T49; 427 | INFOPLIST_FILE = "Ed25519-Swift-pod/Info.plist"; 428 | LD_RUNPATH_SEARCH_PATHS = ( 429 | "$(inherited)", 430 | "@executable_path/../Frameworks", 431 | ); 432 | PRODUCT_BUNDLE_IDENTIFIER = "Dehancer.Ed25519-Swift-pod"; 433 | PRODUCT_NAME = "$(TARGET_NAME)"; 434 | PROVISIONING_PROFILE_SPECIFIER = ""; 435 | SWIFT_VERSION = 4.2; 436 | }; 437 | name = Debug; 438 | }; 439 | 317778C92207222B0046B034 /* Release */ = { 440 | isa = XCBuildConfiguration; 441 | baseConfigurationReference = 4A5CCC15E540B8B43B5143A0 /* Pods-Ed25519-Swift-pod.release.xcconfig */; 442 | buildSettings = { 443 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 444 | CODE_SIGN_ENTITLEMENTS = "Ed25519-Swift-pod/Ed25519_Swift_pod.entitlements"; 445 | CODE_SIGN_IDENTITY = "Mac Developer"; 446 | CODE_SIGN_STYLE = Automatic; 447 | COMBINE_HIDPI_IMAGES = YES; 448 | DEVELOPMENT_TEAM = TCA85S5T49; 449 | INFOPLIST_FILE = "Ed25519-Swift-pod/Info.plist"; 450 | LD_RUNPATH_SEARCH_PATHS = ( 451 | "$(inherited)", 452 | "@executable_path/../Frameworks", 453 | ); 454 | PRODUCT_BUNDLE_IDENTIFIER = "Dehancer.Ed25519-Swift-pod"; 455 | PRODUCT_NAME = "$(TARGET_NAME)"; 456 | PROVISIONING_PROFILE_SPECIFIER = ""; 457 | SWIFT_VERSION = 4.2; 458 | }; 459 | name = Release; 460 | }; 461 | 317778CB2207222B0046B034 /* Debug */ = { 462 | isa = XCBuildConfiguration; 463 | buildSettings = { 464 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 465 | BUNDLE_LOADER = "$(TEST_HOST)"; 466 | CODE_SIGN_STYLE = Automatic; 467 | COMBINE_HIDPI_IMAGES = YES; 468 | DEVELOPMENT_TEAM = TCA85S5T49; 469 | INFOPLIST_FILE = "Ed25519-Swift-podTests/Info.plist"; 470 | LD_RUNPATH_SEARCH_PATHS = ( 471 | "$(inherited)", 472 | "@executable_path/../Frameworks", 473 | "@loader_path/../Frameworks", 474 | ); 475 | PRODUCT_BUNDLE_IDENTIFIER = "Dehancer.Ed25519-Swift-podTests"; 476 | PRODUCT_NAME = "$(TARGET_NAME)"; 477 | SWIFT_VERSION = 4.2; 478 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Ed25519-Swift-pod.app/Contents/MacOS/Ed25519-Swift-pod"; 479 | }; 480 | name = Debug; 481 | }; 482 | 317778CC2207222B0046B034 /* Release */ = { 483 | isa = XCBuildConfiguration; 484 | buildSettings = { 485 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 486 | BUNDLE_LOADER = "$(TEST_HOST)"; 487 | CODE_SIGN_STYLE = Automatic; 488 | COMBINE_HIDPI_IMAGES = YES; 489 | DEVELOPMENT_TEAM = TCA85S5T49; 490 | INFOPLIST_FILE = "Ed25519-Swift-podTests/Info.plist"; 491 | LD_RUNPATH_SEARCH_PATHS = ( 492 | "$(inherited)", 493 | "@executable_path/../Frameworks", 494 | "@loader_path/../Frameworks", 495 | ); 496 | PRODUCT_BUNDLE_IDENTIFIER = "Dehancer.Ed25519-Swift-podTests"; 497 | PRODUCT_NAME = "$(TARGET_NAME)"; 498 | SWIFT_VERSION = 4.2; 499 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Ed25519-Swift-pod.app/Contents/MacOS/Ed25519-Swift-pod"; 500 | }; 501 | name = Release; 502 | }; 503 | /* End XCBuildConfiguration section */ 504 | 505 | /* Begin XCConfigurationList section */ 506 | 317778A9220722290046B034 /* Build configuration list for PBXProject "Ed25519-Swift-pod" */ = { 507 | isa = XCConfigurationList; 508 | buildConfigurations = ( 509 | 317778C52207222B0046B034 /* Debug */, 510 | 317778C62207222B0046B034 /* Release */, 511 | ); 512 | defaultConfigurationIsVisible = 0; 513 | defaultConfigurationName = Release; 514 | }; 515 | 317778C72207222B0046B034 /* Build configuration list for PBXNativeTarget "Ed25519-Swift-pod" */ = { 516 | isa = XCConfigurationList; 517 | buildConfigurations = ( 518 | 317778C82207222B0046B034 /* Debug */, 519 | 317778C92207222B0046B034 /* Release */, 520 | ); 521 | defaultConfigurationIsVisible = 0; 522 | defaultConfigurationName = Release; 523 | }; 524 | 317778CA2207222B0046B034 /* Build configuration list for PBXNativeTarget "Ed25519-Swift-podTests" */ = { 525 | isa = XCConfigurationList; 526 | buildConfigurations = ( 527 | 317778CB2207222B0046B034 /* Debug */, 528 | 317778CC2207222B0046B034 /* Release */, 529 | ); 530 | defaultConfigurationIsVisible = 0; 531 | defaultConfigurationName = Release; 532 | }; 533 | /* End XCConfigurationList section */ 534 | }; 535 | rootObject = 317778A6220722290046B034 /* Project object */; 536 | } 537 | -------------------------------------------------------------------------------- /platforms/swift/test/Ed25519-Swift-pod/Ed25519-Swift-pod.xcworkspace/xcuserdata/denn.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 20 | 21 | 22 | 24 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /platforms/swift/test/Ed25519-Swift-pod/Ed25519-Swift-pod/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Ed25519-Swift-pod 4 | // 5 | // Created by denn on 03/02/2019. 6 | // Copyright © 2019 Dehacer. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import ed25519 11 | 12 | @NSApplicationMain 13 | class AppDelegate: NSObject, NSApplicationDelegate { 14 | 15 | @IBOutlet weak var window: NSWindow! 16 | 17 | func applicationDidFinishLaunching(_ aNotification: Notification) { 18 | 19 | let pair = try! Pair(secretPhrase: "some secret phrase") 20 | let pair_random = Pair.random() 21 | 22 | let message = "some message or token string" 23 | var signature = pair.sign(message) 24 | 25 | Swift.print("Signature : \(signature.encode())") 26 | 27 | Swift.print("Signature verify: \(signature.verify(withPublic: pair.publicKey, string: message))") 28 | Swift.print("Signature verify random: \(signature.verify(withPublic: pair_random.publicKey, string: message))") 29 | 30 | var data = message.data(using: String.Encoding.utf8)! 31 | Swift.print("Signature verify data: \(signature.verify(withPublic: pair.publicKey, message: data))") 32 | 33 | let restored_signature = try! Signature(base58: signature.encode()) 34 | Swift.print("Restored signature verify: \(restored_signature.verify(withPublic: pair.publicKey, message: data))") 35 | data.reverse() 36 | Swift.print("Restored signature verify modified data: \(restored_signature.verify(withPublic: pair.publicKey, message: data))") 37 | 38 | let digest = Digest { (calculator) in 39 | calculator 40 | .append(true) 41 | .append(3) 42 | .append("...") 43 | .append(pair.publicKey) 44 | .append(Seed()) 45 | 46 | } 47 | Swift.print("Digest : \(digest.encode())") 48 | 49 | signature = pair.sign(digest) 50 | Swift.print("Signature : \(signature.encode())") 51 | Swift.print("Signature verify: \(signature.verify(withPublic: pair.publicKey, digest: digest))") 52 | Swift.print("Signature verify random: \(signature.verify(withPublic: pair_random.publicKey, digest: digest))") 53 | 54 | do { 55 | _ = try Signature(base58: "...some wrong base 58...") 56 | } 57 | catch { 58 | Swift.print("Error: \(error)") 59 | } 60 | } 61 | 62 | func applicationWillTerminate(_ aNotification: Notification) { 63 | // Insert code here to tear down your application 64 | } 65 | 66 | 67 | } 68 | 69 | -------------------------------------------------------------------------------- /platforms/swift/test/Ed25519-Swift-pod/Ed25519-Swift-pod/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /platforms/swift/test/Ed25519-Swift-pod/Ed25519-Swift-pod/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /platforms/swift/test/Ed25519-Swift-pod/Ed25519-Swift-pod/Ed25519_Swift_pod.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /platforms/swift/test/Ed25519-Swift-pod/Ed25519-Swift-pod/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2019 Dehacer. All rights reserved. 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /platforms/swift/test/Ed25519-Swift-pod/Ed25519-Swift-podTests/Ed25519_Swift_podTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Ed25519_Swift_podTests.swift 3 | // Ed25519-Swift-podTests 4 | // 5 | // Created by denn on 03/02/2019. 6 | // Copyright © 2019 Dehacer. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import Ed25519_Swift_pod 11 | 12 | class Ed25519_Swift_podTests: XCTestCase { 13 | 14 | override func setUp() { 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | } 21 | 22 | func testExample() { 23 | // This is an example of a functional test case. 24 | // Use XCTAssert and related functions to verify your tests produce the correct results. 25 | } 26 | 27 | func testPerformanceExample() { 28 | // This is an example of a performance test case. 29 | self.measure { 30 | // Put the code you want to measure the time of here. 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /platforms/swift/test/Ed25519-Swift-pod/Ed25519-Swift-podTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /platforms/swift/test/Ed25519-Swift-pod/Podfile: -------------------------------------------------------------------------------- 1 | use_frameworks! 2 | platform :osx, '10.14' 3 | 4 | pre_install do |installer| 5 | # workaround for #3289 6 | Pod::Installer::Xcode::TargetValidator.send(:define_method, :verify_no_static_framework_transitive_dependencies) {} 7 | end 8 | 9 | target 'Ed25519-Swift-pod' do 10 | pod 'ed25519', :path => '../../../../' 11 | 12 | # 13 | # Uncomment in your app: 14 | # 15 | # pod 'MileCsaLight', :git => 'https://github.com/mile-core/mile-csa-api' 16 | end 17 | -------------------------------------------------------------------------------- /src/base58.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by denn on 2019-01-29. 3 | // 4 | 5 | #include "ed25519.hpp" 6 | #include "btc_base58.hpp" 7 | #include 8 | 9 | namespace ed25519{ 10 | 11 | namespace base58 { 12 | 13 | std::string encode(const std::vector &data) { 14 | return EncodeBase58(data); 15 | } 16 | 17 | bool decode(const std::string &str, std::vector &data) { 18 | return DecodeBase58Check(str, data); 19 | } 20 | 21 | bool validate(const std::string &str) { 22 | return Base58Check(str); 23 | } 24 | } 25 | 26 | error_category::error_category(const std::string &message):mess_(message) {} 27 | 28 | const char *error_category::name() const noexcept { 29 | return "base58 error"; 30 | } 31 | 32 | std::string error_category::message(int ev) const { 33 | switch (ev) { 34 | case error::BADFORMAT: 35 | return mess_.empty() ? "base58 check string decode error" : mess_; 36 | case error::UNEXPECTED_SIZE: 37 | return mess_.empty() ? "unexpected data size " : mess_; 38 | case error::EMPTY: 39 | return mess_.empty() ? "data is empty" : mess_; 40 | default: 41 | return std::generic_category().message(ev); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/digest.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by denn on 2019-01-30. 3 | // 4 | 5 | #include "ed25519.h" 6 | #include "ed25519.hpp" 7 | #include "sha3.hpp" 8 | #include "ed25519_ext.hpp" 9 | #include 10 | 11 | #include 12 | 13 | template 14 | constexpr T htonT (T value) noexcept 15 | { 16 | #if __BYTE_ORDER == __LITTLE_ENDIAN 17 | char* ptr = reinterpret_cast(&value); 18 | std::reverse(ptr, ptr + sizeof(T)); 19 | #endif 20 | return value; 21 | } 22 | 23 | namespace ed25519 { 24 | 25 | 26 | struct CalculatorImpl: public Digest::Calculator{ 27 | 28 | void append(const variant_t &value) override; 29 | void set_endian(endian) override ; 30 | endian get_endian() override ; 31 | 32 | explicit CalculatorImpl(Digest *digest): ctx_({}), digest_(digest), endian_(little){ 33 | 34 | if ( htonT(47) == /* DISABLES CODE */ (47) ) { 35 | endian_ = big; 36 | } else { 37 | endian_ = little; 38 | } 39 | 40 | sha3_Init256(&ctx_); 41 | } 42 | 43 | ~CalculatorImpl() { 44 | sha3_Finalize(&ctx_, digest_->data()); 45 | } 46 | 47 | private: 48 | sha3_context ctx_; 49 | Digest *digest_; 50 | Digest::Calculator::endian endian_; 51 | 52 | }; 53 | 54 | 55 | Digest::Digest(const context& handler):Data() { 56 | CalculatorImpl calculator(this); 57 | handler(calculator); 58 | } 59 | 60 | Digest::Digest():Data() {} 61 | 62 | std::optional Digest::Decode(const std::string &base58, const ed25519::ErrorHandler &error) { 63 | auto s = Digest(); 64 | if (s.decode(base58,error)){ 65 | return std::make_optional(s); 66 | } 67 | return std::nullopt; 68 | } 69 | 70 | void CalculatorImpl::set_endian(Digest::Calculator::endian e) { 71 | endian_ = e; 72 | } 73 | 74 | Digest::Calculator::endian CalculatorImpl::get_endian() { 75 | return endian_; 76 | } 77 | 78 | void CalculatorImpl::append(const Digest::Calculator::variant_t &value) { 79 | 80 | ed25519::visit([&](auto&& arg) { 81 | 82 | using T = std::decay_t; 83 | 84 | if constexpr (std::is_same_v){ 85 | unsigned char data = arg ? 1 : 0; 86 | sha3_Update((void *)&ctx_, &data, 1); 87 | } 88 | 89 | else if constexpr (std::is_same_v){ 90 | unsigned char data = arg; 91 | sha3_Update((void *)&ctx_, &data, 1); 92 | } 93 | 94 | else if constexpr (std::is_same_v){ 95 | std::vector message; 96 | if (endian_ == little) 97 | { 98 | message.push_back(static_cast(arg & 0xff)); 99 | message.push_back(static_cast((arg >> 8) & 0xff)); 100 | } 101 | else 102 | { 103 | message.push_back(static_cast((arg >> 8) & 0xff)); 104 | message.push_back(static_cast(arg & 0xff)); 105 | } 106 | sha3_Update(&ctx_, message.data(), message.size()); 107 | } 108 | 109 | else if constexpr (std::is_same_v){ 110 | std::vector message; 111 | 112 | if (endian_ == little) 113 | { 114 | message.push_back(static_cast(arg & 0xff)); 115 | message.push_back(static_cast((arg >> 8) & 0xff)); 116 | message.push_back(static_cast((arg >> 16) & 0xff)); 117 | message.push_back(static_cast((arg >> 24) & 0xff)); 118 | } 119 | else 120 | { 121 | message.push_back(static_cast((arg >> 24) & 0xff)); 122 | message.push_back(static_cast((arg >> 16) & 0xff)); 123 | message.push_back(static_cast((arg >> 8) & 0xff)); 124 | message.push_back(static_cast(arg & 0xff)); 125 | } 126 | sha3_Update(&ctx_, message.data(), message.size()); 127 | } 128 | 129 | else if constexpr (std::is_same_v){ 130 | sha3_Update(&ctx_, arg.data(), arg.size()); 131 | } 132 | 133 | else if constexpr (std::is_same_v>){ 134 | sha3_Update(&ctx_, arg.data(), arg.size()); 135 | } 136 | 137 | else if constexpr (std::is_same_v>){ 138 | sha3_Update(&ctx_, arg.data(), arg.size()); 139 | } 140 | 141 | else if constexpr (std::is_same_v>){ 142 | sha3_Update(&ctx_, arg.data(), arg.size()); 143 | } 144 | 145 | 146 | }, value); 147 | 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /src/ed25519.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by denn on 2019-01-29. 3 | // 4 | 5 | #include "ed25519.h" 6 | #include "ed25519.hpp" 7 | #include "sha3.hpp" 8 | #include "ed25519_ext.hpp" 9 | #include 10 | #include 11 | 12 | namespace ed25519 { 13 | 14 | Seed::Seed(const std::string &phrase) { 15 | fill(0); 16 | sha3_256((const unsigned char*) phrase.c_str(), phrase.length(), this->data()); 17 | } 18 | 19 | Seed::Seed():seed_data() { 20 | fill(0); 21 | ed25519_create_seed(this->data()); 22 | } 23 | 24 | namespace keys { 25 | 26 | std::optional Public::Decode(const std::string &base58, const ErrorHandler &error){ 27 | auto s = Public(); 28 | if (s.decode(base58,error)){ 29 | return std::make_optional(s); 30 | } 31 | return std::nullopt; 32 | } 33 | 34 | std::optional Private::Decode(const std::string &base58, const ErrorHandler &error){ 35 | auto s = Private(); 36 | if (s.decode(base58,error)){ 37 | return std::make_optional(s); 38 | } 39 | return std::nullopt; 40 | } 41 | 42 | Pair::Pair() { 43 | clean(); 44 | } 45 | 46 | std::optional Pair::Random() { 47 | 48 | Pair pair; 49 | 50 | Seed seed; 51 | ed25519_create_keypair(pair.publicKey_.data(), pair.privateKey_.data(), seed.data()); 52 | return std::make_optional(pair); 53 | } 54 | 55 | std::optional Pair::FromPrivateKey(const std::string &privateKey, const ErrorHandler &error) { 56 | 57 | if (privateKey.empty()) 58 | { 59 | std::error_code ec(static_cast(error::EMPTY),error_category("private keyis empty")); 60 | error(ec); 61 | return std::nullopt; 62 | } 63 | 64 | auto pair = Pair(); 65 | 66 | if (!pair.privateKey_.decode(privateKey, error)) 67 | { 68 | return std::nullopt; 69 | } 70 | 71 | ed25519_restore_from_private_key(pair.publicKey_.data(), pair.privateKey_.data()); 72 | 73 | return std::make_optional(pair); 74 | } 75 | 76 | std::optional Pair::WithSecret(const std::string &phrase, 77 | const ed25519::ErrorHandler &error) { 78 | if (phrase.empty()) 79 | { 80 | std::error_code ec(static_cast(error::EMPTY),error_category("secret phrase is empty")); 81 | error(ec); 82 | return std::nullopt; 83 | } 84 | 85 | Pair pair; 86 | Seed seed(phrase); 87 | ed25519_create_keypair(pair.publicKey_.data(), pair.privateKey_.data(), seed.data()); 88 | 89 | return std::make_optional(pair); 90 | } 91 | 92 | void Pair::clean() { 93 | publicKey_.clean(); 94 | privateKey_.clean(); 95 | } 96 | 97 | bool Pair::validate() { 98 | return publicKey_.validate() && privateKey_.validate(); 99 | } 100 | 101 | std::unique_ptr Pair::sign(const std::vector& message){ 102 | 103 | auto signature = std::unique_ptr{new Signature()}; 104 | 105 | ed25519_sign(signature->data(), 106 | message.data(), message.size(), 107 | publicKey_.data(), 108 | privateKey_.data()); 109 | 110 | return signature; 111 | } 112 | 113 | std::unique_ptr Pair::sign(const std::string &message){ 114 | std::vector v(message.begin(), message.end()); 115 | return sign(v); 116 | } 117 | 118 | std::unique_ptr Pair::sign(const Digest& digest){ 119 | 120 | auto signature = std::unique_ptr{new Signature()}; 121 | 122 | ed25519_sign(signature->data(), 123 | digest.data(), digest.size(), 124 | publicKey_.data(), 125 | privateKey_.data()); 126 | 127 | return signature; 128 | } 129 | } 130 | 131 | std::optional Signature::Decode(const std::string &base58, const ErrorHandler &error){ 132 | auto s = Signature(); 133 | if (s.decode(base58,error)){ 134 | return std::make_optional(s); 135 | } 136 | return std::nullopt; 137 | } 138 | 139 | bool Signature::verify(const ed25519::Digest &digest, const ed25519::keys::Public &key) const { 140 | return ed25519_verify(data(), digest.data(), digest.size(), key.data()) == 1; 141 | } 142 | 143 | bool Signature::verify(const std::string &message, const ed25519::keys::Public &key) const { 144 | std::vector v(message.begin(), message.end()); 145 | return verify(v,key); 146 | } 147 | 148 | bool Signature::verify(const std::vector &message, const ed25519::keys::Public &key) const { 149 | return ed25519_verify(data(), message.data(), message.size(), key.data()) == 1; 150 | } 151 | 152 | } 153 | -------------------------------------------------------------------------------- /src/external/btc_base58.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by denn on 2019-01-29. 3 | // 4 | 5 | // Copyright (c) 2014-2016 The Bitcoin Core developers 6 | // Distributed under the MIT software license, see the accompanying 7 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 8 | 9 | 10 | #include "btc_base58.hpp" 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | 19 | /** All alphanumeric characters except for "0", "I", "O", and "l" */ 20 | static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; 21 | 22 | namespace ed25519::base58 { 23 | 24 | 25 | string BinToHex(const vector &data) { 26 | // note: optimize 27 | string convert; 28 | convert.reserve(data.size() * 2 + 2); 29 | std::stringstream s(convert); 30 | s << std::hex; 31 | for (size_t i = 0; i < data.size(); i++) { 32 | s << std::setw(2) << std::setfill('0') << (unsigned int) data[i]; 33 | } 34 | return s.str(); 35 | } 36 | 37 | bool HexToBin(const string &hexString, vector &data, string &errorDescription) { 38 | // code 255 means error 39 | static unsigned char sDecLookupTable[] = 40 | { 41 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 42 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 43 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 44 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, // 0123456789 45 | 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, // ABCDEF 46 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 47 | 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, // abcdef 48 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 49 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 50 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 51 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 52 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 53 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 54 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 55 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 57 | }; 58 | 59 | errorDescription = ""; 60 | data.clear(); 61 | 62 | if ((hexString.size() & 1) != 0) { 63 | errorDescription = StringFormat("string with odd size: %zu bytes", hexString.size()); 64 | return false; 65 | } 66 | 67 | size_t binarySize = hexString.size() >> 1; // /2 68 | 69 | data.resize(binarySize); 70 | 71 | for (size_t i = 0, j = 0; i < binarySize; i++, j += 2) { 72 | unsigned char h1 = hexString[j]; 73 | unsigned char h0 = hexString[j + 1]; 74 | // 75 | unsigned char c1 = sDecLookupTable[h1]; 76 | unsigned char c0 = sDecLookupTable[h0]; 77 | // check for errors 78 | if (c1 == 255 || c0 == 255) { 79 | errorDescription = StringFormat("bad %u hex symbol '%c%c'", i, h1, h0); 80 | return false; 81 | } 82 | data[i] = (c1 << 4) | c0; 83 | } 84 | 85 | return true; 86 | } 87 | 88 | bool HexStringToUchar(const string &hexString, unsigned char &value) { 89 | if (hexString.empty()) { 90 | return false; 91 | } 92 | 93 | string s = hexString; 94 | 95 | if (s.size() > 2 && s[0] == '0' && s[1] == 'x') { 96 | s = hexString.substr(2); 97 | } 98 | 99 | if (s.size() > (sizeof(unsigned char) * 2)) { 100 | return false; 101 | } 102 | 103 | unsigned int v = 0; 104 | std::stringstream ss; 105 | ss << std::hex << s; 106 | ss >> v; 107 | 108 | // check that all symbols are processed e.g. 0xfz -> error 109 | if (ss.fail() || !ss.eof()) { 110 | return false; 111 | } 112 | 113 | if (v > static_cast(std::numeric_limits::max())) { 114 | return false; 115 | } 116 | 117 | value = static_cast(v); 118 | 119 | return true; 120 | } 121 | 122 | uint_least32_t crc32(unsigned char *buf, size_t len) { 123 | uint_least32_t crc_table[256] = {}; 124 | uint_least32_t crc = {}; 125 | 126 | for (int i = 0; i < 256; i++) { 127 | crc = i; 128 | for (int j = 0; j < 8; j++) { 129 | crc = crc & 1 ? (crc >> 1) ^ 0xEDB88320UL : crc >> 1; 130 | } 131 | crc_table[i] = crc; 132 | } 133 | 134 | crc = 0xFFFFFFFFUL; 135 | while (len--) { 136 | crc = crc_table[(crc ^ *buf++) & 0xFF] ^ (crc >> 8); 137 | } 138 | 139 | return crc ^ 0xFFFFFFFFUL; 140 | } 141 | 142 | bool DecodeBase58(const char *psz, vector &vch) { 143 | // Skip leading spaces. 144 | while (*psz && isspace(*psz)) 145 | psz++; 146 | // Skip and count leading '1's. 147 | int zeroes = 0; 148 | int length = 0; 149 | while (*psz == '1') { 150 | zeroes++; 151 | psz++; 152 | } 153 | // Allocate enough space in big-endian base256 representation. 154 | int size = (int) strlen(psz) * 733 / 1000 + 1; // log(58) / log(256), rounded up. 155 | std::vector b256(size); 156 | // Process the characters. 157 | while (*psz && !isspace(*psz)) { 158 | // Decode base58 character 159 | const char *ch = strchr(pszBase58, *psz); 160 | if (ch == nullptr) 161 | return false; 162 | // Apply "b256 = b256 * 58 + ch". 163 | int carry = (int) (ch - pszBase58); 164 | int i = 0; 165 | for (std::vector::reverse_iterator it = b256.rbegin(); 166 | (carry != 0 || i < length) && (it != b256.rend()); ++it, ++i) { 167 | carry += 58 * (*it); 168 | *it = carry % 256; 169 | carry /= 256; 170 | } 171 | assert(carry == 0); 172 | length = i; 173 | psz++; 174 | } 175 | // Skip trailing spaces. 176 | while (isspace(*psz)) 177 | psz++; 178 | if (*psz != 0) 179 | return false; 180 | // Skip leading zeroes in b256. 181 | std::vector::iterator it = b256.begin() + (size - length); 182 | while (it != b256.end() && *it == 0) 183 | it++; 184 | // Copy result into output vector. 185 | vch.reserve(zeroes + (b256.end() - it)); 186 | vch.assign(zeroes, 0x00); 187 | while (it != b256.end()) 188 | vch.push_back(*(it++)); 189 | return true; 190 | } 191 | 192 | std::string EncodeBase58(const unsigned char *pbegin, const unsigned char *pend) { 193 | // Skip & count leading zeroes. 194 | int zeroes = 0; 195 | int length = 0; 196 | while (pbegin != pend && *pbegin == 0) { 197 | pbegin++; 198 | zeroes++; 199 | } 200 | // Allocate enough space in big-endian base58 representation. 201 | int size = (int) (pend - pbegin) * 138 / 100 + 1; // log(256) / log(58), rounded up. 202 | std::vector b58(size); 203 | // Process the bytes. 204 | while (pbegin != pend) { 205 | int carry = *pbegin; 206 | int i = 0; 207 | // Apply "b58 = b58 * 256 + ch". 208 | for (std::vector::reverse_iterator it = b58.rbegin(); 209 | (carry != 0 || i < length) && (it != b58.rend()); it++, i++) { 210 | carry += 256 * (*it); 211 | *it = carry % 58; 212 | carry /= 58; 213 | } 214 | 215 | assert(carry == 0); 216 | length = i; 217 | pbegin++; 218 | } 219 | // Skip leading zeroes in base58 result. 220 | std::vector::iterator it = b58.begin() + (size - length); 221 | while (it != b58.end() && *it == 0) 222 | it++; 223 | // Translate the result into a string. 224 | std::string str; 225 | str.reserve(zeroes + (b58.end() - it)); 226 | str.assign(zeroes, '1'); 227 | while (it != b58.end()) { 228 | str += pszBase58[*(it++)]; 229 | } 230 | 231 | return str; 232 | } 233 | 234 | string EncodeBase58(const vector &vch) { 235 | return EncodeBase58(vch.data(), vch.data() + vch.size()); 236 | } 237 | 238 | bool DecodeBase58(const string &str, vector &vchRet) { 239 | return DecodeBase58(str.c_str(), vchRet); 240 | } 241 | 242 | string EncodeBase58Check(const vector &vchIn) { 243 | // add 4-byte hash check to the end 244 | vector vch(vchIn); 245 | 246 | // uint256 hash = Hash(vch.begin(), vch.end()); 247 | // vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4); 248 | 249 | uint_least32_t crc32_ = crc32(&vch[0], vch.size()); 250 | // little endian 251 | vch.push_back(static_cast(crc32_ & 0xff)); 252 | vch.push_back(static_cast((crc32_ >> 8) & 0xff)); 253 | vch.push_back(static_cast((crc32_ >> 16) & 0xff)); 254 | vch.push_back(static_cast((crc32_ >> 24) & 0xff)); 255 | 256 | return EncodeBase58(vch); 257 | } 258 | 259 | bool DecodeBase58Check(const char *psz, vector &vchRet) { 260 | if (!DecodeBase58(psz, vchRet) || (vchRet.size() < 4)) { 261 | vchRet.clear(); 262 | return false; 263 | } 264 | // re-calculate the checksum, ensure it matches the included 4-byte checksum 265 | // uint256 hash = Hash(vchRet.begin(), vchRet.end() - 4); 266 | // if (memcmp(&hash, &vchRet[vchRet.size() - 4], 4) != 0) { 267 | // vchRet.clear(); 268 | // return false; 269 | // } 270 | size_t sz = vchRet.size(); 271 | // 272 | uint_least32_t crc32_ = crc32(&vchRet[0], sz - 4); 273 | // 274 | if (static_cast(crc32_ & 0xff) != vchRet[sz - 4] || 275 | static_cast((crc32_ >> 8) & 0xff) != vchRet[sz - 3] || 276 | static_cast((crc32_ >> 16) & 0xff) != vchRet[sz - 2] || 277 | static_cast((crc32_ >> 24) & 0xff) != vchRet[sz - 1]) { 278 | vchRet.clear(); 279 | return false; 280 | } 281 | vchRet.resize(vchRet.size() - 4); 282 | 283 | return true; 284 | } 285 | 286 | bool DecodeBase58Check(const string &str, vector &vchRet) { 287 | return DecodeBase58Check(str.c_str(), vchRet); 288 | } 289 | 290 | /// TODO: 291 | /// . make more effective 292 | bool Base58Check(const string &str) { 293 | vector vchRet; 294 | return DecodeBase58Check(str.c_str(), vchRet); 295 | } 296 | } -------------------------------------------------------------------------------- /src/external/btc_base58.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2010 Satoshi Nakamoto 2 | // Copyright (c) 2009-2015 The Bitcoin Core developers 3 | // Distributed under the MIT software license, see the accompanying 4 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 5 | // 6 | // 7 | 8 | /** 9 | * Why base-58 instead of standard base-64 encoding? 10 | * - Don't want 0OIl characters that look the same in some fonts and 11 | * could be used to create visually identical looking data. 12 | * - A string with non-alphanumeric characters is not as easily accepted as input. 13 | * - E-mail usually won't line-break if there's no punctuation to break at. 14 | * - Double-clicking selects the whole string as one word if it's all alphanumeric. 15 | */ 16 | #ifndef ED25512__BITCOIN_BASE58_H 17 | #define ED25512__BITCOIN_BASE58_H 18 | 19 | #include "ed25519.hpp" 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | using std::string; 27 | using std::vector; 28 | using std::array; 29 | 30 | namespace ed25519::base58 { 31 | /** 32 | * Encode a byte vector as a base58-encoded string 33 | */ 34 | string EncodeBase58(const vector &vch); 35 | 36 | 37 | /** 38 | * Decode a base58-encoded string (str) that includes a checksum into a byte 39 | * vector (vchRet), return true if decoding is successful 40 | */ 41 | bool DecodeBase58Check(const string &str, vector &vchRet); 42 | 43 | /** 44 | * Check base58-encoded string 45 | * @param str - base58 encoded string 46 | * @return true if it is right 47 | */ 48 | bool Base58Check(const string &str); 49 | } 50 | 51 | 52 | #endif // ED25512__BITCOIN_BASE58_H 53 | -------------------------------------------------------------------------------- /src/external/ed25519_ext.cpp: -------------------------------------------------------------------------------- 1 | #include "sha512.h" 2 | #include "ge.h" 3 | #include "ed25519_ext.hpp" 4 | 5 | void ed25519_restore_from_private_key(unsigned char *public_key, const unsigned char *private_key) 6 | { 7 | ge_p3 A; 8 | 9 | ge_scalarmult_base(&A, private_key); 10 | ge_p3_tobytes(public_key, &A); 11 | } -------------------------------------------------------------------------------- /src/external/ed25519_ext.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ED25519_EXT_H 2 | #define ED25519_EXT_H 3 | 4 | void ed25519_restore_from_private_key(unsigned char *public_key, const unsigned char *private_key); 5 | 6 | #endif -------------------------------------------------------------------------------- /src/external/sha3.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* ------------------------------------------------------------------------- 3 | * Works when compiled for either 32-bit or 64-bit targets, optimized for 4 | * 64 bit. 5 | * 6 | * Canonical implementation of Init/Update/Finalize for SHA-3 byte input. 7 | * 8 | * SHA3-256, SHA3-384, SHA-512 are implemented. SHA-224 can easily be added. 9 | * 10 | * Based on code from http://keccak.noekeon.org/ . 11 | * 12 | * I place the code that I wrote into public domain, free to use. 13 | * 14 | * I would appreciate if you give credits to this work if you used it to 15 | * write or test * your code. 16 | * 17 | * Aug 2015. Andrey Jivsov. crypto@brainhub.org 18 | * ---------------------------------------------------------------------- */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include "sha3.hpp" 24 | 25 | #define SHA3_ASSERT( x ) 26 | #if defined(_MSC_VER) 27 | #define SHA3_TRACE( format, ...) 28 | #define SHA3_TRACE_BUF( format, buf, l, ...) 29 | #else 30 | #define SHA3_TRACE(format, args...) 31 | #define SHA3_TRACE_BUF(format, buf, l, args...) 32 | #endif 33 | 34 | //#define SHA3_USE_KECCAK 35 | /* 36 | * Define SHA3_USE_KECCAK to run "pure" Keccak, as opposed to SHA3. 37 | * The tests that this macro enables use the input and output from [Keccak] 38 | * (see the reference below). The used test vectors aren't correct for SHA3, 39 | * however, they are helpful to verify the implementation. 40 | * SHA3_USE_KECCAK only changes one line of code in Finalize. 41 | */ 42 | 43 | #if defined(_MSC_VER) 44 | #define SHA3_CONST(x) x 45 | #else 46 | #define SHA3_CONST(x) x##L 47 | #endif 48 | 49 | /* The following state definition should normally be in a separate 50 | * header file 51 | */ 52 | 53 | 54 | 55 | static const uint64_t keccakf_rndc[24] = { 56 | SHA3_CONST(0x0000000000000001UL), SHA3_CONST(0x0000000000008082UL), 57 | SHA3_CONST(0x800000000000808aUL), SHA3_CONST(0x8000000080008000UL), 58 | SHA3_CONST(0x000000000000808bUL), SHA3_CONST(0x0000000080000001UL), 59 | SHA3_CONST(0x8000000080008081UL), SHA3_CONST(0x8000000000008009UL), 60 | SHA3_CONST(0x000000000000008aUL), SHA3_CONST(0x0000000000000088UL), 61 | SHA3_CONST(0x0000000080008009UL), SHA3_CONST(0x000000008000000aUL), 62 | SHA3_CONST(0x000000008000808bUL), SHA3_CONST(0x800000000000008bUL), 63 | SHA3_CONST(0x8000000000008089UL), SHA3_CONST(0x8000000000008003UL), 64 | SHA3_CONST(0x8000000000008002UL), SHA3_CONST(0x8000000000000080UL), 65 | SHA3_CONST(0x000000000000800aUL), SHA3_CONST(0x800000008000000aUL), 66 | SHA3_CONST(0x8000000080008081UL), SHA3_CONST(0x8000000000008080UL), 67 | SHA3_CONST(0x0000000080000001UL), SHA3_CONST(0x8000000080008008UL) 68 | }; 69 | 70 | static const unsigned keccakf_rotc[24] = { 71 | 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 27, 41, 56, 8, 25, 43, 62, 72 | 18, 39, 61, 20, 44 73 | }; 74 | 75 | static const unsigned keccakf_piln[24] = { 76 | 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23, 19, 13, 12, 2, 20, 77 | 14, 22, 9, 6, 1 78 | }; 79 | 80 | /* generally called after SHA3_KECCAK_SPONGE_WORDS-ctx->capacityWords words 81 | * are XORed into the state s 82 | */ 83 | static void 84 | keccakf(uint64_t s[25]) 85 | { 86 | int i, j, round; 87 | uint64_t t, bc[5]; 88 | #define KECCAK_ROUNDS 24 89 | 90 | for(round = 0; round < KECCAK_ROUNDS; round++) { 91 | 92 | /* Theta */ 93 | for(i = 0; i < 5; i++) 94 | bc[i] = s[i] ^ s[i + 5] ^ s[i + 10] ^ s[i + 15] ^ s[i + 20]; 95 | 96 | for(i = 0; i < 5; i++) { 97 | t = bc[(i + 4) % 5] ^ SHA3_ROTL64(bc[(i + 1) % 5], 1); 98 | for(j = 0; j < 25; j += 5) 99 | s[j + i] ^= t; 100 | } 101 | 102 | /* Rho Pi */ 103 | t = s[1]; 104 | for(i = 0; i < 24; i++) { 105 | j = keccakf_piln[i]; 106 | bc[0] = s[j]; 107 | s[j] = SHA3_ROTL64(t, keccakf_rotc[i]); 108 | t = bc[0]; 109 | } 110 | 111 | /* Chi */ 112 | for(j = 0; j < 25; j += 5) { 113 | for(i = 0; i < 5; i++) 114 | bc[i] = s[j + i]; 115 | for(i = 0; i < 5; i++) 116 | s[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5]; 117 | } 118 | 119 | /* Iota */ 120 | s[0] ^= keccakf_rndc[round]; 121 | } 122 | } 123 | 124 | /* *************************** Public Inteface ************************ */ 125 | 126 | /* For Init or Reset call these: */ 127 | void 128 | sha3_Init256(void *priv) 129 | { 130 | sha3_context *ctx = (sha3_context *) priv; 131 | memset(ctx, 0, sizeof(*ctx)); 132 | ctx->capacityWords = 2 * 256 / (8 * sizeof(uint64_t)); 133 | ctx->numOutputBytes = 32; 134 | } 135 | 136 | void 137 | sha3_Init384(void *priv) 138 | { 139 | sha3_context *ctx = (sha3_context *) priv; 140 | memset(ctx, 0, sizeof(*ctx)); 141 | ctx->capacityWords = 2 * 384 / (8 * sizeof(uint64_t)); 142 | ctx->numOutputBytes = 48; 143 | } 144 | 145 | void 146 | sha3_Init512(void *priv) 147 | { 148 | sha3_context *ctx = (sha3_context *) priv; 149 | memset(ctx, 0, sizeof(*ctx)); 150 | ctx->capacityWords = 2 * 512 / (8 * sizeof(uint64_t)); 151 | ctx->numOutputBytes = 64; 152 | } 153 | 154 | void 155 | sha3_Update(void *priv, void const *bufIn, size_t len) 156 | { 157 | sha3_context *ctx = (sha3_context *) priv; 158 | 159 | /* 0...7 -- how much is needed to have a word */ 160 | unsigned old_tail = (8 - ctx->byteIndex) & 7; 161 | 162 | size_t words; 163 | unsigned tail; 164 | size_t i; 165 | 166 | const uint8_t *buf = (const uint8_t*) bufIn; 167 | 168 | SHA3_TRACE_BUF("called to update with:", buf, len); 169 | 170 | SHA3_ASSERT(ctx->byteIndex < 8); 171 | SHA3_ASSERT(ctx->wordIndex < sizeof(ctx->s) / sizeof(ctx->s[0])); 172 | 173 | if(len < old_tail) { /* have no complete word or haven't started 174 | * the word yet */ 175 | SHA3_TRACE("because %d<%d, store it and return", (unsigned)len, 176 | (unsigned)old_tail); 177 | /* endian-independent code follows: */ 178 | while (len--) 179 | ctx->saved |= (uint64_t) (*(buf++)) << ((ctx->byteIndex++) * 8); 180 | SHA3_ASSERT(ctx->byteIndex < 8); 181 | return; 182 | } 183 | 184 | if(old_tail) { /* will have one word to process */ 185 | SHA3_TRACE("completing one word with %d bytes", (unsigned)old_tail); 186 | /* endian-independent code follows: */ 187 | len -= old_tail; 188 | while (old_tail--) 189 | ctx->saved |= (uint64_t) (*(buf++)) << ((ctx->byteIndex++) * 8); 190 | 191 | /* now ready to add saved to the sponge */ 192 | ctx->s[ctx->wordIndex] ^= ctx->saved; 193 | SHA3_ASSERT(ctx->byteIndex == 8); 194 | ctx->byteIndex = 0; 195 | ctx->saved = 0; 196 | if(++ctx->wordIndex == 197 | (SHA3_KECCAK_SPONGE_WORDS - ctx->capacityWords)) { 198 | keccakf(ctx->s); 199 | ctx->wordIndex = 0; 200 | } 201 | } 202 | 203 | /* now work in full words directly from input */ 204 | 205 | SHA3_ASSERT(ctx->byteIndex == 0); 206 | 207 | words = len / sizeof(uint64_t); 208 | tail = (unsigned)(len - words * sizeof(uint64_t)); 209 | 210 | SHA3_TRACE("have %d full words to process", (unsigned)words); 211 | 212 | for(i = 0; i < words; i++, buf += sizeof(uint64_t)) { 213 | const uint64_t t = (uint64_t) (buf[0]) | 214 | ((uint64_t) (buf[1]) << 8 * 1) | 215 | ((uint64_t) (buf[2]) << 8 * 2) | 216 | ((uint64_t) (buf[3]) << 8 * 3) | 217 | ((uint64_t) (buf[4]) << 8 * 4) | 218 | ((uint64_t) (buf[5]) << 8 * 5) | 219 | ((uint64_t) (buf[6]) << 8 * 6) | 220 | ((uint64_t) (buf[7]) << 8 * 7); 221 | #if defined(__x86_64__ ) || defined(__i386__) 222 | SHA3_ASSERT(memcmp(&t, buf, 8) == 0); 223 | #endif 224 | ctx->s[ctx->wordIndex] ^= t; 225 | if(++ctx->wordIndex == 226 | (SHA3_KECCAK_SPONGE_WORDS - ctx->capacityWords)) { 227 | keccakf(ctx->s); 228 | ctx->wordIndex = 0; 229 | } 230 | } 231 | 232 | SHA3_TRACE("have %d bytes left to process, save them", (unsigned)tail); 233 | 234 | /* finally, save the partial word */ 235 | SHA3_ASSERT(ctx->byteIndex == 0 && tail < 8); 236 | while (tail--) { 237 | SHA3_TRACE("Store byte %02x '%c'", *buf, *buf); 238 | ctx->saved |= (uint64_t) (*(buf++)) << ((ctx->byteIndex++) * 8); 239 | } 240 | SHA3_ASSERT(ctx->byteIndex < 8); 241 | SHA3_TRACE("Have saved=0x%016" PRIx64 " at the end", ctx->saved); 242 | } 243 | 244 | /* This is simply the 'update' with the padding block. 245 | * The padding block is 0x01 || 0x00* || 0x80. First 0x01 and last 0x80 246 | * bytes are always present, but they can be the same byte. 247 | */ 248 | void sha3_Finalize(void *priv, unsigned char *out) 249 | { 250 | sha3_context *ctx = (sha3_context *) priv; 251 | 252 | SHA3_TRACE("called with %d bytes in the buffer", ctx->byteIndex); 253 | 254 | /* Append 2-bit suffix 01, per SHA-3 spec. Instead of 1 for padding we 255 | * use 1<<2 below. The 0x02 below corresponds to the suffix 01. 256 | * Overall, we feed 0, then 1, and finally 1 to start padding. Without 257 | * M || 01, we would simply use 1 to start padding. */ 258 | 259 | #ifndef SHA3_USE_KECCAK 260 | /* SHA3 version */ 261 | ctx->s[ctx->wordIndex] ^= 262 | (ctx->saved ^ ((uint64_t) ((uint64_t) (0x02 | (1 << 2)) << 263 | ((ctx->byteIndex) * 8)))); 264 | #else 265 | /* For testing the "pure" Keccak version */ 266 | ctx->s[ctx->wordIndex] ^= 267 | (ctx->saved ^ ((uint64_t) ((uint64_t) 1 << (ctx->byteIndex * 268 | 8)))); 269 | #endif 270 | 271 | ctx->s[SHA3_KECCAK_SPONGE_WORDS - ctx->capacityWords - 1] ^= 272 | SHA3_CONST(0x8000000000000000UL); 273 | keccakf(ctx->s); 274 | 275 | /* Return first bytes of the ctx->s. This conversion is not needed for 276 | * little-endian platforms e.g. wrap with #if !defined(__BYTE_ORDER__) 277 | * || !defined(__ORDER_LITTLE_ENDIAN__) || \ 278 | * __BYTE_ORDER__!=__ORDER_LITTLE_ENDIAN__ ... the conversion below ... 279 | * #endif */ 280 | { 281 | unsigned i; 282 | for(i = 0; i < SHA3_KECCAK_SPONGE_WORDS; i++) { 283 | const unsigned t1 = (uint32_t) ctx->s[i]; 284 | const unsigned t2 = (uint32_t) ((ctx->s[i] >> 16) >> 16); 285 | ctx->sb[i * 8 + 0] = (uint8_t) (t1); 286 | ctx->sb[i * 8 + 1] = (uint8_t) (t1 >> 8); 287 | ctx->sb[i * 8 + 2] = (uint8_t) (t1 >> 16); 288 | ctx->sb[i * 8 + 3] = (uint8_t) (t1 >> 24); 289 | ctx->sb[i * 8 + 4] = (uint8_t) (t2); 290 | ctx->sb[i * 8 + 5] = (uint8_t) (t2 >> 8); 291 | ctx->sb[i * 8 + 6] = (uint8_t) (t2 >> 16); 292 | ctx->sb[i * 8 + 7] = (uint8_t) (t2 >> 24); 293 | } 294 | } 295 | 296 | unsigned i; 297 | for (i = 0; i < ctx->numOutputBytes; i++) { 298 | out[i] = ctx->sb[i]; 299 | } 300 | SHA3_TRACE_BUF("Hash: (first 32 bytes)", ctx->sb, 256 / 8); 301 | 302 | } 303 | 304 | 305 | void sha3_256(const unsigned char *message, size_t message_len, unsigned char *out) { 306 | sha3_context ctx; 307 | 308 | sha3_Init256(&ctx); 309 | sha3_Update(&ctx, message, message_len); 310 | sha3_Finalize(&ctx, out); 311 | } 312 | 313 | void sha3_384(const unsigned char *message, size_t message_len, unsigned char *out) { 314 | sha3_context ctx; 315 | 316 | sha3_Init384(&ctx); 317 | sha3_Update(&ctx, message, message_len); 318 | sha3_Finalize(&ctx, out); 319 | } 320 | 321 | void sha3_512(const unsigned char *message, size_t message_len, unsigned char *out) { 322 | sha3_context ctx; 323 | 324 | sha3_Init512(&ctx); 325 | sha3_Update(&ctx, message, message_len); 326 | sha3_Finalize(&ctx, out); 327 | } 328 | -------------------------------------------------------------------------------- /src/external/sha3.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // sha3.h 3 | // SpirtualCoin 4 | // 5 | // Created by Kaji Satoshi on 2016/09/07. 6 | // Copyright © 2016年 Kaji Satoshi. All rights reserved. 7 | // 8 | 9 | #ifndef _SHA3_H 10 | #define _SHA3_H 11 | 12 | #include 13 | #include 14 | 15 | /* 'Words' here refers to uint64_t */ 16 | #define SHA3_KECCAK_SPONGE_WORDS \ 17 | (((1600)/8/*bits to byte*/)/sizeof(uint64_t)) 18 | 19 | /* 'Words' here refers to uint64_t */ 20 | 21 | 22 | #ifndef SHA3_ROTL64 23 | #define SHA3_ROTL64(x, y) \ 24 | (((x) << (y)) | ((x) >> ((sizeof(uint64_t)*8) - (y)))) 25 | #endif 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | typedef struct sha3_context_ { 31 | uint64_t saved; /* the portion of the input message that we 32 | * didn't consume yet */ 33 | union { /* Keccak's state */ 34 | uint64_t s[SHA3_KECCAK_SPONGE_WORDS]; 35 | uint8_t sb[SHA3_KECCAK_SPONGE_WORDS * 8]; 36 | }; 37 | unsigned byteIndex; /* 0..7--the next byte after the set one 38 | * (starts from 0; 0--none are buffered) */ 39 | unsigned wordIndex; /* 0..24--the next word to integrate input 40 | * (starts from 0) */ 41 | unsigned capacityWords; 42 | 43 | unsigned numOutputBytes;/* the double size of the hash output in 44 | * words (e.g. 16 for Keccak 512) */ 45 | } sha3_context; 46 | 47 | void sha3_Init256(void *priv); 48 | void sha3_Init384(void *priv); 49 | void sha3_Init512(void *priv); 50 | void sha3_Update(void *priv, void const *bufIn, size_t len); 51 | void sha3_Finalize(void *priv, unsigned char *out); 52 | void sha3_256(const unsigned char *message, size_t message_len, unsigned char *out); 53 | void sha3_384(const unsigned char *message, size_t message_len, unsigned char *out); 54 | void sha3_512(const unsigned char *message, size_t message_len, unsigned char *out); 55 | 56 | #ifdef __cplusplus 57 | } 58 | #endif 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /src/utils.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by denn on 2019-01-29. 3 | // 4 | #include 5 | #include 6 | #include 7 | #include "ed25519.hpp" 8 | 9 | namespace ed25519 { 10 | std::string StringFormat(const char* format, ...) 11 | { 12 | char buffer[1024] = {}; 13 | va_list ap = {}; 14 | 15 | va_start(ap, format); 16 | vsnprintf(buffer, sizeof(buffer), format, ap); 17 | va_end(ap); 18 | 19 | return std::string(buffer); 20 | } 21 | } -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | add_subdirectory(api) 3 | add_subdirectory(digest) 4 | add_subdirectory(performance) 5 | enable_testing () 6 | -------------------------------------------------------------------------------- /test/api/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if (GTEST_FOUND) 2 | include_directories(${GTEST_INCLUDE_DIRS}) 3 | set(TEST_LIBRARIES ${GTEST_BOTH_LIBRARIES}) 4 | else() 5 | message("Googletest ${TEST} RELEASE MODE: ${CMAKE_BUILD_TYPE}") 6 | set(TEST_LIBRARIES gtest;gtest_main) 7 | endif() 8 | 9 | if (NOT WIN32) 10 | set(TEST_LIBRARIES ${TEST_LIBRARIES};pthread) 11 | endif () 12 | 13 | message("TEST_LIBRARIES ${TEST_LIBRARIES}") 14 | 15 | file (GLOB TESTS_SOURCES ${TESTS_SOURCES} 16 | ./*.cpp 17 | ) 18 | 19 | file (GLOB TESTS_SOURCES ${TESTS_SOURCES} 20 | ./*.cpp 21 | ) 22 | 23 | set (TEST api_${PROJECT_LIB}) 24 | 25 | add_executable(${TEST} ${TESTS_SOURCES}) 26 | 27 | target_link_libraries ( 28 | ${TEST} 29 | PRIVATE 30 | ${PROJECT_LIB} 31 | ${TEST_LIBRARIES} 32 | #GTest::gtest GTest::gtest_main 33 | ) 34 | 35 | if (COMMON_DEPENDENCIES) 36 | message(STATUS "${TEST} DEPENDENCIES: ${COMMON_DEPENDENCIES}") 37 | add_dependencies( 38 | ${TEST} 39 | ${COMMON_DEPENDENCIES} 40 | ) 41 | endif () 42 | 43 | add_test (test ${TEST}) 44 | -------------------------------------------------------------------------------- /test/api/api_test.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by denn on 2019-01-29. 3 | // 4 | 5 | #include "ed25519.hpp" 6 | #include 7 | #include "gtest/gtest.h" 8 | 9 | #define ALL_TESTS 1 10 | 11 | #define GOUT(STREAM) \ 12 | do \ 13 | { \ 14 | std::cout << "[MESSAGE ] "<< STREAM << std::endl; \ 15 | } while (false); 16 | 17 | auto error_handler = [](const std::error_code code){ 18 | GOUT("Test error: " + ed25519::StringFormat("code: %i, message: %s", code.value(), + code.message().c_str())); 19 | }; 20 | 21 | 22 | TEST(TEST_API, ed25519_api_initial ){ 23 | std::cout << "ed25519_api_initial" << std::endl; 24 | } 25 | 26 | #if ALL_TESTS 27 | 28 | TEST(TEST_API, ed25519_api ){ 29 | 30 | ed25519::Seed seed; 31 | 32 | std::string ssed = ed25519::base58::encode(seed).c_str(); 33 | 34 | GOUT("Seed : "); 35 | GOUT(ssed.c_str()); 36 | 37 | ed25519::Seed data2; 38 | 39 | EXPECT_EQ(true,ed25519::base58::decode(ssed, data2)); 40 | GOUT(ssed.c_str()); 41 | 42 | std::string wrang_ssed; 43 | EXPECT_EQ(false,ed25519::base58::decode(wrang_ssed,data2,error_handler)); 44 | 45 | } 46 | 47 | TEST(TEST_API, keys_seed ) { 48 | 49 | ed25519::Seed seed; 50 | ed25519::Seed secret("some secret prase"); 51 | 52 | GOUT("Random seed : "); 53 | GOUT(seed.encode()); 54 | 55 | GOUT("Secret seed : "); 56 | GOUT(secret.encode()); 57 | 58 | 59 | ed25519::Seed from_secret(seed); 60 | 61 | GOUT("From seed : "); 62 | GOUT(from_secret.encode()); 63 | 64 | EXPECT_TRUE(from_secret == seed); 65 | 66 | GOUT("From secret seed : "); 67 | from_secret.decode(secret.encode()); 68 | 69 | GOUT(from_secret.encode()); 70 | 71 | EXPECT_TRUE(from_secret == secret); 72 | } 73 | 74 | TEST(TEST_API, pair_keys) { 75 | 76 | auto pair = ed25519::keys::Pair::Random(); 77 | 78 | GOUT("Private random: " + pair->get_private_key().encode()); 79 | GOUT("Public random: " + pair->get_public_key().encode()); 80 | 81 | } 82 | 83 | TEST(TEST_API, pair_key_with_secret ) { 84 | auto secret_pair = ed25519::keys::Pair::WithSecret("some secret phrase"); 85 | 86 | GOUT("Private secret: " + secret_pair->get_private_key().encode()); 87 | GOUT("Public secret: " + secret_pair->get_public_key().encode()); 88 | 89 | EXPECT_TRUE(!ed25519::keys::Pair::WithSecret("", error_handler)); 90 | 91 | } 92 | 93 | TEST(TEST_API, pair_key_from_private ) { 94 | auto secret_pair = ed25519::keys::Pair::WithSecret("some secret phrase"); 95 | 96 | if (auto pair = ed25519::keys::Pair::FromPrivateKey(secret_pair->get_private_key().encode(), error_handler)){ 97 | GOUT("Private from private: " + pair->get_private_key().encode()); 98 | GOUT("Public from private: " + pair->get_public_key().encode()); 99 | 100 | EXPECT_TRUE(pair->get_public_key() == secret_pair->get_public_key()); 101 | 102 | } else { 103 | EXPECT_TRUE(false); 104 | } 105 | } 106 | 107 | TEST(TEST_API, validate_public ) { 108 | auto secret_pair = ed25519::keys::Pair::WithSecret("some secret phrase"); 109 | auto pk = ed25519::keys::Public(); 110 | 111 | EXPECT_TRUE(secret_pair->get_public_key().validate()); 112 | GOUT("Validate public from secret: " + secret_pair->get_public_key().encode()); 113 | 114 | EXPECT_TRUE(pk.validate()); 115 | GOUT("Validate public from empty: " + pk.encode()); 116 | } 117 | 118 | TEST(TEST_API, validate_private ) { 119 | auto secret_pair = ed25519::keys::Pair::WithSecret("some secret phrase"); 120 | auto pvk = ed25519::keys::Private(); 121 | 122 | EXPECT_TRUE(secret_pair->get_private_key().validate()); 123 | GOUT("Validate private from secret: " + secret_pair->get_private_key().encode()); 124 | 125 | EXPECT_TRUE(pvk.validate()); 126 | GOUT("Validate private from empty: " + pvk.encode()); 127 | } 128 | 129 | TEST(TEST_API, validate_base58 ) { 130 | auto secret_pair = ed25519::keys::Pair::WithSecret("some secret phrase"); 131 | auto pvk = std::string("...."); 132 | 133 | EXPECT_TRUE(ed25519::base58::validate(secret_pair->get_private_key().encode())); 134 | GOUT("Validate base58 private from secret: " + secret_pair->get_private_key().encode()); 135 | 136 | EXPECT_TRUE(!ed25519::base58::validate(pvk)); 137 | GOUT("Validate private from empty: " + pvk); 138 | 139 | EXPECT_TRUE(!ed25519::keys::Private::validate(pvk)); 140 | GOUT("Validate private from empty: " + pvk); 141 | 142 | } 143 | 144 | TEST(TEST_API, signature ) { 145 | auto secret_pair = ed25519::keys::Pair::WithSecret("some secret phrase"); 146 | auto secret_pair2 = ed25519::keys::Pair::WithSecret("some secret other phrase"); 147 | 148 | std::string message = "some message or token string"; 149 | 150 | auto signature = secret_pair->sign(message); 151 | 152 | GOUT("Signature: " + signature->encode()); 153 | 154 | std::optional pp = ed25519::keys::Public::Decode(secret_pair->get_public_key().encode()); 155 | 156 | GOUT("Signature 1 ppp : " + pp->encode()); 157 | 158 | auto ppp = secret_pair2->get_public_key(); 159 | // 160 | // This is not permitted 161 | // 162 | // ppp.decode(secret_pair2->get_public_key().encode()); 163 | 164 | GOUT("Signature 2 ppp : " + ppp.encode()); 165 | 166 | EXPECT_TRUE(signature->verify(message, secret_pair->get_public_key())); 167 | EXPECT_TRUE(!signature->verify(message,secret_pair2->get_public_key())); 168 | 169 | auto signature_test = *signature; 170 | 171 | GOUT("Signature copy: -> " + signature_test.encode() + " <- " + signature->encode()); 172 | 173 | if (auto signature = ed25519::Signature::Decode("", error_handler)){ 174 | /// 175 | } 176 | else { 177 | GOUT("Wrong siganture deccoding tested"); 178 | 179 | auto signature_test_copy = ed25519::Signature::Decode(signature_test.encode(), error_handler); 180 | 181 | EXPECT_TRUE(signature_test_copy == signature_test); 182 | EXPECT_TRUE(signature_test_copy != *secret_pair2->sign(message)); 183 | 184 | } 185 | } 186 | 187 | #endif -------------------------------------------------------------------------------- /test/digest/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if (GTEST_FOUND) 2 | include_directories(${GTEST_INCLUDE_DIRS}) 3 | set(TEST_LIBRARIES ${GTEST_BOTH_LIBRARIES}) 4 | else() 5 | message("Googletest ${TEST} RELEASE MODE: ${CMAKE_BUILD_TYPE}") 6 | set(TEST_LIBRARIES gtest;gtest_main) 7 | endif() 8 | 9 | if (NOT WIN32) 10 | set(TEST_LIBRARIES ${TEST_LIBRARIES};pthread) 11 | endif () 12 | 13 | 14 | file (GLOB TESTS_SOURCES ${TESTS_SOURCES} 15 | ./*.cpp 16 | ) 17 | 18 | 19 | file (GLOB TESTS_SOURCES ${TESTS_SOURCES} 20 | ./*.cpp 21 | ) 22 | 23 | set (TEST digest_${PROJECT_LIB}) 24 | 25 | add_executable(${TEST} ${TESTS_SOURCES}) 26 | 27 | 28 | if (COMMON_DEPENDENCIES) 29 | message(STATUS "${TEST} DEPENDENCIES: ${COMMON_DEPENDENCIES}") 30 | add_dependencies( 31 | ${TEST} 32 | ${COMMON_DEPENDENCIES} 33 | ) 34 | endif () 35 | 36 | target_link_libraries ( 37 | ${TEST} 38 | ${PROJECT_LIB} 39 | ${TEST_LIBRARIES}) 40 | 41 | add_test (test ${TEST}) 42 | -------------------------------------------------------------------------------- /test/digest/digest.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by denn on 2019-01-30. 3 | // 4 | 5 | 6 | #include "ed25519.hpp" 7 | #include 8 | #include 9 | 10 | #include "gtest/gtest.h" 11 | #define GTEST_COUT std::cerr << "[ ] [ INFO ]" 12 | 13 | using namespace ed25519; 14 | 15 | auto error_handler = [](const std::error_code& code){ 16 | GTEST_COUT << "Test error: " << ed25519::StringFormat("code: %i, message: %s", code.value(), + code.message().c_str()) << std::endl; 17 | }; 18 | 19 | TEST(TEST, digest_calculator) { 20 | auto pair = keys::Pair::WithSecret("some secret phrase"); 21 | 22 | auto digest = Digest([pair](auto &calculator) { 23 | 24 | GTEST_COUT <<"Calculator ..." + StringFormat(" endian: %i", calculator.get_endian()) << std::endl; 25 | 26 | calculator.append(true); 27 | 28 | calculator.append(1); 29 | 30 | calculator.append((int)(1.12f * 100)); 31 | 32 | std::string title = "123"; 33 | 34 | calculator.append(title); 35 | 36 | std::vector v(title.begin(), title.end()); 37 | 38 | calculator.append(v); 39 | 40 | calculator.append(pair->get_public_key()); 41 | 42 | calculator.append(pair->get_private_key()); 43 | 44 | }); 45 | 46 | GTEST_COUT << "Digest: " + digest.encode() << std::endl; 47 | 48 | auto siganture = pair->sign(digest); 49 | 50 | GTEST_COUT << "Digest signature: " + siganture->encode() << std::endl; 51 | 52 | auto digest_restored = Digest::Decode(digest.encode(), error_handler); 53 | 54 | std::optional pk = ed25519::keys::Public::Decode(pair->get_public_key().encode(), default_error_handler); 55 | 56 | GTEST_COUT << siganture->verify(*digest_restored, *pk) << std::endl; 57 | } -------------------------------------------------------------------------------- /test/performance/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | if (GTEST_FOUND) 3 | include_directories(${GTEST_INCLUDE_DIRS}) 4 | set(TEST_LIBRARIES ${GTEST_BOTH_LIBRARIES}) 5 | else() 6 | message("Googletest ${TEST} RELEASE MODE: ${CMAKE_BUILD_TYPE}") 7 | set(TEST_LIBRARIES gtest;gtest_main) 8 | endif() 9 | 10 | if (NOT WIN32) 11 | set(TEST_LIBRARIES ${TEST_LIBRARIES};pthread) 12 | endif () 13 | 14 | 15 | file (GLOB TESTS_SOURCES ${TESTS_SOURCES} 16 | ./*.cpp 17 | ) 18 | 19 | set (TEST performance_${PROJECT_LIB}) 20 | 21 | add_executable(${TEST} ${TESTS_SOURCES}) 22 | 23 | target_link_libraries ( 24 | ${TEST} 25 | ${PROJECT_LIB} 26 | ${TEST_LIBRARIES} 27 | ) 28 | 29 | if (COMMON_DEPENDENCIES) 30 | message(STATUS "${TEST} DEPENDENCIES: ${COMMON_DEPENDENCIES}") 31 | add_dependencies( 32 | ${TEST} 33 | ${COMMON_DEPENDENCIES} 34 | ) 35 | endif () 36 | 37 | add_test (test ${TEST}) 38 | -------------------------------------------------------------------------------- /test/performance/sigantures.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by denn on 2019-01-30. 3 | // 4 | 5 | #include "ed25519.hpp" 6 | 7 | #include "gtest/gtest.h" 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace ed25519; 13 | 14 | TEST(TEST, siganture_rate){ 15 | 16 | auto pair = keys::Pair::WithSecret("some secret phrase"); 17 | std::string message; 18 | auto tests = {256, 4096, 60000}; 19 | int nc = 1000; 20 | 21 | for(auto i: tests ) { 22 | for (size_t j = 0; j < i/size::seed; ++j) { 23 | message.append(Seed().encode()); 24 | } 25 | 26 | auto signature = pair->sign(message); 27 | 28 | auto start = std::chrono::high_resolution_clock::now(); 29 | 30 | int vc = 0; 31 | for (int k = 0; k < nc; ++k) { 32 | if (signature->verify(message, pair->get_public_key())) { 33 | vc ++; 34 | } 35 | } 36 | 37 | auto finish = std::chrono::high_resolution_clock::now(); 38 | std::chrono::duration elapsed = finish - start; 39 | 40 | auto diff = (float)elapsed.count()/1000; 41 | 42 | std::cout << "verified signatures[message size="<