├── .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="<