├── .clang-format ├── .clang-tidy ├── .github └── workflows │ ├── Build.yml │ ├── Checks.yml │ ├── Coverage.yml │ └── Documentation.yml ├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.md ├── RELEASE.txt ├── doc ├── CMakeLists.txt ├── DoxyConf ├── mainpage.md └── styling.css ├── include └── scl │ ├── coro │ ├── batch.h │ ├── coroutine.h │ ├── future.h │ ├── promise.h │ ├── runtime.h │ ├── sleep_awaiter.h │ └── task.h │ ├── math │ ├── array.h │ ├── curves │ │ ├── ec_ops.h │ │ └── secp256k1.h │ ├── ec.h │ ├── ff.h │ ├── fields │ │ ├── ff_ops.h │ │ ├── ff_ops_gmp.h │ │ ├── mersenne127.h │ │ ├── mersenne61.h │ │ ├── secp256k1_field.h │ │ └── secp256k1_scalar.h │ ├── fp.h │ ├── lagrange.h │ ├── math.h │ ├── matrix.h │ ├── number.h │ ├── poly.h │ ├── vector.h │ ├── z2k.h │ └── z2k │ │ └── z2k_ops.h │ ├── net │ ├── channel.h │ ├── config.h │ ├── loopback.h │ ├── net.h │ ├── network.h │ ├── packet.h │ ├── sys_iface.h │ ├── tcp_channel.h │ └── tcp_utils.h │ ├── protocol │ ├── base.h │ ├── clock.h │ ├── env.h │ ├── eval.h │ ├── protocol.h │ └── result.h │ ├── scl.h │ ├── serialization │ ├── serializable.h │ ├── serialization.h │ └── serializer.h │ ├── simulation │ ├── cancellation.h │ ├── channel.h │ ├── channel_id.h │ ├── config.h │ ├── context.h │ ├── event.h │ ├── hook.h │ ├── manager.h │ ├── runtime.h │ ├── simulation.h │ ├── simulator.h │ └── transport.h │ ├── ss │ ├── additive.h │ ├── feldman.h │ ├── pedersen.h │ ├── shamir.h │ └── ss.h │ └── util │ ├── bitmap.h │ ├── cmdline.h │ ├── digest.h │ ├── hash.h │ ├── iuf_hash.h │ ├── measurement.h │ ├── merkle.h │ ├── merkle_proof.h │ ├── prg.h │ ├── sha256.h │ ├── sha3.h │ ├── sign.h │ ├── str.h │ ├── time.h │ └── util.h ├── scripts ├── check_all.sh ├── check_copyright_headers.py ├── check_coverage.sh ├── check_formatting.sh └── check_header_guards.py ├── src └── scl │ ├── coro │ └── runtime.cc │ ├── math │ ├── curves │ │ └── secp256k1_curve.cc │ ├── fields │ │ ├── ff_ops_gmp.cc │ │ ├── mersenne127.cc │ │ ├── mersenne61.cc │ │ ├── naf.h │ │ ├── secp256k1_field.cc │ │ ├── secp256k1_helpers.h │ │ ├── secp256k1_scalar.cc │ │ └── small_ff.h │ └── number.cc │ ├── net │ ├── config.cc │ └── network.cc │ ├── simulation │ ├── channel.cc │ ├── config.cc │ ├── context.cc │ ├── event.cc │ ├── runtime.cc │ ├── simulator.cc │ └── transport.cc │ └── util │ ├── cmdline.cc │ ├── measurement.cc │ ├── prg.cc │ ├── sha256.cc │ ├── sha3.cc │ └── str.cc └── test ├── CMakeLists.txt ├── data ├── 3_parties.txt ├── invalid_entry.txt └── invalid_no_entries.txt └── scl ├── coro ├── test_batch.cc └── test_task.cc ├── gf7.cc ├── gf7.h ├── math ├── fields.h ├── test_array.cc ├── test_ff.cc ├── test_la.cc ├── test_matrix.cc ├── test_mersenne127.cc ├── test_mersenne61.cc ├── test_number.cc ├── test_poly.cc ├── test_secp256k1.cc ├── test_vector.cc └── test_z2k.cc ├── net ├── test_config.cc ├── test_loopback.cc ├── test_network.cc ├── test_packet.cc ├── util.cc └── util.h ├── protocol ├── beaver.h ├── test_protocol.cc └── triple.h ├── serialization └── test_serializer.cc ├── simulation ├── test_channel.cc ├── test_config.cc ├── test_context.cc ├── test_env.cc ├── test_event.cc ├── test_manager.cc └── test_simulator.cc ├── ss ├── test_additive.cc ├── test_feldman.cc ├── test_pedersen.cc └── test_shamir.cc └── util ├── test_bitmap.cc ├── test_cmdline.cc ├── test_ecdsa.cc ├── test_measurement.cc ├── test_merkle.cc ├── test_prg.cc ├── test_sha256.cc └── test_sha3.cc /.clang-format: -------------------------------------------------------------------------------- 1 | Language: Cpp 2 | BasedOnStyle: Google 3 | 4 | DerivePointerAlignment: false 5 | AllowShortFunctionsOnASingleLine: Empty 6 | AllowAllParametersOfDeclarationOnNextLine: false 7 | AllowAllArgumentsOnNextLine: false 8 | BinPackArguments: false 9 | BinPackParameters: false 10 | 11 | # The include rules below structures includes as 12 | # 13 | # - STL headers (anything without an extension, tbp) 14 | # - Other headers (anything that ends with .h) 15 | # - External SCL headers (anything of the form ) 16 | # - Internal SCL headers (anything of the form "scl/...") 17 | # 18 | # The only exception is when a .cc file includes a header file with the same 19 | # name at the same path. 20 | 21 | IncludeCategories: 22 | - Regex: '^' 26 | Priority: 2 27 | SortPriority: 0 28 | - Regex: '^<.*' 29 | Priority: 1 30 | SortPriority: 0 31 | - Regex: '^scl/.*' 32 | Priority: 5 33 | SortPriority: 0 34 | -------------------------------------------------------------------------------- /.clang-tidy: -------------------------------------------------------------------------------- 1 | Checks: '-*,bugprone-*,performance-*,readability-*,google-global-names-in-headers,cert-dcl59-cpp,-bugprone-easily-swappable-parameters,-readability-identifier-length,-readability-magic-numbers,-readability-function-cognitive-complexity,-readability-function-size,-readability-convert-member-functions-to-static' 2 | 3 | CheckOptions: 4 | - key: performance-unnecessary-value-param.AllowedTypes 5 | value: shared_ptr;unique_ptr 6 | 7 | # Enabled checks: 8 | # - bugprone 9 | # - performance 10 | # - readability 11 | # - google-global-names-in-headers 12 | # - cert-dcl59-cpp 13 | # 14 | # Specific disabled checks 15 | # 16 | # bugprone-easily-swappable-parameters: 17 | # Doesn't make sense to exclude functions taking multiple ints in SCL. 18 | # 19 | # readability-identifier-length: 20 | # Short identifiers make sense. 21 | # 22 | # readability-magic-numbers: 23 | # Too strict. 24 | # 25 | # readability-convert-member-functions-to-static 26 | # Too many false positives. 27 | # 28 | # readability-function-cognitive-complexity 29 | # Catch2. 30 | # 31 | # readability-function-size 32 | # Catch2. 33 | 34 | AnalyzeTemporaryDtors: false 35 | -------------------------------------------------------------------------------- /.github/workflows/Build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | push: 5 | branches: 6 | - '*' 7 | - '!master' 8 | 9 | jobs: 10 | release: 11 | name: release 12 | runs-on: ubuntu-22.04 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | 17 | - name: Build 18 | shell: bash 19 | run: | 20 | cmake . -B build -DSCL_BUILD_DOCUMENTATION=OFF 21 | cmake --build build 22 | 23 | - name: Test 24 | shell: bash 25 | run: cmake --build build --target test 26 | -------------------------------------------------------------------------------- /.github/workflows/Checks.yml: -------------------------------------------------------------------------------- 1 | name: Checks 2 | 3 | on: 4 | push: 5 | branches: 6 | - '*' 7 | - '!master' 8 | 9 | jobs: 10 | headers: 11 | name: headers 12 | runs-on: ubuntu-22.04 13 | steps: 14 | - uses: actions/checkout@v2 15 | 16 | - name: Copyright 17 | run: ./scripts/check_copyright_headers.py 18 | 19 | - name: Header Guards 20 | run: ./scripts/check_header_guards.py 21 | 22 | style: 23 | name: style 24 | runs-on: ubuntu-22.04 25 | steps: 26 | - uses: actions/checkout@v2 27 | 28 | - name: Setup 29 | run: sudo apt-get install -y clang-format-15 30 | 31 | - name: Check 32 | shell: bash 33 | run: ./scripts/check_formatting.sh 34 | -------------------------------------------------------------------------------- /.github/workflows/Coverage.yml: -------------------------------------------------------------------------------- 1 | name: Coverage 2 | 3 | on: 4 | push: 5 | branches: 6 | - '*' 7 | - '!master' 8 | 9 | jobs: 10 | coverage: 11 | name: coverage 12 | runs-on: ubuntu-24.04 13 | env: 14 | COV_THRESHOLD_LINES: 95 15 | COV_THRESHOLD_FUNCS: 90 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | 20 | - name: Setup 21 | shell: bash 22 | run: sudo apt-get install -y lcov 23 | 24 | - name: Build 25 | shell: bash 26 | run: | 27 | cmake . -B build -DSCL_BUILD_TEST_WITH_COVERAGE=ON -DSCL_BUILD_DOCUMENTATION=OFF 28 | cmake --build build 29 | 30 | - name: Compute coverage 31 | shell: bash 32 | run: cmake --build build --target coverage | tee cov.txt 33 | 34 | - name: Check coverage 35 | shell: bash 36 | run: ./scripts/check_coverage.sh cov.txt 37 | -------------------------------------------------------------------------------- /.github/workflows/Documentation.yml: -------------------------------------------------------------------------------- 1 | name: Documentation 2 | 3 | on: 4 | push: 5 | branches: 6 | - '*' 7 | - '!master' 8 | 9 | jobs: 10 | documentation: 11 | name: documentation 12 | runs-on: ubuntu-22.04 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | 17 | - name: Cache doxygen 18 | id: cache-doxygen 19 | uses: actions/cache@v4 20 | with: 21 | path: ~/doxygen 22 | key: ${{ runner.os }}-doxygen 23 | 24 | - name: Install doxygen 25 | if: ${{ steps.cache-doxygen.outputs.cache-hit != 'true' }} 26 | run: | 27 | curl https://www.doxygen.nl/files/doxygen-1.10.0.linux.bin.tar.gz -o doxygen.tar.gz 28 | mkdir ~/doxygen 29 | tar xf doxygen.tar.gz -C ~/doxygen --strip-components=1 30 | 31 | - name: Generate documentation 32 | shell: bash 33 | run: | 34 | cmake . -B build -DSCL_BUILD_TESTS=OFF -DSCL_DOXYGEN_BIN=$HOME/doxygen/bin/doxygen 35 | cmake --build build --target documentation 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # files related to build 2 | .cache/ 3 | .clangd 4 | build/ 5 | buildDebug/ 6 | buildRelease/ 7 | buildOMP/ 8 | compile_commands.json 9 | 10 | # do not track compiled documentation files 11 | doc/html 12 | 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SCL — Secure Computation Library 2 | 3 | SCL is a utilities library for prototyping Secure Multiparty Computation (_MPC_ 4 | for short) protocols. The focus of SCL is usability, not necessarily speed. What 5 | this means is that SCL strives to provide an intuitive, easy to use and 6 | understand, and well documented interface that helps the programmer prototype an 7 | MPC protocol faster (and nicer) than if they had to write everything themselves. 8 | 9 | SCL provides high level interfaces and functionality for working with 10 | * Secret sharing, additive and Shamir. 11 | * Finite fields. 12 | * Primitives, such as hash functions and PRGs. 13 | 14 | SCL in addition provides methods for running protocols on both a real 15 | network, where each party is connected via TCP, as well as a 16 | *simulated* network. 17 | 18 | ### Disclaimer 19 | 20 | SCL is distributed under the GNU Affero General Public License, for details, 21 | refer to `LICENSE` or [https://www.gnu.org/licenses/](https://www.gnu.org/licenses/). 22 | 23 | This program is distributed in the hope that it will be useful, but WITHOUT ANY 24 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 25 | PARTICULAR PURPOSE. 26 | 27 | # Building SCL 28 | 29 | SCL uses [gmp](https://gmplib.org/) for working with Elliptic Curves, and 30 | [catch2](https://github.com/catchorg/Catch2/tree/v2.x) for testing and `lcov` 31 | for test coverage. 32 | 33 | The CMake file recongnizes two different build types: `Debug` and `Release`, the 34 | latter being the default. In either case, building is straight forward and can 35 | be done with the commands 36 | 37 | ``` 38 | cmake . -B build -DCMAKE_BUILD_TYPE= 39 | cmake --build build 40 | ``` 41 | 42 | In case the `Release` build is used, SCL can be installed by running 43 | 44 | ``` 45 | sudo cmake --install build 46 | ``` 47 | 48 | after the build command. By default, headers are install in `usr/local/include` 49 | and the shared library in `/usr/local/lib`. This location can be controlled by 50 | setting the `CMAKE_INSTALL_PREFIX` accordingly. 51 | 52 | Support for Elliptic Curves can be disabled (and thus remove the need to have 53 | gmp installed) by passing `-DWITH_EC=OFF` to cmake. 54 | 55 | 56 | # Using SCL 57 | 58 | To use SCL, link `libscl.so` when building your program and include the 59 | `include/` directory to your builds includes. The test folder is a good place to 60 | see examples of how the different functionality works. 61 | 62 | # Documentation 63 | 64 | SCL uses Doxygen for documentation, which can be generated by running 65 | `make documentation` from within the build folder. The generated 66 | documentation is placed in the `doc` folder. 67 | 68 | # Citing 69 | 70 | I'd greatly appreciate any work that uses SCL include the below bibtex entry 71 | 72 | ``` 73 | @misc{secure-computation-library, 74 | author = {Anders Dalskov}, 75 | title = {{SCL (Secure Computation Library)---utility library for prototyping MPC applications}}, 76 | howpublished = {\url{https://github.com/anderspkd/secure-computation-library}}, 77 | } 78 | ``` 79 | -------------------------------------------------------------------------------- /RELEASE.txt: -------------------------------------------------------------------------------- 1 | 0.1.0: Initial version of SCL for C++20 2 | -------------------------------------------------------------------------------- /doc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SCL --- Secure Computation Library 2 | # Copyright (C) 2024 Anders Dalskov 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU Affero General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU Affero General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Affero General Public License 15 | # along with this program. If not, see . 16 | 17 | cmake_minimum_required(VERSION 3.5) 18 | 19 | if (NOT SCL_DOXYGEN_BIN) 20 | find_program(doxygen doxygen REQUIRED) 21 | else() 22 | if (EXISTS ${SCL_DOXYGEN_BIN} AND (NOT IS_DIRECTORY ${SCL_DOXYGEN_BIN})) 23 | set(doxygen ${SCL_DOXYGEN_BIN}) 24 | else() 25 | message(FATAL_ERROR "\"${SCL_DOXYGEN_BIN}\" not a valid argument for doxygen binary.") 26 | endif() 27 | endif() 28 | 29 | add_custom_target( 30 | documentation 31 | COMMAND ${doxygen} "${CMAKE_SOURCE_DIR}/doc/DoxyConf" 32 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} 33 | COMMENT "Generate documentation for SCL" 34 | VERBATIM) 35 | -------------------------------------------------------------------------------- /doc/DoxyConf: -------------------------------------------------------------------------------- 1 | DOXYFILE_ENCODING = UTF-8 2 | PROJECT_NAME = "Secure Computation Library" 3 | PROJECT_NUMBER = 0.1 4 | PROJECT_BRIEF = "Utility library for common Secure Computation primitives." 5 | 6 | OUTPUT_DIRECTORY = ./doc 7 | 8 | WARN_AS_ERROR = YES 9 | 10 | INPUT = doc/mainpage.md \ 11 | include/scl/ \ 12 | include/scl/util \ 13 | include/scl/math \ 14 | include/scl/math/fields \ 15 | include/scl/math/curves \ 16 | include/scl/ss \ 17 | include/scl/net \ 18 | include/scl/simulation \ 19 | include/scl/protocol \ 20 | include/scl/coro \ 21 | include/scl/serialization 22 | 23 | FILE_PATTERNS = *.h 24 | EXCLUDE_SYMBOLS = SCL_* 25 | 26 | REPEAT_BRIEF = NO 27 | 28 | SORT_MEMBER_DOCS = NO 29 | SORT_BRIEF_DOCS = NO 30 | SORT_MEMBERS_CTORS_1ST = YES 31 | 32 | SHOW_USED_FILES = NO 33 | SHOW_FILES = NO 34 | 35 | USE_MDFILE_AS_MAINPAGE = doc/mainpage.md 36 | HTML_EXTRA_STYLESHEET = doc/styling.css 37 | 38 | GENERATE_TREEVIEW = YES 39 | 40 | USE_MATHJAX = YES 41 | 42 | HAVE_DOT = NO 43 | GENERATE_LATEX = NO 44 | GENERATE_LEGEND = NO -------------------------------------------------------------------------------- /doc/mainpage.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | **SCL** (short for *Secure Computation Library*) is a C++-20 library which aims 4 | at removing a lot of the typical boilerplate code that one usually has to write 5 | when developing a proof-of-concept for a new Secure Multiparty Computation (or 6 | *MPC* for short) protocol. 7 | 8 | Everything SCL is placed in the \ref scl namespace, and different 9 | functionalities are placed in different sub namespaces, a short description of 10 | each as well as their purpose is given here: 11 | 12 | - \ref scl::coro coroutines. 13 | - \ref scl::math math related stuff. 14 | - \ref scl::net networking. 15 | - \ref scl::proto protocol interfaces. 16 | - \ref scl::sim protocol execution simulation. 17 | - \ref scl::seri serialization. 18 | - \ref scl::ss secret-sharing. 19 | - \ref scl::util other utilities. 20 | -------------------------------------------------------------------------------- /doc/styling.css: -------------------------------------------------------------------------------- 1 | body, table, div, p, dl, td { 2 | font-family: sans-serif; 3 | font-size: 13px; 4 | } 5 | 6 | code { 7 | background-color: #efefef; 8 | border: solid 1px; 9 | border-color: #cfcfcf; 10 | border-radius: 4px; 11 | padding-left: 2px; 12 | padding-right: 2px; 13 | } 14 | 15 | span.lineno { 16 | line-height: 1.3; 17 | } -------------------------------------------------------------------------------- /include/scl/coro/coroutine.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_CORO_COROUTINE_H 19 | #define SCL_CORO_COROUTINE_H 20 | 21 | #include "scl/coro/runtime.h" 22 | #include "scl/coro/task.h" 23 | 24 | /** 25 | * @brief Coroutine utilities. 26 | */ 27 | namespace scl::coro {} // namespace scl::coro 28 | 29 | #endif // SCL_CORO_COROUTINE_H 30 | -------------------------------------------------------------------------------- /include/scl/coro/future.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_CORO_FUTURE_H 19 | #define SCL_CORO_FUTURE_H 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | namespace scl::coro { 27 | 28 | class Runtime; 29 | 30 | namespace details { 31 | 32 | /** 33 | * @brief Concept that a future type must satisfy. 34 | */ 35 | template 36 | concept FutureAwaitableType = requires(FUTURE future) { 37 | { future() } -> std::convertible_to; 38 | }; 39 | 40 | /** 41 | * @brief The awaiter for future events. 42 | * @tparam FUTURE_EVENT the type of the future event. 43 | * 44 | * \p FUTURE_EVENT must be a subclass of FutureEvent. 45 | */ 46 | template 47 | class FutureAwaiter final { 48 | public: 49 | /** 50 | * @brief Construct a new awaiter from a future. 51 | * @param future the future. 52 | */ 53 | FutureAwaiter(FUTURE&& future) : m_future(std::forward(future)){}; 54 | 55 | /** 56 | * @brief Futures are by design not ready immediately. 57 | */ 58 | bool await_ready() const noexcept { 59 | return false; 60 | } 61 | 62 | /** 63 | * @brief Schedule the coroutine for later execution, pending some condition. 64 | * @return the next coroutine to execute. 65 | */ 66 | std::coroutine_handle<> await_suspend(std::coroutine_handle<> handle); 67 | 68 | /** 69 | * @brief Does nothing. 70 | */ 71 | void await_resume() const noexcept {} 72 | 73 | /** 74 | * @brief Sets the runtime for this future. 75 | */ 76 | void setRuntime(Runtime* runtime) { 77 | m_runtime = runtime; 78 | } 79 | 80 | private: 81 | Runtime* m_runtime; 82 | FUTURE m_future; 83 | }; 84 | 85 | } // namespace details 86 | } // namespace scl::coro 87 | 88 | #endif // SCL_CORO_FUTURE_H 89 | -------------------------------------------------------------------------------- /include/scl/coro/sleep_awaiter.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_CORO_SLEEP_AWAITER_H 19 | #define SCL_CORO_SLEEP_AWAITER_H 20 | 21 | #include 22 | #include 23 | 24 | #include "scl/util/time.h" 25 | 26 | namespace scl::coro { 27 | 28 | class Runtime; 29 | 30 | namespace details { 31 | 32 | /** 33 | * @brief Awaiter interface for suspending coroutines for some amount of time. 34 | */ 35 | class SleepAwaiter { 36 | public: 37 | /** 38 | * @brief Create a new sleep awaiter. 39 | */ 40 | SleepAwaiter(util::Time::Duration duration) : m_duration(duration) {} 41 | 42 | /** 43 | * @brief Check if the sleep awaiter is ready. 44 | * 45 | * The assumption made is that duration > 0, and so this function 46 | * always returns false. 47 | */ 48 | bool await_ready() const noexcept { 49 | return false; 50 | } 51 | 52 | /** 53 | * @brief Suspend the coroutine that is being put to sleep. 54 | */ 55 | std::coroutine_handle<> await_suspend(std::coroutine_handle<> handle); 56 | 57 | /** 58 | * @brief Resume the coroutine. Does nothing. 59 | */ 60 | void await_resume() const noexcept {}; 61 | 62 | /** 63 | * @brief Set the runtime for this coroutine. 64 | */ 65 | void setRuntime(Runtime* runtime) { 66 | m_runtime = runtime; 67 | } 68 | 69 | private: 70 | util::Time::Duration m_duration; 71 | 72 | Runtime* m_runtime = nullptr; 73 | }; 74 | 75 | } // namespace details 76 | } // namespace scl::coro 77 | 78 | #endif // SCL_CORO_SLEEP_AWAITER_H 79 | -------------------------------------------------------------------------------- /include/scl/math/curves/secp256k1.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_MATH_CURVES_SECP256K1_H 19 | #define SCL_MATH_CURVES_SECP256K1_H 20 | 21 | #include 22 | 23 | #include "scl/math/curves/ec_ops.h" 24 | #include "scl/math/ff.h" 25 | #include "scl/math/fields/secp256k1_field.h" 26 | #include "scl/math/fields/secp256k1_scalar.h" 27 | 28 | namespace scl::math::ec { 29 | 30 | /** 31 | * @brief Elliptic curve definition for secp256k1. 32 | * @see http://www.secg.org/sec2-v2.pdf 33 | */ 34 | struct Secp256k1 { 35 | /** 36 | * @brief The finite field defined by 37 | * \f$p=2^{256}-2^{32}-2^{9}-2^{8}-2^{7}-2^{6}-2^{4}-1\f$ 38 | */ 39 | using Field = ff::Secp256k1Field; 40 | 41 | /** 42 | * @brief The finite field defined by a large prime order subgroup. 43 | */ 44 | using Scalar = ff::Secp256k1Scalar; 45 | 46 | /** 47 | * @brief Secp256k1 curve elements are stored in projective coordinates. 48 | */ 49 | using ValueType = std::array, 3>; 50 | 51 | /** 52 | * @brief Name of the secp256k1 curve. 53 | */ 54 | constexpr static const char* NAME = "secp256k1"; 55 | }; 56 | 57 | } // namespace scl::math::ec 58 | 59 | #endif // SCL_MATH_CURVES_SECP256K1_H 60 | -------------------------------------------------------------------------------- /include/scl/math/fields/ff_ops.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_MATH_FIELDS_FF_OPS_H 19 | #define SCL_MATH_FIELDS_FF_OPS_H 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "scl/math/number.h" 27 | 28 | namespace scl::math::ff { 29 | 30 | /** 31 | * @brief Convert an int into a field element. 32 | * @param out where to store the converted element 33 | * @param value the integer to convert 34 | */ 35 | template 36 | void convertTo(typename FIELD::ValueType& out, int value); 37 | 38 | /** 39 | * @brief Read a field element from a string. 40 | * @param out where to store the resulting element 41 | * @param src the string 42 | */ 43 | template 44 | void convertTo(typename FIELD::ValueType& out, const std::string& src); 45 | 46 | /** 47 | * @brief Add two field elements in-place. 48 | * @param out the first operand and output 49 | * @param op the second operand 50 | */ 51 | template 52 | void add(typename FIELD::ValueType& out, const typename FIELD::ValueType& op); 53 | 54 | /** 55 | * @brief Subtract two field elements in-place. 56 | * @param out the first operand and output 57 | * @param op the second operand 58 | */ 59 | template 60 | void subtract(typename FIELD::ValueType& out, 61 | const typename FIELD::ValueType& op); 62 | 63 | /** 64 | * @brief Multiply two field elements in-place. 65 | * @param out the first operand and output 66 | * @param op the second operand 67 | */ 68 | template 69 | void multiply(typename FIELD::ValueType& out, 70 | const typename FIELD::ValueType& op); 71 | 72 | /** 73 | * @brief Negate a field element in-place. 74 | * @param out the element to negate 75 | */ 76 | template 77 | void negate(typename FIELD::ValueType& out); 78 | 79 | /** 80 | * @brief Invert a field element in-place. 81 | * @param out the element to invert 82 | */ 83 | template 84 | void invert(typename FIELD::ValueType& out); 85 | 86 | /** 87 | * @brief Check if two field elements are the same. 88 | * @param in1 the first element 89 | * @param in2 the second element 90 | * @return true if \p in1 and \p in2 are the same and false otherwise 91 | */ 92 | template 93 | bool equal(const typename FIELD::ValueType& in1, 94 | const typename FIELD::ValueType& in2); 95 | 96 | /** 97 | * @brief Convert a field element to bytes. 98 | * @param dest the field element to convert 99 | * @param src where to store the converted element 100 | */ 101 | template 102 | void toBytes(unsigned char* dest, const typename FIELD::ValueType& src); 103 | 104 | /** 105 | * @brief Convert the content of a buffer to a field element. 106 | * @param dest where to store the converted element 107 | * @param src the buffer 108 | */ 109 | template 110 | void fromBytes(typename FIELD::ValueType& dest, const unsigned char* src); 111 | 112 | /** 113 | * @brief Convert a field element to a string. 114 | * @param in the field element to convert 115 | * @return an STL string representation of \p in. 116 | */ 117 | template 118 | std::string toString(const typename FIELD::ValueType& in); 119 | 120 | } // namespace scl::math::ff 121 | 122 | #endif // SCL_MATH_FIELDS_FF_OPS_H 123 | -------------------------------------------------------------------------------- /include/scl/math/fields/mersenne127.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_MATH_FIELDS_MERSENNE127_H 19 | #define SCL_MATH_FIELDS_MERSENNE127_H 20 | 21 | #include 22 | #include 23 | 24 | namespace scl::math::ff { 25 | 26 | /** 27 | * @brief The field \f$\mathbb{F}_p\f$ with \f$p=2^{127}-1\f$. 28 | */ 29 | struct Mersenne127 { 30 | /** 31 | * @brief Internal type elements of this field. 32 | */ 33 | using ValueType = __uint128_t; 34 | 35 | /** 36 | * @brief The name of this field. 37 | */ 38 | constexpr static const char* NAME = "Mersenne127"; 39 | 40 | /** 41 | * @brief The size of field elements of this field in bytes. 42 | */ 43 | constexpr static const std::size_t BYTE_SIZE = sizeof(ValueType); 44 | 45 | /** 46 | * @brief The size of field elements of this field in bits. 47 | */ 48 | constexpr static const std::size_t BIT_SIZE = 127; 49 | }; 50 | 51 | } // namespace scl::math::ff 52 | 53 | #endif // SCL_MATH_FIELDS_MERSENNE127_H 54 | -------------------------------------------------------------------------------- /include/scl/math/fields/mersenne61.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_MATH_FIELDS_MERSENNE61_H 19 | #define SCL_MATH_FIELDS_MERSENNE61_H 20 | 21 | #include 22 | #include 23 | 24 | namespace scl::math::ff { 25 | 26 | /** 27 | * @brief The field \f$\mathbb{F}_p\f$ with \f$p=2^{61}-1\f$. 28 | */ 29 | struct Mersenne61 { 30 | /** 31 | * @brief Internal type elements of this field. 32 | */ 33 | using ValueType = std::uint64_t; 34 | 35 | /** 36 | * @brief The name of this field. 37 | */ 38 | constexpr static const char* NAME = "Mersenne61"; 39 | 40 | /** 41 | * @brief The size of field elements of this field in bytes. 42 | */ 43 | constexpr static const std::size_t BYTE_SIZE = sizeof(ValueType); 44 | 45 | /** 46 | * @brief The size of field elements of this field in bits. 47 | */ 48 | constexpr static const std::size_t BIT_SIZE = 61; 49 | }; 50 | 51 | } // namespace scl::math::ff 52 | 53 | #endif // SCL_MATH_FIELDS_MERSENNE61_H 54 | -------------------------------------------------------------------------------- /include/scl/math/fields/secp256k1_field.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_MATH_FIELDS_SECP256K1_FIELD_H 19 | #define SCL_MATH_FIELDS_SECP256K1_FIELD_H 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | namespace scl::math::ff { 27 | 28 | /** 29 | * @brief The Field over which secp256k1 is defined. 30 | */ 31 | struct Secp256k1Field { 32 | /** 33 | * @brief Field elements are stored as 4 limb numbers internally. 34 | */ 35 | using ValueType = std::array; 36 | 37 | /** 38 | * @brief Name of the secp256k1 field. 39 | */ 40 | constexpr static const char* NAME = "secp256k1_field"; 41 | 42 | /** 43 | * @brief Byte size of a secp256k1 field element. 44 | */ 45 | constexpr static const std::size_t BYTE_SIZE = 4 * sizeof(mp_limb_t); 46 | 47 | /** 48 | * @brief Bit size of a secp256k1 field element. 49 | */ 50 | constexpr static const std::size_t BIT_SIZE = 8 * BYTE_SIZE; 51 | }; 52 | 53 | } // namespace scl::math::ff 54 | 55 | #endif // SCL_MATH_FIELDS_SECP256K1_FIELD_H 56 | -------------------------------------------------------------------------------- /include/scl/math/fields/secp256k1_scalar.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_MATH_FIELDS_SECP256K1_SCALAR_H 19 | #define SCL_MATH_FIELDS_SECP256K1_SCALAR_H 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | namespace scl::math::ff { 27 | 28 | /** 29 | * @brief Finite field modulo a Secp256k1 prime order sub-group. 30 | */ 31 | struct Secp256k1Scalar { 32 | /** 33 | * @brief Internal type of elements. 34 | */ 35 | using ValueType = std::array; 36 | 37 | /** 38 | * @brief Name of the field. 39 | */ 40 | constexpr static const char* NAME = "secp256k1_order"; 41 | 42 | /** 43 | * @brief Size of an element in bytes. 44 | */ 45 | constexpr static const std::size_t BYTE_SIZE = 4 * sizeof(mp_limb_t); 46 | 47 | /** 48 | * @brief Size of an element in bits. 49 | */ 50 | constexpr static const std::size_t BIT_SIZE = 8 * BYTE_SIZE; 51 | }; 52 | 53 | } // namespace scl::math::ff 54 | 55 | #endif // SCL_MATH_FIELDS_SECP256K1_SCALAR_H 56 | -------------------------------------------------------------------------------- /include/scl/math/fp.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_MATH_FP_H 19 | #define SCL_MATH_FP_H 20 | 21 | #include 22 | 23 | #include "scl/math/ff.h" 24 | #include "scl/math/fields/mersenne127.h" 25 | #include "scl/math/fields/mersenne61.h" 26 | 27 | namespace scl::math { 28 | 29 | #define SCL_IN_RANGE(v, l, u) ((l) <= (v) && (v) <= (u)) 30 | 31 | /** 32 | * @brief Select a suitable Finite Field based on a provided bitlevel. 33 | */ 34 | template 35 | struct FieldSelector { 36 | static_assert(BITS > 0 && BITS < 128, "Bits not in range [1, 127]"); 37 | 38 | /** 39 | * @brief The field. 40 | */ 41 | using Field = std:: 42 | conditional_t; 43 | }; 44 | 45 | #undef SCL_IN_RANGE 46 | 47 | /** 48 | * @brief A suitable pre-defined field with space for \p Bits computation. 49 | * @tparam Bits the size in bits of the finite field 50 | * 51 | * Fp is an alias for FF instantiated with a prime order Finite Field of an 52 | * appropriate size indicated by the \p Bits parameter. Currently, only \p Bits 53 | * have to be in the range [1, 127] as SCL only has support for two 54 | * fields: 55 | *
    56 | *
  • A 61-bit Finite Field defined over a \f$p=2^{61}-1\f$
  • 57 | *
  • A 127-bit Finite Field defined over a \f$p=2^{127}-1\f$
  • 58 | *
59 | * 60 | * @see Mersenne61 61 | * @see Mersenne127 62 | */ 63 | template 64 | using Fp = FF::Field>; 65 | 66 | } // namespace scl::math 67 | 68 | #endif // SCL_MATH_FP_H 69 | -------------------------------------------------------------------------------- /include/scl/math/lagrange.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_MATH_LAGRANGE_H 19 | #define SCL_MATH_LAGRANGE_H 20 | 21 | #include 22 | #include 23 | 24 | #include "scl/math/vector.h" 25 | 26 | namespace scl::math { 27 | 28 | /** 29 | * @brief Computes a lagrange basis for a set of nodes. 30 | * @param nodes the set of nodes. 31 | * @param x the evaluation point x. 32 | * 33 | *

This function computes a set of values \f$\{\ell_i(x)\}_{iLagrange basis for a polynomial of degree \f$\leq n\f$, where 35 | * \f$n\f$ is the number of nodes provided. This basis can be used for 36 | * polynomial interpolation. 37 | * 38 | * @code 39 | * // pairs of evaluations of some polynomial f 40 | * auto nodes = ... // 0, 1, 2, 3, 4, 5 41 | * auto ys = ... // f(0), f(2), f(3), f(4), f(5) 42 | * 43 | * auto basis = computeLagrangeBasis(nodes, 7); 44 | * 45 | * auto f7 = ys.dot(basis); // f(7) 46 | * @endcode 47 | * 48 | *

The nodes provided must be pairwise invertible. That is, for every 49 | * \f$x_i,x_j\f$ in \p nodes, then \f$x_i-x_j\f$ must be invertible for all 50 | * \f$i\neq j\f$. 51 | * 52 | * @see https://en.wikipedia.org/wiki/Lagrange_polynomial 53 | */ 54 | template 55 | Vector computeLagrangeBasis(const math::Vector& nodes, const T& x) { 56 | const auto n = nodes.size(); 57 | std::vector b; 58 | b.reserve(n); 59 | for (std::size_t i = 0; i < n; ++i) { 60 | auto ell = T::one(); 61 | const auto xi = nodes[i]; 62 | for (std::size_t j = 0; j < n; ++j) { 63 | if (i != j) { 64 | const auto xj = nodes[j]; 65 | ell *= (x - xj) / (xi - xj); 66 | } 67 | } 68 | b.emplace_back(ell); 69 | } 70 | return b; 71 | } 72 | 73 | /** 74 | * @brief Computes a lagrange basis for a set of nodes. 75 | * @param nodes the set of nodes. 76 | * @param x the evaluation point x. 77 | * @see computeLagrangeBasis 78 | */ 79 | template 80 | Vector computeLagrangeBasis(const math::Vector& nodes, int x) { 81 | return computeLagrangeBasis(nodes, T{x}); 82 | } 83 | 84 | } // namespace scl::math 85 | 86 | #endif // SCL_MATH_LAGRANGE_H 87 | -------------------------------------------------------------------------------- /include/scl/math/math.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_MATH_MATH_H 19 | #define SCL_MATH_MATH_H 20 | 21 | #include "scl/math/ec.h" 22 | #include "scl/math/ff.h" 23 | #include "scl/math/fp.h" 24 | #include "scl/math/matrix.h" 25 | #include "scl/math/number.h" 26 | #include "scl/math/vector.h" 27 | #include "scl/math/z2k.h" 28 | 29 | /** 30 | * @brief Maths! 31 | */ 32 | namespace scl::math { 33 | 34 | /** 35 | * @brief Functionality related to finite fields. 36 | */ 37 | namespace ff {} 38 | 39 | /** 40 | * @brief Functionality related to elliptic curves. 41 | */ 42 | namespace ec {} 43 | 44 | } // namespace scl::math 45 | 46 | #endif // SCL_MATH_MATH_H 47 | -------------------------------------------------------------------------------- /include/scl/net/channel.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_NET_CHANNEL_H 19 | #define SCL_NET_CHANNEL_H 20 | 21 | #include "scl/coro/task.h" 22 | #include "scl/net/packet.h" 23 | 24 | namespace scl::net { 25 | 26 | /** 27 | * @brief Peer-to-peer communication channel interface. 28 | */ 29 | class Channel { 30 | public: 31 | virtual ~Channel() {} 32 | 33 | /** 34 | * @brief Close connection to remote. 35 | */ 36 | virtual void close() = 0; 37 | 38 | /** 39 | * @brief Send a data packet on the channel. 40 | * @param packet the packet to send. 41 | */ 42 | virtual coro::Task send(Packet&& packet) = 0; 43 | 44 | /** 45 | * @brief Send a data packet on the channel. 46 | * @param packet the packet to send. 47 | */ 48 | virtual coro::Task send(const Packet& packet) = 0; 49 | 50 | /** 51 | * @brief Receive a data packet from on the channel. 52 | * @return the received packet. 53 | */ 54 | virtual coro::Task recv() = 0; 55 | 56 | /** 57 | * @brief Check if there is something to receive on this channel. 58 | * @return true if this channel has data and false otherwise. 59 | */ 60 | virtual coro::Task hasData() = 0; 61 | }; 62 | 63 | } // namespace scl::net 64 | 65 | #endif // SCL_NET_CHANNEL_H 66 | -------------------------------------------------------------------------------- /include/scl/net/net.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_NET_NET_H 19 | #define SCL_NET_NET_H 20 | 21 | #include "scl/net/config.h" 22 | #include "scl/net/loopback.h" 23 | #include "scl/net/network.h" 24 | #include "scl/net/tcp_channel.h" 25 | 26 | /** 27 | * @brief %Network utilities. 28 | */ 29 | namespace scl::net {} // namespace scl::net 30 | 31 | #endif // SCL_NET_NET_H 32 | -------------------------------------------------------------------------------- /include/scl/protocol/clock.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_PROTOCOL_CLOCK_H 19 | #define SCL_PROTOCOL_CLOCK_H 20 | 21 | #include "scl/util/time.h" 22 | 23 | namespace scl::proto { 24 | 25 | /** 26 | * @brief A clock interface. 27 | */ 28 | struct Clock { 29 | virtual ~Clock() {} 30 | 31 | /** 32 | * @brief Read the current value of the clock. 33 | */ 34 | virtual util::Time::Duration read() const = 0; 35 | }; 36 | 37 | /** 38 | * @brief A clock implementation based on real time. 39 | */ 40 | class RealtimeClock final : public Clock { 41 | public: 42 | /** 43 | * @brief Create a new RealtimeClock. 44 | */ 45 | RealtimeClock() : m_clock_start(util::Time::now()) {} 46 | 47 | /** 48 | * @brief Read the current value of the clock. 49 | * @return the amount of time elapsed since this clock was created. 50 | */ 51 | util::Time::Duration read() const override { 52 | return util::Time::now() - m_clock_start; 53 | } 54 | 55 | private: 56 | util::Time::TimePoint m_clock_start; 57 | }; 58 | 59 | } // namespace scl::proto 60 | 61 | #endif // SCL_PROTOCOL_CLOCK_H 62 | -------------------------------------------------------------------------------- /include/scl/protocol/env.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_PROTOCOL_ENV_H 19 | #define SCL_PROTOCOL_ENV_H 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "scl/net/network.h" 28 | #include "scl/protocol/clock.h" 29 | #include "scl/util/time.h" 30 | 31 | namespace scl::proto { 32 | 33 | /** 34 | * @brief Environment for protocol executions. 35 | * 36 | * ProtocolEnvironment is meant to provide a protocol controlled access to a 37 | * number of useful resources, such as a network, but also the ability to know 38 | * its total running time, as well as the ability to work with threads. 39 | */ 40 | struct Env { 41 | /** 42 | * @brief The network. 43 | */ 44 | net::Network network; 45 | 46 | /** 47 | * @brief Clock used to tell for how long the protocol has been running. 48 | */ 49 | std::unique_ptr clock; 50 | }; 51 | 52 | /** 53 | * @brief Create an environment from a network. 54 | * @param network the network. 55 | * @return an Env object. 56 | * 57 | * The returned environemnt uses the RealTimeClock and StlThreadContext for the 58 | * environment's clock and thread context, respectively. 59 | */ 60 | inline Env createDefaultEnv(net::Network network) { 61 | return Env{.network = std::move(network), 62 | .clock = std::make_unique()}; 63 | } 64 | 65 | } // namespace scl::proto 66 | 67 | #endif // SCL_PROTOCOL_ENV_H 68 | -------------------------------------------------------------------------------- /include/scl/protocol/eval.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_PROTOCOL_EVAL_H 19 | #define SCL_PROTOCOL_EVAL_H 20 | 21 | #include 22 | #include 23 | 24 | #include "scl/coro/task.h" 25 | #include "scl/protocol/base.h" 26 | #include "scl/protocol/env.h" 27 | #include "scl/protocol/result.h" 28 | 29 | namespace scl::proto { 30 | 31 | /** 32 | * @brief Evaluate a protocol. 33 | * @param protocol the protocol to evaluate. 34 | * @param env the environment to use. 35 | * @param output_callback a callable that receives protocol outputs. 36 | * 37 | * This function will evaluate a protocol, passing any outputs that 38 | * the protocol produces to @p output_callback. 39 | */ 40 | template 41 | coro::Task evaluate(std::unique_ptr protocol, 42 | Env& env, 43 | CALLBACK output_callback) { 44 | while (protocol) { 45 | ProtocolResult result = co_await protocol->run(env); 46 | 47 | if (result.next_protocol) { 48 | protocol = std::move(result.next_protocol); 49 | } 50 | 51 | if (result.result.has_value()) { 52 | output_callback(result.result); 53 | } 54 | } 55 | 56 | co_return; 57 | } 58 | 59 | /** 60 | * @brief Evaluate a protocol. 61 | * @tparam RESULT the type of the protocol's output. 62 | * @param protocol the protocol to evaluate. 63 | * @param env the environment to use. 64 | * 65 | * This function evaluates a protocol and returns the result that it 66 | * produces. If the protocol terminates, but produces no output, then 67 | * an std::logic_error is thrown. Similarly, if the result produced 68 | * cannot be std::any_cast to something of type 69 | * RESULT, then an error is thrown. 70 | */ 71 | template 72 | coro::Task evaluate(std::unique_ptr protocol, Env& env) { 73 | while (protocol) { 74 | ProtocolResult result = co_await protocol->run(env); 75 | 76 | if (result.next_protocol) { 77 | protocol = std::move(result.next_protocol); 78 | } else { 79 | if (result.result.has_value()) { 80 | co_return std::any_cast(result.result); 81 | } else { 82 | throw std::logic_error("Protocol did not produce any result"); 83 | } 84 | } 85 | } 86 | } 87 | 88 | /** 89 | * @brief Evaluate a protocol that produces no result. 90 | * @param protocol the protocol to evaluate. 91 | * @param env the environment to use. 92 | */ 93 | template <> 94 | inline coro::Task evaluate(std::unique_ptr protocol, Env& env) { 95 | while (protocol) { 96 | ProtocolResult result = co_await protocol->run(env); 97 | protocol = std::move(result.next_protocol); 98 | } 99 | } 100 | 101 | } // namespace scl::proto 102 | 103 | #endif // SCL_PROTOCOL_EVAL_H 104 | -------------------------------------------------------------------------------- /include/scl/protocol/protocol.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_PROTOCOL_PROTOCOL_H 19 | #define SCL_PROTOCOL_PROTOCOL_H 20 | 21 | #include "scl/protocol/base.h" 22 | #include "scl/protocol/env.h" 23 | #include "scl/protocol/eval.h" 24 | #include "scl/protocol/result.h" 25 | 26 | /** 27 | * @brief %Protocol utilities. 28 | */ 29 | namespace scl::proto {} // namespace scl::proto 30 | 31 | #endif // SCL_PROTOCOL_PROTOCOL_H 32 | -------------------------------------------------------------------------------- /include/scl/protocol/result.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_PROTOCOL_RESULT_H 19 | #define SCL_PROTOCOL_RESULT_H 20 | 21 | #include 22 | #include 23 | 24 | namespace scl::proto { 25 | 26 | struct Protocol; 27 | 28 | /** 29 | * @brief The Result of running a Protocol. 30 | * 31 | * All Protocols must return a ProtocolResult object indicating (1) the next 32 | * protocol to run, and (2) the output produced by the protocol. Either can be 33 | * empty, which gives rise to the four constructions present on this class. 34 | */ 35 | struct ProtocolResult { 36 | /** 37 | * @brief Create a protocol result without any next steps or output. 38 | * 39 | * Result returned by a final protocol that produced no output. 40 | */ 41 | static ProtocolResult done() { 42 | return {.next_protocol = nullptr, .result = {}}; 43 | } 44 | 45 | /** 46 | * @brief Create a protocol result without any next steps and an output. 47 | * 48 | * Result returned by a final protocol that produced some output. 49 | */ 50 | static ProtocolResult done(std::any output) { 51 | return ProtocolResult{.next_protocol = nullptr, 52 | .result = std::move(output)}; 53 | } 54 | 55 | /** 56 | * @brief Create a protocol result with a next step. 57 | * 58 | * Result returned by an intermediary protocol that produced no output. 59 | */ 60 | static ProtocolResult next(std::unique_ptr next) { 61 | return ProtocolResult{.next_protocol = std::move(next), .result = {}}; 62 | } 63 | 64 | /** 65 | * @brief Create a protocol result with a next step and output. 66 | * 67 | * Result returned by an intermediary protocol that produced some output. 68 | */ 69 | static ProtocolResult next(std::unique_ptr next, std::any output) { 70 | return ProtocolResult{.next_protocol = std::move(next), 71 | .result = std::move(output)}; 72 | } 73 | 74 | /** 75 | * @brief The next protocol to run. A nullptr value indicates no next step. 76 | */ 77 | std::unique_ptr next_protocol; 78 | 79 | /** 80 | * @brief The output of the protocol. 81 | */ 82 | std::any result; 83 | }; 84 | 85 | } // namespace scl::proto 86 | 87 | #endif // SCL_PROTOCOL_RESULT_H 88 | -------------------------------------------------------------------------------- /include/scl/scl.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_SCL_H 19 | #define SCL_SCL_H 20 | 21 | #include "scl/coro/coroutine.h" 22 | #include "scl/math/math.h" 23 | #include "scl/net/net.h" 24 | #include "scl/protocol/protocol.h" 25 | #include "scl/serialization/serialization.h" 26 | #include "scl/simulation/simulation.h" 27 | #include "scl/ss/ss.h" 28 | #include "scl/util/util.h" 29 | 30 | /** 31 | * @brief Main namespace. 32 | */ 33 | namespace scl {} // namespace scl 34 | 35 | #endif // SCL_SCL_H 36 | -------------------------------------------------------------------------------- /include/scl/serialization/serializable.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_SERIALIZATION_SERIALIZABLE_H 19 | #define SCL_SERIALIZATION_SERIALIZABLE_H 20 | 21 | #include "scl/serialization/serializer.h" 22 | 23 | namespace scl::seri { 24 | 25 | /** 26 | * @brief Requirements for a type to be serializable in SCL. 27 | */ 28 | template 29 | concept Serializable = 30 | requires(T v, const unsigned char* in, unsigned char* out) { 31 | { Serializer::sizeOf(v) } -> std::same_as; 32 | { Serializer::write(v, out) } -> std::same_as; 33 | { Serializer::read(v, in) } -> std::same_as; 34 | }; 35 | 36 | } // namespace scl::seri 37 | 38 | #endif // SCL_SERIALIZATION_SERIALIZABLE_H 39 | -------------------------------------------------------------------------------- /include/scl/serialization/serialization.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_SERIALIZATION_SERIALIZATION_H 19 | #define SCL_SERIALIZATION_SERIALIZATION_H 20 | 21 | #include "scl/serialization/serializable.h" 22 | #include "scl/serialization/serializer.h" 23 | 24 | /** 25 | * @brief Code for serializing and deserializing things. 26 | */ 27 | namespace scl::seri {} 28 | 29 | #endif // SCL_SERIALIZATION_SERIALIZATION_H 30 | -------------------------------------------------------------------------------- /include/scl/simulation/cancellation.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_SIMULATION_CANCELLATION_H 19 | #define SCL_SIMULATION_CANCELLATION_H 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "scl/util/bitmap.h" 26 | 27 | namespace scl::sim::details { 28 | 29 | /** 30 | * @brief Exception used to signal that a coroutine has been cancelled. 31 | */ 32 | struct CancellationException final : public std::runtime_error { 33 | CancellationException() : std::runtime_error("cancelled") {} 34 | }; 35 | 36 | } // namespace scl::sim::details 37 | 38 | #endif // SCL_SIMULATION_CANCELLATION_H 39 | -------------------------------------------------------------------------------- /include/scl/simulation/channel.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_SIMULATION_CHANNEL_H 19 | #define SCL_SIMULATION_CHANNEL_H 20 | 21 | #include 22 | 23 | #include "scl/coro/task.h" 24 | #include "scl/net/channel.h" 25 | #include "scl/simulation/channel_id.h" 26 | #include "scl/simulation/context.h" 27 | #include "scl/simulation/transport.h" 28 | 29 | namespace scl::sim::details { 30 | 31 | /** 32 | * @brief Channel implementation used during simulations. 33 | */ 34 | class SimulatedChannel final : public net::Channel { 35 | public: 36 | /** 37 | * @brief Construct a SimulatedChannel. 38 | * @param cid the ID of this channel. 39 | * @param context a context object for this channel. 40 | * @param transport the transport to use for moving data. 41 | */ 42 | SimulatedChannel(ChannelId cid, 43 | GlobalContext::LocalContext context, 44 | std::shared_ptr transport) 45 | : m_cid(cid), m_context(context), m_transport(transport) {} 46 | 47 | /** 48 | * @brief Closes the channel. 49 | * 50 | * Creates a EventType::CLOSE event. 51 | */ 52 | void close() override; 53 | 54 | /** 55 | * @brief Sends data on the channel. 56 | * 57 | * Creates a EventType::SEND event. 58 | */ 59 | coro::Task send(net::Packet&& packet) override; 60 | 61 | /** 62 | * @brief Sends data on the channel. 63 | * 64 | * Creates a EventType::SEND event. 65 | */ 66 | coro::Task send(const net::Packet& packet) override; 67 | 68 | /** 69 | * @brief Receives data on the channel. 70 | * 71 | * Creates a EventType::RECV event. 72 | */ 73 | coro::Task recv() override; 74 | 75 | /** 76 | * @brief Checks if there is data available on this channel. 77 | * 78 | * Creates a EventType::HAS_DATA event. 79 | */ 80 | coro::Task hasData() override; 81 | 82 | private: 83 | ChannelId m_cid; 84 | GlobalContext::LocalContext m_context; 85 | std::shared_ptr m_transport; 86 | }; 87 | 88 | } // namespace scl::sim::details 89 | 90 | #endif // SCL_SIMULATION_CHANNEL_H 91 | -------------------------------------------------------------------------------- /include/scl/simulation/channel_id.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_SIMULATION_CHANNEL_ID_H 19 | #define SCL_SIMULATION_CHANNEL_ID_H 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | namespace scl::sim { 26 | 27 | /** 28 | * @brief Channel identifier. 29 | * 30 | *

During simulations, each pair of parties are connected by two channels 31 | * {i, j} and {j, i}. The channel {i, j} 32 | * is used by i when writing to j. 33 | * 34 | *

ChannelId is == and < comparable, and a 35 | * specialization for std::hash exists. ChannelId can therefore be used as a key 36 | * in a std::map. 37 | */ 38 | struct ChannelId { 39 | /** 40 | * @brief ID of this party. 41 | */ 42 | std::size_t local; 43 | 44 | /** 45 | * @brief ID of the remote party. 46 | */ 47 | std::size_t remote; 48 | 49 | /** 50 | * @brief Flips the view of the this ID. 51 | */ 52 | ChannelId flip() const { 53 | return {remote, local}; 54 | } 55 | 56 | /** 57 | * @brief operator == for ChannelIds. 58 | */ 59 | friend bool operator==(const ChannelId& cid0, const ChannelId& cid1) { 60 | return cid0.local == cid1.local && cid0.remote == cid1.remote; 61 | } 62 | 63 | /** 64 | * @brief operator < for ChannelIds. 65 | */ 66 | friend bool operator<(const ChannelId& cid0, const ChannelId& cid1) { 67 | return cid0.local < cid1.local || 68 | (cid0.local == cid1.local && cid0.remote < cid1.remote); 69 | } 70 | 71 | /** 72 | * @brief Print operator for ChannelId. 73 | */ 74 | friend std::ostream& operator<<(std::ostream& os, const ChannelId& cid) { 75 | return os << "{local=" << cid.local << ", remote=" << cid.remote << "}"; 76 | } 77 | }; 78 | 79 | } // namespace scl::sim 80 | 81 | /// @cond 82 | 83 | template <> 84 | struct std::hash { 85 | std::size_t operator()(const scl::sim::ChannelId& cid) const { 86 | return cid.local ^ (cid.remote << 32); 87 | } 88 | }; 89 | 90 | /// @endcond 91 | 92 | #endif // SCL_SIMULATION_CHANNEL_ID_H 93 | -------------------------------------------------------------------------------- /include/scl/simulation/hook.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_SIMULATION_HOOK_H 19 | #define SCL_SIMULATION_HOOK_H 20 | 21 | #include 22 | 23 | #include "scl/simulation/event.h" 24 | 25 | namespace scl::sim { 26 | 27 | class SimulationContext; 28 | 29 | /** 30 | * @brief Interface for hooks. 31 | * 32 | * A hook is a piece of a code that is run in response to an event, and can 33 | * therefore be used to add custom logging or simulation termination. 34 | * 35 | * @code 36 | * struct MyHook final : public Hook { 37 | * void run(std::size_t party_id, const ReadOnlyGlobalContext& ctx) override 38 | * { 39 | * auto event = (ProtocolEvent*)ctx.trace(party_id)->back(); 40 | * std::cout << "Party " << party_id 41 | * << " finished running " event->protocol_name; 42 | * << std::endl; 43 | * } 44 | * }; 45 | * 46 | * // elsewhere 47 | * 48 | * Manager* manager = // create a Manager object 49 | * manager->addHook(sim::EventType::PROTOCOL_END); 50 | * @endcode 51 | * 52 | * The hooks are run right after the triggering event has been added to the 53 | * party's event trace. It is therefore safe to assume that 54 | * ctx.traces[party_id] is not empty. 55 | * 56 | * A party, or the simulation as a whole, can be stopped through the 57 | * SimulationContext object that the hook receives. This is useful 58 | * to e.g., terminate the simulation when a particular party finishes. 59 | * 60 | * @code 61 | * struct MyHook final : public Hook { 62 | * void run(std::size_t party_id, const ReadOnlyGlobalContext& ctx) override { 63 | * // stop the other party 64 | * ctx.cancel(1 - party); 65 | * } 66 | * }; 67 | * 68 | * // elsewhere 69 | * 70 | * Manager* manager = // ... 71 | * // call the hook when a party finishes the simulation. The hook will then 72 | * // cancel the other party, which must still be running. 73 | * manager->addHook(sim::EventType::STOP); 74 | * @endcode 75 | * 76 | * Terminating the calling party (the party indicated by the 77 | * party_id argument) on any of the following events 78 | *

    79 | *
  • sim::EventType::STOP 80 | *
  • sim::EventType::KILLED 81 | *
  • sim::EventType::CANCELLED 82 | *
83 | * is undefined behaviour. 84 | * 85 | * @see sim::Manager::addHook 86 | */ 87 | struct Hook { 88 | virtual ~Hook() {} 89 | 90 | /** 91 | * @brief Function to run. 92 | */ 93 | virtual void run(std::size_t party_id, const SimulationContext& ctx) = 0; 94 | }; 95 | 96 | /** 97 | * @brief A hook and trigger event. 98 | */ 99 | struct TriggerAndHook { 100 | /** 101 | * @brief The event to trigger the hook on. 102 | */ 103 | std::optional trigger; 104 | /** 105 | * @brief The hook. 106 | */ 107 | std::unique_ptr hook; 108 | }; 109 | 110 | } // namespace scl::sim 111 | 112 | #endif // SCL_SIMULATION_HOOK_H 113 | -------------------------------------------------------------------------------- /include/scl/simulation/runtime.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_SIMULATION_RUNTIME_H 19 | #define SCL_SIMULATION_RUNTIME_H 20 | 21 | #include 22 | #include 23 | 24 | #include "scl/coro/runtime.h" 25 | #include "scl/simulation/context.h" 26 | #include "scl/simulation/event.h" 27 | 28 | namespace scl::sim::details { 29 | 30 | /** 31 | * @brief Runtime implementation used in the simulator. 32 | */ 33 | class SimulatorRuntime final : public coro::Runtime { 34 | constexpr static std::size_t MANAGER_PID = -1; 35 | 36 | struct Coro { 37 | std::coroutine_handle<> coroutine; 38 | std::function predicate; 39 | std::size_t party_id; 40 | }; 41 | 42 | public: 43 | /** 44 | * @brief Construct a new simulator runtime. 45 | */ 46 | SimulatorRuntime(GlobalContext& ctx) 47 | : m_ctx(ctx), m_current_pid(MANAGER_PID) {} 48 | 49 | ~SimulatorRuntime() {} 50 | 51 | using coro::Runtime::schedule; 52 | 53 | /** 54 | * @brief Schedule a coroutine to run for a particular party. 55 | * @param coroutine the coroutine. 56 | * @param id the id of the party. 57 | * 58 | * This function is used when scheduling the initial batch of protocols. Each 59 | * protocol run gets assigned a party id using this function, and the ID is 60 | * then used throughout the execution in order correctly manipulate the 61 | * context. 62 | */ 63 | void scheduleWithId(std::coroutine_handle<> coroutine, std::size_t id) { 64 | m_tq.emplace_back( 65 | coroutine, 66 | []() { return true; }, 67 | id); 68 | } 69 | 70 | void schedule(std::coroutine_handle<> coroutine, 71 | std::function&& predicate) override; 72 | 73 | void schedule(std::coroutine_handle<> coroutine, 74 | util::Time::Duration delay) override; 75 | 76 | void deschedule(std::coroutine_handle<> coroutine) override; 77 | 78 | std::coroutine_handle<> next() override; 79 | 80 | bool taskQueueEmpty() const override { 81 | return m_tq.empty(); 82 | } 83 | 84 | private: 85 | GlobalContext& m_ctx; 86 | 87 | std::size_t m_current_pid; 88 | std::list m_tq; 89 | 90 | void removeCancelledCoros(); 91 | }; 92 | 93 | } // namespace scl::sim::details 94 | 95 | #endif // SCL_SIMULATION_RUNTIME_H 96 | -------------------------------------------------------------------------------- /include/scl/simulation/simulation.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_SIMULATION_SIMULATION_H 19 | #define SCL_SIMULATION_SIMULATION_H 20 | 21 | #include "scl/simulation/config.h" 22 | #include "scl/simulation/simulator.h" 23 | 24 | /** 25 | * @brief Protocol simulation. 26 | */ 27 | namespace scl::sim {} // namespace scl::sim 28 | 29 | #endif // SCL_SIMULATION_SIMULATION_H 30 | -------------------------------------------------------------------------------- /include/scl/simulation/simulator.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_SIMULATION_SIMULATOR_H 19 | #define SCL_SIMULATION_SIMULATOR_H 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "scl/protocol/base.h" 26 | #include "scl/simulation/config.h" 27 | #include "scl/simulation/event.h" 28 | #include "scl/simulation/manager.h" 29 | 30 | namespace scl::sim { 31 | 32 | /** 33 | * @brief Simulate the execution of a protocol. 34 | * @param manager a simulation manager. 35 | */ 36 | void simulate(std::unique_ptr manager); 37 | 38 | } // namespace scl::sim 39 | 40 | #endif // SCL_SIMULATION_SIMULATOR_H 41 | -------------------------------------------------------------------------------- /include/scl/ss/additive.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_SS_ADDITIVE_H 19 | #define SCL_SS_ADDITIVE_H 20 | 21 | #include 22 | 23 | #include "scl/math/vector.h" 24 | #include "scl/util/prg.h" 25 | 26 | namespace scl::ss { 27 | 28 | /** 29 | * @brief Creates an additive secret-sharing. 30 | * @param secret the secret to secret-share. 31 | * @param n the number of shares. 32 | * @param prg a PRG used to generate random shares. 33 | * @return An additive secret-sharing. 34 | * 35 | *

An additive secret-sharing of a value \f$x\f$ is a list 36 | * \f$(x_1,x_2,\dots,x_n)\f$ of values such that \f$x=\sum_i x_i\f$. 37 | * 38 | *

An additive secret-sharing output by this function is a math::Vec object, 39 | * and so reconstructing the secret is simply shares.sum(). 40 | */ 41 | template 42 | math::Vector additiveShare(const T& secret, std::size_t n, util::PRG& prg) { 43 | std::vector shares; 44 | shares.reserve(n); 45 | auto sum = T::zero(); 46 | for (std::size_t i = 0; i < n - 1; ++i) { 47 | const auto s = T::random(prg); 48 | shares.emplace_back(s); 49 | sum += s; 50 | } 51 | shares.emplace_back(secret - sum); 52 | return shares; 53 | } // LCOV_EXCL_LINE 54 | 55 | } // namespace scl::ss 56 | 57 | #endif // SCL_SS_ADDITIVE_H 58 | -------------------------------------------------------------------------------- /include/scl/ss/ss.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_SS_SS_H 19 | #define SCL_SS_SS_H 20 | 21 | #include "scl/ss/additive.h" 22 | #include "scl/ss/feldman.h" 23 | #include "scl/ss/pedersen.h" 24 | #include "scl/ss/shamir.h" 25 | 26 | /** 27 | * @brief Secret sharing utilities. 28 | * 29 | * The scl::ss namespace contains a small collection of functionalities 30 | * related to secret-sharing. 31 | */ 32 | namespace scl::ss {} // namespace scl::ss 33 | 34 | #endif // SCL_SS_SS_H 35 | -------------------------------------------------------------------------------- /include/scl/util/digest.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_UTIL_DIGEST_H 19 | #define SCL_UTIL_DIGEST_H 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "scl/util/str.h" 26 | 27 | namespace scl::util { 28 | 29 | /** 30 | * @brief A digest of some bitsize. 31 | * @tparam Bits the bitsize of the digest 32 | * 33 | * This type is effectively std::array. 34 | */ 35 | template 36 | using Digest = std::array; 37 | 38 | /** 39 | * @brief Convert a digest to a string. 40 | * @param digest the digest 41 | * @return a hex representation of the digest. 42 | */ 43 | template 44 | std::string digestToString(const DIGEST& digest) { 45 | return toHexString(digest.begin(), digest.end()); 46 | } 47 | 48 | } // namespace scl::util 49 | 50 | #endif // SCL_UTIL_DIGEST_H 51 | -------------------------------------------------------------------------------- /include/scl/util/hash.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_UTIL_HASH_H 19 | #define SCL_UTIL_HASH_H 20 | 21 | #include 22 | 23 | #include "scl/util/digest.h" 24 | #include "scl/util/sha3.h" 25 | 26 | namespace scl::util { 27 | 28 | /** 29 | * @brief A default hash function given a digest size. 30 | * 31 | * This type defults to one of the three instantiations of SHA3 that SCL 32 | * provides. 33 | */ 34 | template 35 | using Hash = Sha3; 36 | 37 | } // namespace scl::util 38 | 39 | #endif // SCL_UTIL_HASH_H 40 | -------------------------------------------------------------------------------- /include/scl/util/iuf_hash.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_UTIL_IUF_HASH_H 19 | #define SCL_UTIL_IUF_HASH_H 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "scl/serialization/serializer.h" 29 | 30 | namespace scl::util { 31 | 32 | /** 33 | * @brief IUF (Init-Update-Finalize) interface for hash functions. 34 | * @tparam HASH hash implementation. 35 | * 36 | * IUFHash provides a CRTP style interface for a hash function implementation 37 | * 38 | * @see Sha3 39 | * @see Sha256 40 | */ 41 | template 42 | struct IUFHash { 43 | /** 44 | * @brief Update the hash function with a set of bytes. 45 | * @param bytes a pointer to a number of bytes. 46 | * @param n the number of bytes. 47 | * @return the updated Hash object. 48 | */ 49 | IUFHash& update(const unsigned char* bytes, std::size_t n) { 50 | static_cast(this)->hash(bytes, n); 51 | return *this; 52 | }; 53 | 54 | /** 55 | * @brief Update the hash function with the content from a byte vector. 56 | * @param data a vector of bytes. 57 | * @return the updated Hash object. 58 | */ 59 | IUFHash& update(const std::vector& data) { 60 | return update(data.data(), data.size()); 61 | }; 62 | 63 | /** 64 | * @brief Update the hash function with the content from a byte STL array. 65 | * @param data the array 66 | * @return the updated Hash object. 67 | */ 68 | template 69 | IUFHash& update(const std::array& data) { 70 | return update(data.data(), N); 71 | } 72 | 73 | /** 74 | * @brief Update the hash function with the content of a string. 75 | * @param string the string. 76 | * @return the updated Hash object. 77 | */ 78 | IUFHash& update(std::string_view string) { 79 | return update(reinterpret_cast(string.data()), 80 | string.size()); 81 | } 82 | 83 | /** 84 | * @brief Update the hash function with the content of a serializable type. 85 | * @param data the data. 86 | * @return the updated Hash object. 87 | */ 88 | template 89 | IUFHash& update(const T& data) { 90 | using Sr = seri::Serializer; 91 | const auto size = Sr::sizeOf(data); 92 | const auto buf = std::make_unique(size); 93 | Sr::write(data, buf.get()); 94 | return update(buf.get(), size); 95 | } 96 | 97 | /** 98 | * @brief Finalize and return the digest. 99 | * @return a digest. 100 | */ 101 | auto finalize() { 102 | auto digest = static_cast(this)->write(); 103 | return digest; 104 | }; 105 | }; 106 | 107 | } // namespace scl::util 108 | 109 | #endif // SCL_UTIL_IUF_HASH_H 110 | -------------------------------------------------------------------------------- /include/scl/util/merkle_proof.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_UTIL_MERKLE_PROOF_H 19 | #define SCL_UTIL_MERKLE_PROOF_H 20 | 21 | #include 22 | 23 | #include "scl/serialization/serializer.h" 24 | #include "scl/util/bitmap.h" 25 | 26 | namespace scl { 27 | namespace util { 28 | 29 | /** 30 | * @brief A Merkle tree proof. 31 | */ 32 | template 33 | struct MerkleProof { 34 | /** 35 | * @brief The path from a particular leaf to the root. 36 | */ 37 | std::vector path; 38 | 39 | /** 40 | * @brief A vector describing whether at the left or right element for each 41 | * element in a path. 42 | */ 43 | Bitmap direction; 44 | }; 45 | 46 | } // namespace util 47 | 48 | namespace seri { 49 | 50 | /** 51 | * @brief Serializer for MerkleProof. 52 | */ 53 | template 54 | struct Serializer> { 55 | /** 56 | * @brief Determines the size in bytes of a merkle proof. 57 | * @param proof the proof. 58 | * @return the size of \p proof in bytes. 59 | */ 60 | static std::size_t sizeOf(const util::MerkleProof& proof) { 61 | return Serializer>::sizeOf(proof.path) + 62 | Serializer::sizeOf(proof.direction); 63 | } 64 | 65 | /** 66 | * @brief Write a merkle proof to a buffer. 67 | * @param proof the proof. 68 | * @param buf the buffer. 69 | * @return the number of bytes written to \p buf. 70 | */ 71 | static std::size_t write(const util::MerkleProof& proof, 72 | unsigned char* buf) { 73 | buf += Serializer>::write(proof.path, buf); 74 | buf += Serializer::write(proof.direction, buf); 75 | return sizeOf(proof); 76 | } 77 | 78 | /** 79 | * @brief Read a merkle proof from a buffer. 80 | * @param proof the proof. 81 | * @param buf the buffer. 82 | * @return the number of bytes read from \p buf. 83 | */ 84 | static std::size_t read(util::MerkleProof& proof, 85 | const unsigned char* buf) { 86 | buf += Serializer>::read(proof.path, buf); 87 | buf += Serializer::read(proof.direction, buf); 88 | return sizeOf(proof); 89 | } 90 | }; 91 | 92 | } // namespace seri 93 | } // namespace scl 94 | 95 | #endif // SCL_UTIL_MERKLE_PROOF_H 96 | -------------------------------------------------------------------------------- /include/scl/util/sha256.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_UTIL_SHA256_H 19 | #define SCL_UTIL_SHA256_H 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "scl/util/digest.h" 26 | #include "scl/util/iuf_hash.h" 27 | 28 | namespace scl::util { 29 | 30 | /** 31 | * @brief SHA256 hash function. 32 | */ 33 | class Sha256 final : public IUFHash { 34 | public: 35 | /** 36 | * @brief The type of a SHA256 digest. 37 | */ 38 | using DigestType = Digest<256>; 39 | 40 | /** 41 | * @brief Update the hash function with a set of bytes. 42 | * @param bytes a pointer to a number of bytes. 43 | * @param nbytes the number of bytes. 44 | */ 45 | void hash(const unsigned char* bytes, std::size_t nbytes); 46 | 47 | /** 48 | * @brief Finalize and return the digest. 49 | */ 50 | DigestType write(); 51 | 52 | private: 53 | std::array m_chunk; 54 | std::uint32_t m_chunk_pos = 0; 55 | std::size_t m_total_len = 0; 56 | std::array m_state = {0x6a09e667, 57 | 0xbb67ae85, 58 | 0x3c6ef372, 59 | 0xa54ff53a, 60 | 0x510e527f, 61 | 0x9b05688c, 62 | 0x1f83d9ab, 63 | 0x5be0cd19}; 64 | 65 | void transform(); 66 | void pad(); 67 | DigestType writeDigest(); 68 | }; 69 | 70 | } // namespace scl::util 71 | 72 | #endif // SCL_UTIL_SHA256_H 73 | -------------------------------------------------------------------------------- /include/scl/util/str.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_UTIL_STR_H 19 | #define SCL_UTIL_STR_H 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | namespace scl::util { 28 | 29 | #define SCL_TO_HEX(v, c) \ 30 | do { \ 31 | if ((c) >= '0' && (c) <= '9') \ 32 | (v) += (c) - '0'; \ 33 | else if ((c) >= 'a' && (c) <= 'f') \ 34 | (v) += (c) - 'a' + 10; \ 35 | else if ((c) >= 'A' && (c) <= 'F') \ 36 | (v) += (c) - 'A' + 10; \ 37 | else \ 38 | throw std::invalid_argument("encountered invalid hex character"); \ 39 | } while (0) 40 | 41 | /** 42 | * @brief Convert a string in hex. 43 | * @tparam T the output type 44 | * 45 | * Normal conventions for hex strings apply, although the 0x prefix 46 | * is not permitted. The input is assumed to encode an integer in big endian. 47 | */ 48 | template 49 | T fromHexString(const std::string& s) { 50 | auto n = s.size(); 51 | if (n % 2) { 52 | throw std::invalid_argument("odd-length hex string"); 53 | } 54 | T t = 0; 55 | for (std::size_t i = 0; i < n; i += 2) { 56 | char c0 = s[i]; 57 | char c1 = s[i + 1]; 58 | t = t << 4; 59 | SCL_TO_HEX(t, c0); 60 | t = t << 4; 61 | SCL_TO_HEX(t, c1); 62 | } 63 | return t; 64 | } 65 | 66 | #undef SCL_TO_HEX 67 | 68 | /** 69 | * @brief Convert value into a string. 70 | */ 71 | template 72 | std::string toHexString(const T& v) { 73 | std::stringstream ss; 74 | ss << std::hex << v; 75 | return ss.str(); 76 | } 77 | 78 | /** 79 | * @brief Convert a list of bytes to a string. 80 | * @param begin the start of an iterator 81 | * @param end the end of an iterator 82 | * @return a hex representation of the digest. 83 | */ 84 | template 85 | std::string toHexString(It begin, It end) { 86 | std::stringstream ss; 87 | ss << std::setfill('0') << std::hex; 88 | while (begin != end) { 89 | ss << std::setw(2) << static_cast(*begin++); 90 | } 91 | return ss.str(); 92 | } 93 | 94 | /** 95 | * @brief ToHexString specialization for __uint128_t. 96 | */ 97 | template <> 98 | std::string toHexString(const __uint128_t& v); 99 | 100 | } // namespace scl::util 101 | 102 | #endif // SCL_UTIL_STR_H 103 | -------------------------------------------------------------------------------- /include/scl/util/time.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_UTIL_TIME_H 19 | #define SCL_UTIL_TIME_H 20 | 21 | #include 22 | #include 23 | 24 | namespace scl::util { 25 | 26 | /** 27 | * @brief Wrapper for time related types. 28 | */ 29 | struct Time { 30 | /** 31 | * @brief Duration type. 32 | */ 33 | using Duration = std::chrono::steady_clock::duration; 34 | 35 | /** 36 | * @brief Time point type. 37 | */ 38 | using TimePoint = std::chrono::steady_clock::time_point; 39 | 40 | /** 41 | * @brief Get the current time as a TimePoint. 42 | */ 43 | static TimePoint now() { 44 | return std::chrono::steady_clock::now(); 45 | }; 46 | }; 47 | 48 | /** 49 | * @brief Convert a timestamp to milliseconds. 50 | */ 51 | inline long double timeToMillis(Time::Duration time) { 52 | using namespace std::chrono; 53 | return duration(time).count(); 54 | } 55 | 56 | } // namespace scl::util 57 | 58 | #endif // SCL_UTIL_TIME_H 59 | -------------------------------------------------------------------------------- /include/scl/util/util.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_UTIL_UTIL_H 19 | #define SCL_UTIL_UTIL_H 20 | 21 | #include "scl/util/cmdline.h" 22 | #include "scl/util/hash.h" 23 | #include "scl/util/prg.h" 24 | 25 | /** 26 | * @brief Utilities and primitives. 27 | */ 28 | namespace scl::util {} // namespace scl::util 29 | 30 | #endif // SCL_UTIL_UTIL_H 31 | -------------------------------------------------------------------------------- /scripts/check_all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! [ -d "scripts" ]; then 4 | echo "run this script from the project root" 5 | exit 1 6 | fi 7 | 8 | function exit_if_failed { 9 | if [ "${1}" -eq 0 ]; then 10 | echo " passed" 11 | else 12 | echo " failed" 13 | exit 0 14 | fi 15 | } 16 | 17 | echo -n "Checking formatting ..." 18 | test $(scripts/check_formatting.sh 2>&1 | wc -l) -eq 0 19 | exit_if_failed $? 20 | 21 | echo -n "Checking header guards ..." 22 | python3 scripts/check_header_guards.py 23 | exit_if_failed $? 24 | 25 | echo -n "Checking copyright headers ..." 26 | python3 scripts/check_copyright_headers.py 27 | exit_if_failed $? 28 | 29 | echo -n "Checking documentation ..." 30 | . scripts/build_documentation.sh 1>/dev/null 31 | exit_if_failed $? 32 | -------------------------------------------------------------------------------- /scripts/check_copyright_headers.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | 5 | YEAR = "2024" 6 | AUTHOR = "Anders Dalskov" 7 | 8 | header = """\ 9 | /* SCL --- Secure Computation Library 10 | * Copyright (C) {year} {author} 11 | * 12 | * This program is free software: you can redistribute it and/or modify 13 | * it under the terms of the GNU Affero General Public License as published by 14 | * the Free Software Foundation, either version 3 of the License, or 15 | * (at your option) any later version. 16 | * 17 | * This program is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU Affero General Public License for more details. 21 | * 22 | * You should have received a copy of the GNU Affero General Public License 23 | * along with this program. If not, see . 24 | */ 25 | """ 26 | 27 | def check_file(filename, path): 28 | expected_header = header.format(year=YEAR, author=AUTHOR).rstrip().split("\n") 29 | with open(path, 'r') as f: 30 | lines = f.readlines()[:len(expected_header) + 1] 31 | n = 0 32 | good = True 33 | for a, b in zip(expected_header, lines): 34 | if a.rstrip() != b.rstrip(): 35 | good = False 36 | break 37 | n += 1 38 | ## license must be followed by an empty line 39 | good = (good and lines[n].rstrip() == "") 40 | if not good: 41 | print(f"{filename} invalid header (error on line: {n})") 42 | return good 43 | 44 | 45 | all_good = True 46 | directories_to_check = ["include", "src", "test"] 47 | 48 | for d in directories_to_check: 49 | for path, __, names in os.walk(d): 50 | for n in names: 51 | if n.endswith(".h") or n.endswith(".cc"): 52 | full_name = os.path.join(path, n) 53 | if not check_file(n, full_name): 54 | all_good = False 55 | 56 | 57 | exit(0 if all_good else 1) 58 | -------------------------------------------------------------------------------- /scripts/check_coverage.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o pipefail 4 | 5 | readarray -t COV <<< $(grep 'Overall coverage rate:' $1 -A 2) 6 | 7 | LINES=$(echo ${COV[1]} | grep -oE '[0-9]+\.[0-9]+') 8 | FUNCS=$(echo ${COV[2]} | grep -oE '[0-9]+\.[0-9]+') 9 | 10 | echo "Line coverage: ${LINES}% (target: ${COV_THRESHOLD_LINES}%)" 11 | echo "Function coverage: ${FUNCS}% (target: ${COV_THRESHOLD_FUNCS}%)" 12 | 13 | awk "BEGIN { if (${LINES} < ${COV_THRESHOLD_LINES}) { print \"line coverage not met\"; exit 1 } }" 14 | awk "BEGIN { if (${FUNCS} < ${COV_THRESHOLD_FUNCS}) { print \"function coverage not met\"; exit 1 } }" 15 | -------------------------------------------------------------------------------- /scripts/check_formatting.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eo pipefail 4 | 5 | find include/ src/ test/ -type f \( -iname "*.h" -o -iname "*.cc" \) -exec clang-format-15 -n {} \; &> /tmp/checks.txt 6 | cat /tmp/checks.txt 7 | [[ ! -s /tmp/checks.txt ]] 8 | -------------------------------------------------------------------------------- /scripts/check_header_guards.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | 5 | def check_guards(path, expected_header_guard): 6 | with open(path, 'r') as f: 7 | opening_header = False 8 | lines = f.readlines() 9 | i = 0 10 | while i < len(lines) - 1: 11 | if lines[i].rstrip() == '#ifndef ' + expected_header_guard: 12 | if lines[i + 1].rstrip() == '#define ' + expected_header_guard: 13 | opening_header = True 14 | break 15 | i += 1 16 | else: 17 | print('No opening header in', path) 18 | return False 19 | 20 | good = opening_header \ 21 | and lines[-1].rstrip() == '#endif // ' + expected_header_guard 22 | 23 | if not good: 24 | print(f'{path} invalid header') 25 | print('Expected:') 26 | print('#ifndef ' + expected_header_guard) 27 | print('#define ' + expected_header_guard) 28 | print('#endif // ' + expected_header_guard) 29 | print('Found:') 30 | print(lines[i].rstrip()) 31 | print(lines[i + 1].rstrip()) 32 | print(lines[-1].rstrip()) 33 | print('----') 34 | 35 | return good 36 | 37 | def check_dir(dirname): 38 | to_truncate = len(dirname) + 1 39 | all_good = True 40 | for path, _, names in os.walk(dirname): 41 | for n in names: 42 | if (n.endswith('.h')): 43 | truncated_path = path[to_truncate:] 44 | full_name = os.path.join(truncated_path, n) 45 | full_name = full_name.replace('/', '_').replace('.', '_') 46 | full_name = full_name.upper() 47 | 48 | if not check_guards(os.path.join(path, n), full_name): 49 | all_good = False 50 | return all_good 51 | 52 | 53 | all_good = check_dir('include') and check_dir('src') 54 | exit(0 if all_good else 1) 55 | -------------------------------------------------------------------------------- /src/scl/coro/runtime.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include "scl/coro/runtime.h" 19 | 20 | #include 21 | 22 | #include "scl/coro/task.h" 23 | 24 | using namespace scl; 25 | 26 | void coro::details::removeHandle(Runtime* runtime, 27 | std::coroutine_handle<> handle) { 28 | if (runtime != nullptr) { 29 | runtime->deschedule(handle); 30 | } 31 | } 32 | 33 | std::coroutine_handle<> coro::DefaultRuntime::next() { 34 | auto b = m_tq.begin(); 35 | const auto e = m_tq.end(); 36 | while (b != e) { 37 | const auto [coro, pred] = *b; 38 | if (pred()) { 39 | m_tq.erase(b); 40 | return coro; 41 | } 42 | b++; 43 | } 44 | return std::noop_coroutine(); 45 | } 46 | 47 | void coro::DefaultRuntime::deschedule(std::coroutine_handle<> coroutine) { 48 | m_tq.remove_if([&coroutine](const Pair& pair) { 49 | return std::get<0>(pair) == coroutine; 50 | }); 51 | } 52 | -------------------------------------------------------------------------------- /src/scl/math/fields/ff_ops_gmp.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include "scl/math/fields/ff_ops_gmp.h" 19 | 20 | using namespace scl; 21 | 22 | std::size_t math::ff::findFirstNonZero(const std::string& s) { 23 | int n = 0; 24 | for (const auto c : s) { 25 | if (c != '0') { 26 | return n; 27 | } 28 | n++; 29 | } 30 | return n; 31 | } 32 | -------------------------------------------------------------------------------- /src/scl/math/fields/mersenne127.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include "scl/math/fields/mersenne127.h" 19 | 20 | #include 21 | #include 22 | 23 | #include "./small_ff.h" 24 | #include "scl/math/fields/ff_ops.h" 25 | #include "scl/util/str.h" 26 | 27 | using namespace scl; 28 | 29 | using u64 = std::uint64_t; 30 | using u128 = __uint128_t; 31 | 32 | // The prime p = 2^127 - 1. 33 | static const u128 p = (((u128)0x7FFFFFFFFFFFFFFF) << 64) | 0xFFFFFFFFFFFFFFFF; 34 | 35 | using Mersenne127 = scl::math::ff::Mersenne127; 36 | 37 | template <> 38 | void math::ff::convertTo(u128& out, const int value) { 39 | out = value < 0 ? value + p : value; 40 | } 41 | 42 | template <> 43 | void math::ff::convertTo(u128& out, const std::string& src) { 44 | out = util::fromHexString(src); 45 | out = out % p; 46 | } 47 | 48 | template <> 49 | void math::ff::add(u128& out, const u128& op) { 50 | details::modAdd(out, op, p); 51 | } 52 | 53 | template <> 54 | void math::ff::subtract(u128& out, const u128& op) { 55 | details::modSub(out, op, p); 56 | } 57 | 58 | namespace { 59 | 60 | struct u256 { 61 | u128 high; 62 | u128 low; 63 | }; 64 | 65 | // https://cp-algorithms.com/algebra/montgomery_multiplication.html 66 | u256 multiplyFull(const u128 x, const u128 y) { 67 | u64 a = x >> 64; 68 | u64 b = x; 69 | u64 c = y >> 64; 70 | u64 d = y; 71 | // (a*2^64 + b) * (c*2^64 + d) = 72 | // (a*c) * 2^128 + (a*d + b*c)*2^64 + (b*d) 73 | u128 ac = (u128)a * c; 74 | u128 ad = (u128)a * d; 75 | u128 bc = (u128)b * c; 76 | u128 bd = (u128)b * d; 77 | 78 | u128 carry = (u128)(u64)ad + (u128)(u64)bc + (bd >> 64U); 79 | u128 high = ac + (ad >> 64U) + (bc >> 64U) + (carry >> 64U); 80 | u128 low = (ad << 64U) + (bc << 64U) + bd; 81 | 82 | return {high, low}; 83 | } 84 | 85 | } // namespace 86 | 87 | template <> 88 | void math::ff::multiply(u128& out, const u128& op) { 89 | u256 z = multiplyFull(out, op); 90 | out = z.high << 1; 91 | u128 b = z.low; 92 | 93 | out |= b >> 127; 94 | b &= p; 95 | 96 | details::modAdd(out, b, p); 97 | } 98 | 99 | template <> 100 | void math::ff::negate(u128& out) { 101 | details::modNeg(out, p); 102 | } 103 | 104 | template <> 105 | void math::ff::invert(u128& out) { 106 | details::modInv(out, out, p); 107 | } 108 | 109 | template <> 110 | bool math::ff::equal(const u128& in1, const u128& in2) { 111 | return in1 == in2; 112 | } 113 | 114 | template <> 115 | void math::ff::fromBytes(u128& dest, const unsigned char* src) { 116 | dest = *(const u128*)src; 117 | dest = dest % p; 118 | } 119 | 120 | template <> 121 | void math::ff::toBytes(unsigned char* dest, const u128& src) { 122 | std::memcpy(dest, &src, sizeof(u128)); 123 | } 124 | 125 | template <> 126 | std::string math::ff::toString(const u128& in) { 127 | return util::toHexString(in); 128 | } 129 | -------------------------------------------------------------------------------- /src/scl/math/fields/mersenne61.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include "scl/math/fields/mersenne61.h" 19 | 20 | #include 21 | #include 22 | 23 | #include "./small_ff.h" 24 | #include "scl/math/fields/ff_ops.h" 25 | #include "scl/util/str.h" 26 | 27 | using namespace scl; 28 | 29 | using u64 = std::uint64_t; 30 | using u128 = __uint128_t; 31 | 32 | // The prime p = 2^61 - 1 33 | static const u64 p = 0x1FFFFFFFFFFFFFFF; 34 | 35 | using Mersenne61 = scl::math::ff::Mersenne61; 36 | 37 | template <> 38 | void math::ff::convertTo(u64& out, const int value) { 39 | out = value < 0 ? value + p : value; 40 | } 41 | 42 | template <> 43 | void math::ff::convertTo(u64& out, const std::string& src) { 44 | out = util::fromHexString(src); 45 | out = out % p; 46 | } 47 | 48 | template <> 49 | void math::ff::add(u64& out, const u64& op) { 50 | details::modAdd(out, op, p); 51 | } 52 | 53 | template <> 54 | void math::ff::subtract(u64& out, const u64& op) { 55 | details::modSub(out, op, p); 56 | } 57 | 58 | template <> 59 | void math::ff::multiply(u64& out, const u64& op) { 60 | u128 z = (u128)out * op; 61 | u64 a = z >> 61; 62 | u64 b = (u64)z; 63 | 64 | a |= b >> 61; 65 | b &= p; 66 | 67 | details::modAdd(a, b, p); 68 | out = a; 69 | } 70 | 71 | template <> 72 | void math::ff::negate(u64& out) { 73 | details::modNeg(out, p); 74 | } 75 | 76 | template <> 77 | void math::ff::invert(u64& out) { 78 | details::modInv(out, out, p); 79 | } 80 | 81 | template <> 82 | bool math::ff::equal(const u64& in1, const u64& in2) { 83 | return in1 == in2; 84 | } 85 | 86 | template <> 87 | void math::ff::fromBytes(u64& dest, const unsigned char* src) { 88 | dest = *(const u64*)src; 89 | dest = dest % p; 90 | } 91 | 92 | template <> 93 | void math::ff::toBytes(unsigned char* dest, const u64& src) { 94 | std::memcpy(dest, &src, sizeof(u64)); 95 | } 96 | 97 | template <> 98 | std::string math::ff::toString(const u64& in) { 99 | return util::toHexString(in); 100 | } 101 | -------------------------------------------------------------------------------- /src/scl/math/fields/naf.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_MATH_FIELDS_NAF_H 19 | #define SCL_MATH_FIELDS_NAF_H 20 | 21 | #include 22 | #include 23 | 24 | #include "scl/math/ff.h" 25 | 26 | namespace scl::math::details { 27 | 28 | /** 29 | * @brief Non-adjacent Form encoding of a field element. 30 | * @tparam T a finite field type. 31 | */ 32 | template 33 | struct NafEncoding { 34 | public: 35 | /** 36 | * @brief A type indicating the sign in the encoding. 37 | */ 38 | class Value { 39 | public: 40 | constexpr Value() : Value(0) {} 41 | 42 | /** 43 | * @brief Create a value representing +1. 44 | */ 45 | static constexpr Value createPos() { 46 | return Value{1}; 47 | } 48 | 49 | /** 50 | * @brief Create a value representing -1. 51 | */ 52 | static constexpr Value createNeg() { 53 | return Value{2}; 54 | } 55 | 56 | /** 57 | * @brief Create a value represeting 0. 58 | */ 59 | static constexpr Value createZero() { 60 | return Value{0}; 61 | } 62 | 63 | /** 64 | * @brief Check if this value is +1. 65 | */ 66 | constexpr bool pos() const { 67 | return m_v == 1; 68 | } 69 | 70 | /** 71 | * @brief Check if this value is -1. 72 | */ 73 | constexpr bool neg() const { 74 | return m_v == 2; 75 | } 76 | 77 | /** 78 | * @brief Check if this value is 0. 79 | */ 80 | constexpr bool zero() const { 81 | return m_v == 0; 82 | } 83 | 84 | private: 85 | constexpr Value(unsigned char v) : m_v(v) {} 86 | unsigned char m_v; 87 | }; 88 | 89 | /** 90 | * @brief Maximum size of the encoding. 91 | */ 92 | constexpr static std::size_t MAX_SIZE = T::BIT_SIZE + 1; 93 | 94 | /** 95 | * @brief The trits. 96 | */ 97 | std::array values; 98 | 99 | /** 100 | * @brief The number of meaningful entries in values. 101 | */ 102 | std::size_t size; 103 | }; 104 | 105 | } // namespace scl::math::details 106 | 107 | #endif // SCL_MATH_FIELDS_NAF_H 108 | -------------------------------------------------------------------------------- /src/scl/math/fields/secp256k1_helpers.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_MATH_FIELDS_SECP256K1_HELPERS_H 19 | #define SCL_MATH_FIELDS_SECP256K1_HELPERS_H 20 | 21 | #include "naf.h" 22 | #include "scl/math/curves/secp256k1.h" 23 | #include "scl/math/ec.h" 24 | #include "scl/math/fields/secp256k1_field.h" 25 | #include "scl/math/fields/secp256k1_scalar.h" 26 | 27 | namespace scl::math::details { 28 | 29 | /** 30 | * @brief Check which of two field elements is smaller. 31 | * 32 | * Used in serialization. 33 | */ 34 | bool isSmaller(const FF& lhs, 35 | const FF& rhs); 36 | 37 | /** 38 | * @brief Compute the square root of an element. 39 | * 40 | * Used in serialization. 41 | */ 42 | FF sqrt(const FF& x); 43 | 44 | /** 45 | * @brief Convert a field element out of montgomery representation. 46 | * 47 | * Used in scalar multiplications. 48 | */ 49 | FF fromMonty(const FF& x); 50 | 51 | /** 52 | * @brief Convert a field element into a NAF encoding. 53 | * 54 | * Used in scalar multiplication. 55 | */ 56 | NafEncoding toNaf(const FF& x); 57 | 58 | } // namespace scl::math::details 59 | 60 | #endif // SCL_MATH_FIELDS_SECP256K1_HELPERS_H 61 | -------------------------------------------------------------------------------- /src/scl/math/fields/small_ff.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_MATH_FIELDS_SMALL_FF_H 19 | #define SCL_MATH_FIELDS_SMALL_FF_H 20 | 21 | #include 22 | 23 | namespace scl::math::details { 24 | 25 | /** 26 | * @brief Compute a modular addition on two simple types. 27 | */ 28 | template 29 | void modAdd(T& t, const T& v, const T& m) { 30 | t = t + v; 31 | if (t >= m) { 32 | t = t - m; 33 | } 34 | } 35 | 36 | /** 37 | * @brief Compute a modular subtraction on two simple types. 38 | */ 39 | template 40 | void modSub(T& t, const T& v, const T& m) { 41 | if (v > t) { 42 | t = t + m - v; 43 | } else { 44 | t = t - v; 45 | } 46 | } 47 | 48 | /** 49 | * @brief Compute the additive inverse of a simple type. 50 | */ 51 | template 52 | void modNeg(T& t, const T& m) { 53 | if (t) { 54 | t = m - t; 55 | } 56 | } 57 | 58 | /** 59 | * @brief Compute a modular inverse of a simple type. 60 | */ 61 | template 62 | void modInv(T& t, const T& v, const T& m) { 63 | #define SCL_PARALLEL_ASSIGN(v1, v2, q) \ 64 | do { \ 65 | const auto __temp = v2; \ 66 | (v2) = (v1) - (q)*__temp; \ 67 | (v1) = __temp; \ 68 | } while (0) 69 | 70 | if (v == 0) { 71 | throw std::logic_error("0 not invertible modulo prime"); 72 | } 73 | 74 | S k = 0; 75 | S new_k = 1; 76 | S r = m; 77 | S new_r = v; 78 | 79 | while (new_r != 0) { 80 | const auto q = r / new_r; 81 | SCL_PARALLEL_ASSIGN(k, new_k, q); 82 | SCL_PARALLEL_ASSIGN(r, new_r, q); 83 | } 84 | 85 | #undef SCL_PARALLEL_ASSIGN 86 | 87 | if (k < 0) { 88 | k = k + m; 89 | } 90 | 91 | t = static_cast(k); 92 | } 93 | 94 | } // namespace scl::math::details 95 | 96 | #endif // SCL_MATH_FIELDS_SMALL_FF_H 97 | -------------------------------------------------------------------------------- /src/scl/net/config.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include "scl/net/config.h" 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | using namespace scl; 27 | 28 | namespace { 29 | 30 | void validateIdAndSize(std::size_t id, std::size_t n) { 31 | if (n == 0) { 32 | throw std::invalid_argument("n cannot be zero"); 33 | } 34 | 35 | if (n <= id) { 36 | throw std::invalid_argument("invalid id"); 37 | } 38 | } 39 | 40 | } // namespace 41 | 42 | net::NetworkConfig net::NetworkConfig::load(std::size_t id, 43 | const std::string& filename) { 44 | std::ifstream file(filename); 45 | 46 | if (!file.is_open()) { 47 | throw std::invalid_argument("could not open file"); 48 | } 49 | 50 | std::string line; 51 | std::vector info; 52 | 53 | while (std::getline(file, line)) { 54 | auto a_ = line.find(','); 55 | auto b_ = line.rfind(','); 56 | 57 | if (a_ == std::string::npos || a_ == b_) { 58 | throw std::invalid_argument("invalid entry in config file"); 59 | } 60 | 61 | auto a = static_cast(a_); 62 | auto b = static_cast(b_); 63 | 64 | auto id = std::stoul(std::string(line.begin(), line.begin() + a)); 65 | auto hostname = std::string(line.begin() + a + 1, line.begin() + b); 66 | auto port = std::stoul(std::string(line.begin() + b + 1, line.end())); 67 | info.emplace_back(Party{id, hostname, port}); 68 | } 69 | 70 | validateIdAndSize(id, info.size()); 71 | 72 | return NetworkConfig(id, info); 73 | } 74 | 75 | net::NetworkConfig net::NetworkConfig::localhost(std::size_t id, 76 | std::size_t size, 77 | std::size_t port_base) { 78 | validateIdAndSize(id, size); 79 | 80 | std::vector info; 81 | for (std::size_t i = 0; i < size; ++i) { 82 | std::size_t port = port_base + i; 83 | info.emplace_back(Party{i, "127.0.0.1", port}); 84 | } 85 | 86 | return NetworkConfig(id, info); 87 | } 88 | 89 | void net::NetworkConfig::validate() { 90 | auto n = networkSize(); 91 | 92 | if (static_cast(id()) >= n) { 93 | throw std::invalid_argument("my ID is invalid in config"); 94 | } 95 | 96 | for (std::size_t i = 0; i < n; ++i) { 97 | auto pi = m_parties[i]; 98 | if (static_cast(pi.id) >= n) { 99 | throw std::invalid_argument("invalid ID in config"); 100 | } 101 | for (std::size_t j = i + 1; j < n; ++j) { 102 | auto pj = m_parties[j]; 103 | if (pi.id == pj.id) { 104 | throw std::invalid_argument("config has duplicate party ids"); 105 | } 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/scl/simulation/config.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include "scl/simulation/config.h" 19 | 20 | #include 21 | #include 22 | 23 | using namespace scl; 24 | 25 | void sim::ChannelConfig::Builder::validate() const { 26 | if (m_bandwidth.has_value()) { 27 | if (m_bandwidth.value() == 0) { 28 | throw std::invalid_argument("bandwidth cannot be 0"); 29 | } 30 | } 31 | 32 | if (m_MSS.has_value()) { 33 | if (m_MSS.value() == 0) { 34 | throw std::invalid_argument("MSS cannot be 0"); 35 | } 36 | } 37 | 38 | if (m_package_loss.has_value()) { 39 | if (m_package_loss.value() < 0) { 40 | throw std::invalid_argument("package loss percentage cannot be negative"); 41 | } 42 | if (m_package_loss.value() >= 1) { 43 | throw std::invalid_argument("package loss percentage cannot exceed 100%"); 44 | } 45 | } 46 | 47 | if (m_window_size.has_value()) { 48 | if (m_window_size.value() == 0) { 49 | throw std::invalid_argument("TCP window size cannot be 0"); 50 | } 51 | } 52 | } 53 | 54 | std::ostream& sim::operator<<(std::ostream& os, const ChannelConfig& config) { 55 | if (config.type() == sim::ChannelConfig::NetworkType::TCP) { 56 | os << "SimulationConfig{"; 57 | os << "Type: TCP, "; 58 | os << "Bandwidth: " << config.bandwidth() << " bits/s, "; 59 | os << "RTT: " << config.RTT() << " ms, "; 60 | os << "MSS: " << config.MSS() << " bytes, "; 61 | os << "PackageLoss: " << 100 * config.packetLoss() << "%, "; 62 | os << "WindowSize: " << config.windowSize() << " bytes}"; 63 | } else { 64 | os << "SimulationConfig{INSTANT}"; 65 | } 66 | 67 | return os; 68 | } 69 | 70 | sim::ChannelConfig sim::ChannelConfig::defaultConfig() { 71 | return ChannelConfig::Builder{}.build(); 72 | } 73 | 74 | sim::ChannelConfig sim::ChannelConfig::loopback() { 75 | return ChannelConfig::Builder{}.type(NetworkType::INSTANT).build(); 76 | } 77 | -------------------------------------------------------------------------------- /src/scl/simulation/runtime.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include "scl/simulation/runtime.h" 19 | 20 | #include 21 | 22 | #include "scl/simulation/context.h" 23 | 24 | using namespace scl; 25 | 26 | void sim::details::SimulatorRuntime::schedule( 27 | std::coroutine_handle<> coroutine, 28 | std::function&& predicate) { 29 | m_tq.emplace_back(coroutine, std::move(predicate), m_current_pid); 30 | } 31 | 32 | void sim::details::SimulatorRuntime::schedule(std::coroutine_handle<> coroutine, 33 | util::Time::Duration delay) { 34 | auto view = m_ctx.view(m_current_pid); 35 | const auto last = view.lastEventTimestamp(); 36 | view.recordEvent(Event::sleep(last, delay)); 37 | this->schedule(coroutine); 38 | } 39 | 40 | void sim::details::SimulatorRuntime::deschedule( 41 | std::coroutine_handle<> coroutine) { 42 | m_tq.remove_if( 43 | [&coroutine](const Coro& coro) { return coro.coroutine == coroutine; }); 44 | } 45 | 46 | // void sim::details::SimulatorRuntime::removeCancelledCoros() { 47 | // auto b = m_tq.begin(); 48 | // const auto e = m_tq.end(); 49 | 50 | // while (b != e) { 51 | // const auto& [coro, pred, pid] = *b; 52 | // if (pid != MANAGER_PID && m_ctx.cancellation_map.at(pid)) { 53 | 54 | // } 55 | // } 56 | // } 57 | 58 | std::coroutine_handle<> sim::details::SimulatorRuntime::next() { 59 | auto b = m_tq.begin(); 60 | const auto e = m_tq.end(); 61 | 62 | while (b != e) { 63 | const auto [coro, pred, pid] = *b; 64 | 65 | // if we're about to run the manager coro, then we do not wish 66 | // to check if it's been cancelled. 67 | if (pid != MANAGER_PID && m_ctx.cancellation_map.at(pid)) { 68 | } else if (pred()) { 69 | m_tq.erase(b); 70 | m_current_pid = pid; 71 | 72 | // Event timestamps are computed as 73 | // 74 | // E[i].ts = E[i - 1] + (now - last_startClock) 75 | // 76 | // It is therefore important that startClock is called here, since 77 | // otherwise we may end up counting time spent executing another party (or 78 | // just time spent in the simulation runtime), when we compute the 79 | // timestamp of event i. 80 | if (m_current_pid != MANAGER_PID) { 81 | m_ctx.view(m_current_pid).startClock(); 82 | } 83 | return coro; 84 | } 85 | b++; 86 | } 87 | 88 | return std::noop_coroutine(); 89 | } 90 | -------------------------------------------------------------------------------- /src/scl/simulation/transport.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include "scl/simulation/transport.h" 19 | 20 | using namespace scl; 21 | 22 | void sim::details::Transport::send(sim::ChannelId cid, net::Packet&& packet) { 23 | m_channels[cid.flip()].push_back(std::move(packet)); 24 | } 25 | 26 | void sim::details::Transport::send(sim::ChannelId cid, 27 | const net::Packet& packet) { 28 | std::size_t idx; 29 | for (idx = 0; idx < m_packets.size(); idx++) { 30 | if (m_packets[idx].packet == packet) { 31 | m_packets[idx].count++; 32 | m_channels[cid.flip()].push_back(idx); 33 | return; 34 | } 35 | } 36 | 37 | // no packet found 38 | m_packets.emplace_back(PktAndCount{packet, 1}); 39 | m_channels[cid.flip()].push_back(idx); 40 | } 41 | 42 | bool sim::details::Transport::hasData(ChannelId cid) const { 43 | if (m_channels.contains(cid)) { 44 | return !m_channels.at(cid).empty(); 45 | } 46 | return false; 47 | } 48 | 49 | net::Packet sim::details::Transport::recv(ChannelId cid) { 50 | // define the variable before assignment to silence a bogus 51 | // maybe-uninitialized error by GCC. 52 | PktOrIdx pkt_or_idx; 53 | 54 | pkt_or_idx = std::move(m_channels.at(cid).front()); 55 | m_channels[cid].pop_front(); 56 | 57 | if (pkt_or_idx.index() == 0) { 58 | // packet that was directly moved to us. 59 | return std::get(pkt_or_idx); 60 | } 61 | 62 | const std::size_t idx = std::get(pkt_or_idx); 63 | 64 | if (m_packets[idx].count == 0) { 65 | throw std::runtime_error("uh oh"); 66 | } 67 | 68 | m_packets[idx].count--; 69 | return m_packets[idx].packet; 70 | } 71 | 72 | void sim::details::Transport::cleanUp(GlobalContext& ctx) { 73 | (void)ctx; 74 | } 75 | -------------------------------------------------------------------------------- /src/scl/util/measurement.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include "scl/util/measurement.h" 19 | 20 | #include 21 | 22 | #include "scl/util/time.h" 23 | 24 | using namespace scl; 25 | 26 | template <> 27 | long double util::Measurement::zero() const { 28 | return 0; 29 | } 30 | 31 | template <> 32 | util::Time::Duration util::Measurement::zero() const { 33 | return util::Time::Duration::zero(); 34 | } 35 | 36 | template <> 37 | long double util::Measurement::square(long double v) const { 38 | return v * v; 39 | } 40 | 41 | template <> 42 | util::Time::Duration util::Measurement::square( 43 | util::Time::Duration dur) const { 44 | long double u = dur.count(); 45 | std::chrono::duration w(u * u); 46 | return std::chrono::duration_cast(w); 47 | } 48 | 49 | template <> 50 | long double util::Measurement::sqrt(long double v) const { 51 | return std::sqrt(v); 52 | } 53 | 54 | template <> 55 | util::Time::Duration util::Measurement::sqrt( 56 | util::Time::Duration dur) const { 57 | long double u = std::sqrt(dur.count()); 58 | std::chrono::duration w(u); 59 | return std::chrono::duration_cast(w); 60 | } 61 | 62 | std::ostream& util::operator<<(std::ostream& os, 63 | const util::TimeMeasurement& measurement) { 64 | os << "{" 65 | << "\"mean\": " << util::timeToMillis(measurement.mean()) << ", " 66 | << "\"unit\": \"ms\", " 67 | << "\"std_dev\": " << util::timeToMillis(measurement.stddev()) << "}"; 68 | 69 | return os; 70 | } 71 | 72 | std::ostream& util::operator<<(std::ostream& os, 73 | const util::DataMeasurement& measurement) { 74 | os << "{" 75 | << "\"mean\": " << measurement.mean() << ", " 76 | << "\"unit\": \"B\", " 77 | << "\"std_dev\": " << measurement.stddev() << "}"; 78 | 79 | return os; 80 | } 81 | -------------------------------------------------------------------------------- /src/scl/util/sha3.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include "scl/util/sha3.h" 19 | 20 | namespace { 21 | 22 | const uint64_t keccakf_rndc[24] = { 23 | 0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL, 24 | 0x8000000080008000ULL, 0x000000000000808bULL, 0x0000000080000001ULL, 25 | 0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008aULL, 26 | 0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000aULL, 27 | 0x000000008000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 28 | 0x8000000000008003ULL, 0x8000000000008002ULL, 0x8000000000000080ULL, 29 | 0x000000000000800aULL, 0x800000008000000aULL, 0x8000000080008081ULL, 30 | 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL}; 31 | 32 | const unsigned int keccakf_rotc[24] = {1, 3, 6, 10, 15, 21, 28, 36, 33 | 45, 55, 2, 14, 27, 41, 56, 8, 34 | 25, 43, 62, 18, 39, 61, 20, 44}; 35 | 36 | const unsigned int keccakf_piln[24] = {10, 7, 11, 17, 18, 3, 5, 16, 37 | 8, 21, 24, 4, 15, 23, 19, 13, 38 | 12, 2, 20, 14, 22, 9, 6, 1}; 39 | 40 | uint64_t RotLeft64(uint64_t x, uint64_t y) { 41 | return (x << y) | (x >> ((sizeof(uint64_t) * 8) - y)); 42 | } 43 | 44 | } // namespace 45 | 46 | void scl::util::keccakf(uint64_t state[25]) { 47 | uint64_t t; 48 | uint64_t bc[5]; 49 | 50 | for (std::size_t round = 0; round < 24; ++round) { 51 | for (std::size_t i = 0; i < 5; ++i) { 52 | bc[i] = state[i] ^ state[i + 5] ^ state[i + 10] ^ state[i + 15] ^ 53 | state[i + 20]; 54 | } 55 | 56 | for (std::size_t i = 0; i < 5; ++i) { 57 | t = bc[(i + 4) % 5] ^ RotLeft64(bc[(i + 1) % 5], 1); 58 | for (std::size_t j = 0; j < 25; j += 5) { 59 | state[j + i] ^= t; 60 | } 61 | } 62 | 63 | t = state[1]; 64 | for (std::size_t i = 0; i < 24; ++i) { 65 | const uint64_t v = keccakf_piln[i]; 66 | bc[0] = state[v]; 67 | state[v] = RotLeft64(t, keccakf_rotc[i]); 68 | t = bc[0]; 69 | } 70 | 71 | for (std::size_t j = 0; j < 25; j += 5) { 72 | for (std::size_t i = 0; i < 5; ++i) { 73 | bc[i] = state[j + i]; 74 | } 75 | for (std::size_t i = 0; i < 5; ++i) { 76 | state[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5]; 77 | } 78 | } 79 | 80 | state[0] ^= keccakf_rndc[round]; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/scl/util/str.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include "scl/util/str.h" 19 | 20 | #include 21 | 22 | template <> 23 | std::string scl::util::toHexString(const __uint128_t& v) { 24 | std::string str; 25 | if (v == 0) { 26 | str = "0"; 27 | } else { 28 | std::stringstream ss; 29 | auto top = static_cast(v >> 64); 30 | auto bot = static_cast(v); 31 | ss << std::hex; 32 | if (top > 0) { 33 | ss << top; 34 | } 35 | ss << bot; 36 | str = ss.str(); 37 | } 38 | return str; 39 | } // LCOV_EXCL_LINE 40 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SCL --- Secure Computation Library 2 | # Copyright (C) 2024 Anders Dalskov 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU Affero General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU Affero General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Affero General Public License 15 | # along with this program. If not, see . 16 | 17 | cmake_minimum_required(VERSION 3.5) 18 | 19 | set(SCL_SOURCE_FILES_TEST 20 | scl/util/test_prg.cc 21 | scl/util/test_sha3.cc 22 | scl/util/test_sha256.cc 23 | scl/util/test_ecdsa.cc 24 | scl/util/test_cmdline.cc 25 | scl/util/test_merkle.cc 26 | scl/util/test_bitmap.cc 27 | scl/util/test_measurement.cc 28 | 29 | scl/serialization/test_serializer.cc 30 | 31 | scl/gf7.cc 32 | scl/math/test_mersenne61.cc 33 | scl/math/test_mersenne127.cc 34 | scl/math/test_vector.cc 35 | scl/math/test_matrix.cc 36 | scl/math/test_la.cc 37 | scl/math/test_ff.cc 38 | scl/math/test_z2k.cc 39 | scl/math/test_poly.cc 40 | scl/math/test_array.cc 41 | 42 | scl/math/test_secp256k1.cc 43 | scl/math/test_number.cc 44 | 45 | scl/ss/test_additive.cc 46 | scl/ss/test_shamir.cc 47 | scl/ss/test_feldman.cc 48 | scl/ss/test_pedersen.cc 49 | 50 | scl/coro/test_task.cc 51 | scl/coro/test_batch.cc 52 | 53 | scl/net/util.cc 54 | scl/net/test_config.cc 55 | scl/net/test_loopback.cc 56 | scl/net/test_network.cc 57 | scl/net/test_packet.cc 58 | 59 | scl/protocol/test_protocol.cc 60 | 61 | scl/simulation/test_event.cc 62 | scl/simulation/test_context.cc 63 | scl/simulation/test_config.cc 64 | scl/simulation/test_channel.cc 65 | scl/simulation/test_simulator.cc 66 | ) 67 | 68 | Include(FetchContent) 69 | 70 | # get Catch2 and compile it. We cannot use the system provided 71 | # version, since that is compiled with C++14 which causes linker 72 | # errors... 73 | FetchContent_Declare( 74 | Catch2 75 | GIT_REPOSITORY https://github.com/catchorg/Catch2.git 76 | GIT_TAG v3.4.0 77 | ) 78 | FetchContent_MakeAvailable(Catch2) 79 | 80 | include(CTest) 81 | include(Catch) 82 | 83 | add_compile_definitions(SCL_TEST_DATA_DIR="${CMAKE_SOURCE_DIR}/test/data/") 84 | 85 | add_executable(scl_test ${SCL_SOURCE_FILES_TEST}) 86 | target_link_libraries(scl_test 87 | PRIVATE Catch2::Catch2WithMain 88 | PRIVATE scl 89 | PRIVATE pthread 90 | PRIVATE gmp) 91 | catch_discover_tests(scl_test) 92 | 93 | if(SCL_BUILD_TEST_WITH_COVERAGE) 94 | 95 | if (NOT SCL_GCOV_BIN) 96 | set(SCL_GCOV_BIN "gcov") 97 | endif() 98 | 99 | ## stuff that SCL uses, but which we are not interested in 100 | ## generating coverage of. 101 | set(SCL_COVERAGE_EXCLUDES "") 102 | list(APPEND SCL_COVERAGE_EXCLUDES "'/usr/*'") 103 | list(APPEND SCL_COVERAGE_EXCLUDES "'${CMAKE_BINARY_DIR}/*'") 104 | list(APPEND SCL_COVERAGE_EXCLUDES "'${CMAKE_SOURCE_DIR}/test/*'") 105 | 106 | add_custom_target(coverage 107 | COMMAND lcov --ignore-errors mismatch --gcov-tool ${SCL_GCOV_BIN} -d ${CMAKE_BINARY_DIR} -b ${CMAKE_BINARY_DIR} -z 108 | COMMAND lcov --ignore-errors mismatch --gcov-tool ${SCL_GCOV_BIN} -d ${CMAKE_BINARY_DIR} -b ${CMAKE_BINARY_DIR} -c -i -o cov.base 109 | COMMAND scl_test 110 | COMMAND lcov --ignore-errors mismatch --gcov-tool ${SCL_GCOV_BIN} -d ${CMAKE_BINARY_DIR} -b ${CMAKE_BINARY_DIR} -c -o cov.cap 111 | COMMAND lcov --ignore-errors mismatch --gcov-tool ${SCL_GCOV_BIN} -a cov.base -a cov.cap -o cov.total 112 | COMMAND wc -l cov.total 113 | COMMAND lcov --ignore-errors mismatch --gcov-tool ${SCL_GCOV_BIN} --remove cov.total ${SCL_COVERAGE_EXCLUDES} -o cov.info 114 | COMMAND genhtml --demangle-cpp --ignore-errors mismatch -o coverage cov.info 115 | 116 | WORKING_DIRECTORY ${CMAKE_BINARY_DIR} 117 | BYPRODUCTS cov.base cov.cap cov.total cov.info) 118 | 119 | endif() 120 | -------------------------------------------------------------------------------- /test/data/3_parties.txt: -------------------------------------------------------------------------------- 1 | 1,1.2.3.4,8000 2 | 0,2.3.4.5,5000 3 | 2,5.5.5.5,3000 4 | -------------------------------------------------------------------------------- /test/data/invalid_entry.txt: -------------------------------------------------------------------------------- 1 | a,b 2 | -------------------------------------------------------------------------------- /test/data/invalid_no_entries.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anderspkd/secure-computation-library/69ec0e0110cec92842258c24a93d3b6d98b2c710/test/data/invalid_no_entries.txt -------------------------------------------------------------------------------- /test/scl/coro/test_batch.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include "scl/coro/batch.h" 23 | #include "scl/coro/runtime.h" 24 | #include "scl/coro/task.h" 25 | 26 | using namespace scl; 27 | 28 | namespace { 29 | 30 | coro::Task task() { 31 | co_return 42; 32 | } 33 | 34 | coro::Task batch() { 35 | std::vector> tasks; 36 | tasks.emplace_back(task()); 37 | tasks.emplace_back(task()); 38 | tasks.emplace_back(task()); 39 | 40 | auto rs = co_await coro::batch(std::move(tasks)); 41 | REQUIRE(rs.size() == 3); 42 | REQUIRE(rs[0] == 42); 43 | REQUIRE(rs[1] == 42); 44 | REQUIRE(rs[2] == 42); 45 | } 46 | 47 | } // namespace 48 | 49 | TEST_CASE("Simple batch", "[coro]") { 50 | auto rt = coro::DefaultRuntime::create(); 51 | rt->run(batch()); 52 | } 53 | 54 | namespace { 55 | 56 | coro::Task sleeps() { 57 | using namespace std::chrono_literals; 58 | co_await 100h; 59 | co_return 42; 60 | } 61 | 62 | coro::Task partialBatch() { 63 | std::vector> tasks; 64 | tasks.emplace_back(task()); 65 | tasks.emplace_back(sleeps()); 66 | tasks.emplace_back(task()); 67 | 68 | auto rs = co_await coro::batch(std::move(tasks), 2); 69 | REQUIRE(rs.size() == 3); 70 | REQUIRE(rs[0].has_value()); 71 | REQUIRE_FALSE(rs[1].has_value()); 72 | REQUIRE(rs[2].has_value()); 73 | 74 | REQUIRE(rs[0].value() == 42); 75 | REQUIRE(rs[2].value() == 42); 76 | } 77 | 78 | } // namespace 79 | 80 | TEST_CASE("Partial batch execution", "[coro]") { 81 | auto rt = coro::DefaultRuntime::create(); 82 | rt->run(partialBatch()); 83 | } 84 | -------------------------------------------------------------------------------- /test/scl/coro/test_task.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #include "scl/coro/runtime.h" 22 | #include "scl/coro/task.h" 23 | 24 | using namespace scl; 25 | 26 | namespace { 27 | 28 | coro::Task voidTask(bool& r) { 29 | r = true; 30 | co_return; 31 | } 32 | 33 | } // namespace 34 | 35 | TEST_CASE("void task", "[coro]") { 36 | bool set = false; 37 | auto rt = coro::DefaultRuntime::create(); 38 | 39 | // Tasks are cold start, so not run before being executed by a runtime. 40 | auto void_task = voidTask(set); 41 | REQUIRE(!set); 42 | 43 | rt->run(std::move(void_task)); 44 | 45 | REQUIRE(set); 46 | } 47 | 48 | namespace { 49 | 50 | coro::Task intTask() { 51 | co_return 42; 52 | } 53 | 54 | } // namespace 55 | 56 | TEST_CASE("int task", "[coro]") { 57 | auto rt = coro::DefaultRuntime::create(); 58 | auto r = rt->run(intTask()); 59 | REQUIRE(r == 42); 60 | } 61 | 62 | namespace { 63 | 64 | coro::Task anotherIntTask() { 65 | co_return co_await intTask() + 1; 66 | } 67 | 68 | coro::Task adder() { 69 | auto v0 = co_await intTask(); 70 | auto v1 = co_await anotherIntTask(); 71 | co_return v0 + v1; 72 | } 73 | 74 | } // namespace 75 | 76 | TEST_CASE("adder task", "[coro]") { 77 | auto rt = coro::DefaultRuntime::create(); 78 | // runs until the coroutine returns, even if it awaits. 79 | auto r = rt->run(adder()); 80 | REQUIRE(r == 42 + 43); 81 | } 82 | 83 | namespace { 84 | 85 | coro::Task throws() { 86 | throw std::runtime_error("oops"); 87 | } 88 | 89 | coro::Task voidThrows() { 90 | co_await throws(); 91 | } 92 | 93 | coro::Task nonVoidThrows() { 94 | co_await throws(); 95 | co_return 42; 96 | } 97 | 98 | } // namespace 99 | 100 | TEST_CASE("task throws void", "[coro]") { 101 | auto rt = coro::DefaultRuntime::create(); 102 | REQUIRE_THROWS_MATCHES(rt->run(voidThrows()), 103 | std::runtime_error, 104 | Catch::Matchers::Message("oops")); 105 | } 106 | 107 | TEST_CASE("task throws non-void", "[coro]") { 108 | auto rt = coro::DefaultRuntime::create(); 109 | REQUIRE_THROWS_MATCHES(rt->run(nonVoidThrows()), 110 | std::runtime_error, 111 | Catch::Matchers::Message("oops")); 112 | } 113 | 114 | TEST_CASE("result on unfinished Task", "[coro]") { 115 | auto t1 = nonVoidThrows(); 116 | REQUIRE_THROWS_MATCHES( 117 | t1.result(), 118 | std::logic_error, 119 | Catch::Matchers::Message("result() called on unfinished coroutine")); 120 | } 121 | -------------------------------------------------------------------------------- /test/scl/gf7.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include "./gf7.h" 19 | 20 | #include "scl/math/fields/ff_ops.h" 21 | 22 | using namespace scl; 23 | 24 | using GF7 = test::GaloisField7; 25 | 26 | template <> 27 | void math::ff::convertTo(unsigned char& out, int v) { 28 | auto r = v % 7; 29 | out = r < 0 ? 7 + r : r; 30 | } 31 | 32 | template <> 33 | void math::ff::add(unsigned char& out, const unsigned char& op) { 34 | out = (out + op) % 7; 35 | } 36 | 37 | template <> 38 | void math::ff::subtract(unsigned char& out, const unsigned char& op) { 39 | if (out < op) { 40 | out = 7 + out - op; 41 | } else { 42 | out = out - op; 43 | } 44 | } 45 | 46 | template <> 47 | void math::ff::multiply(unsigned char& out, const unsigned char& op) { 48 | out = (out * op) % 7; 49 | } 50 | 51 | template <> 52 | void math::ff::negate(unsigned char& out) { 53 | out = (7 - out) % 7; 54 | } 55 | 56 | template <> 57 | void math::ff::invert(unsigned char& out) { 58 | unsigned char inv; 59 | switch (out) { 60 | case 1: 61 | case 6: 62 | inv = out; 63 | break; 64 | case 2: 65 | inv = 4; 66 | break; 67 | case 3: 68 | inv = 5; 69 | break; 70 | case 4: 71 | inv = 2; 72 | break; 73 | case 5: 74 | inv = 3; 75 | break; 76 | default: 77 | throw std::logic_error("0 not invertible modulo prime"); 78 | } 79 | out = inv; 80 | } 81 | 82 | template <> 83 | bool math::ff::equal(const unsigned char& in1, const unsigned char& in2) { 84 | return in1 == in2; 85 | } 86 | 87 | template <> 88 | void math::ff::fromBytes(unsigned char& dest, const unsigned char* src) { 89 | dest = *src; 90 | dest = dest % 7; 91 | } 92 | 93 | template <> 94 | void math::ff::toBytes(unsigned char* dest, const unsigned char& src) { 95 | *dest = src; 96 | } 97 | 98 | template <> 99 | std::string math::ff::toString(const unsigned char& in) { 100 | std::stringstream ss; 101 | ss << (int)in; 102 | return ss.str(); 103 | } 104 | -------------------------------------------------------------------------------- /test/scl/gf7.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef TEST_SCL_GF7_H 19 | #define TEST_SCL_GF7_H 20 | 21 | #include 22 | #include 23 | 24 | namespace scl::test { 25 | 26 | struct GaloisField7 { 27 | using ValueType = unsigned char; 28 | constexpr static const char* NAME = "GF(7)"; 29 | constexpr static const std::size_t BYTE_SIZE = 1; 30 | constexpr static const std::size_t BIT_SIZE = 8; 31 | }; 32 | 33 | } // namespace scl::test 34 | 35 | #endif /* TEST_SCL_GF7_H */ 36 | -------------------------------------------------------------------------------- /test/scl/math/fields.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include "../gf7.h" 19 | #include "scl/math/fields/secp256k1_field.h" 20 | #include "scl/math/fields/secp256k1_scalar.h" 21 | #include "scl/math/fp.h" 22 | 23 | namespace scl::test { 24 | 25 | using Mersenne61 = math::Fp<61>; 26 | using Mersenne127 = math::Fp<127>; 27 | using GF7 = math::FF; 28 | 29 | using Secp256k1_Field = math::FF; 30 | using Secp256k1_Order = math::FF; 31 | 32 | } // namespace scl::test 33 | 34 | #define FIELD_DEFS \ 35 | scl::test::Mersenne61, scl::test::Mersenne127, scl::test::GF7, \ 36 | scl::test::Secp256k1_Field, scl::test::Secp256k1_Order 37 | -------------------------------------------------------------------------------- /test/scl/math/test_array.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | 20 | #include "scl/math/array.h" 21 | #include "scl/math/curves/secp256k1.h" 22 | #include "scl/math/ec.h" 23 | #include "scl/math/ff.h" 24 | #include "scl/math/fields/mersenne127.h" 25 | #include "scl/serialization/serializer.h" 26 | 27 | using namespace scl; 28 | using G = math::EC; 29 | using F = G::ScalarField; 30 | 31 | TEST_CASE("Array default init", "[math]") { 32 | const G inf; 33 | math::Array p; 34 | 35 | REQUIRE(p == math::Array{{inf, inf, inf, inf}}); 36 | 37 | const auto zero = F::zero(); 38 | math::Array q; 39 | REQUIRE(q == math::Array{{zero, zero, zero}}); 40 | } 41 | 42 | TEST_CASE("Array operations", "[math]") { 43 | math::Array p = {{F(1), F(2), F(4)}}; 44 | math::Array q = {{F(4), F(2), F(1)}}; 45 | 46 | REQUIRE(p + q == math::Array{{F(5), F(4), F(5)}}); 47 | REQUIRE(p - q == math::Array{{F(-3), F(0), F(3)}}); 48 | REQUIRE(p * q == math::Array{{F(4), F(4), F(4)}}); 49 | REQUIRE(q * p == math::Array{{F(4), F(4), F(4)}}); 50 | } 51 | 52 | TEST_CASE("Array operations mixed", "[math]") { 53 | const auto gen = G::generator(); 54 | math::Array g = {{gen, gen, gen}}; 55 | math::Array f = {{F(44), F(55), F(66)}}; 56 | 57 | REQUIRE(g * f == math::Array{{gen * F(44), gen * F(55), gen * F(66)}}); 58 | REQUIRE(f * g == math::Array{{gen * F(44), gen * F(55), gen * F(66)}}); 59 | } 60 | 61 | TEST_CASE("Array to string", "[math]") { 62 | math::Array p; 63 | REQUIRE(p.toString() == "P{EC{POINT_AT_INFINITY}, EC{POINT_AT_INFINITY}}"); 64 | } 65 | 66 | TEST_CASE("Array serialization", "[math]") { 67 | auto prg = util::PRG::create("prod seri"); 68 | auto prod = math::Array::random(prg); 69 | 70 | using S = seri::Serializer>; 71 | 72 | unsigned char buf[S::sizeOf(prod)]; 73 | S::write(prod, buf); 74 | 75 | math::Array p; 76 | 77 | REQUIRE(p != prod); 78 | 79 | S::read(p, buf); 80 | 81 | REQUIRE(p == prod); 82 | } 83 | -------------------------------------------------------------------------------- /test/scl/math/test_mersenne127.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #include "scl/math/fp.h" 22 | 23 | using namespace scl; 24 | 25 | using Field = math::Fp<127>; 26 | using u128 = __uint128_t; 27 | 28 | TEST_CASE("Mersenne127 defs", "[math][ff]") { 29 | REQUIRE(Field::bitSize() == 127); 30 | REQUIRE(Field::byteSize() == 16); 31 | REQUIRE(std::string(Field::name()) == "Mersenne127"); 32 | } 33 | 34 | TEST_CASE("Mersenne127 to string", "[math][ff]") { 35 | REQUIRE(Field::zero().toString() == "0"); 36 | REQUIRE(Field::one().toString() == "1"); 37 | 38 | Field x(0x7b); 39 | REQUIRE(x.toString() == "7b"); 40 | 41 | REQUIRE(Field::fromString("80000000000000000000000000000000") == 42 | Field::one()); 43 | 44 | Field big = Field::fromString("58797a14d0653d22a05c11c60e1aacf4"); 45 | REQUIRE(big.toString() == "58797a14d0653d22a05c11c60e1aacf4"); 46 | 47 | std::stringstream ss; 48 | ss << x; 49 | REQUIRE(ss.str() == "7b"); 50 | } 51 | 52 | TEST_CASE("Mersenne127 from string", "[math][ff]") { 53 | auto y = Field::fromString("7b"); 54 | REQUIRE(y == Field(0x7b)); 55 | } 56 | 57 | TEST_CASE("Mersenne127 read/write", "[math][ff]") { 58 | Field big = Field::fromString("58797a14d0653d22a05c11c60e1aacf4"); 59 | unsigned char buffer[Field::byteSize()]; 60 | big.write(buffer); 61 | auto y = Field::read(buffer); 62 | REQUIRE(big == y); 63 | 64 | Field x(0x7b); 65 | x.write(buffer); 66 | auto z = Field::read(buffer); 67 | REQUIRE(z == x); 68 | } 69 | -------------------------------------------------------------------------------- /test/scl/math/test_mersenne61.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include "scl/math/fp.h" 23 | 24 | using namespace scl; 25 | 26 | using Field = math::Fp<61>; 27 | 28 | TEST_CASE("Mersenne61 defs", "[math][ff]") { 29 | REQUIRE(std::string(Field::name()) == "Mersenne61"); 30 | REQUIRE(Field::bitSize() == 61); 31 | REQUIRE(Field::byteSize() == 8); 32 | } 33 | 34 | TEST_CASE("Mersenne61 to string", "[math][ff]") { 35 | Field zero = Field::zero(); 36 | Field one = Field::one(); 37 | Field x(0x7b); 38 | Field big(0x41621e); 39 | 40 | REQUIRE(zero.toString() == "0"); 41 | REQUIRE(one.toString() == "1"); 42 | REQUIRE(x.toString() == "7b"); 43 | REQUIRE(big.toString() == "41621e"); 44 | std::stringstream ss; 45 | ss << x; 46 | REQUIRE(ss.str() == "7b"); 47 | } 48 | 49 | TEST_CASE("Mersenne61 from string", "[math][ff]") { 50 | Field x(0x7b); 51 | Field big(0x41621e); 52 | 53 | REQUIRE_THROWS_MATCHES(Field::fromString("012"), 54 | std::invalid_argument, 55 | Catch::Matchers::Message("odd-length hex string")); 56 | REQUIRE_THROWS_MATCHES( 57 | Field::fromString("1g"), 58 | std::invalid_argument, 59 | Catch::Matchers::Message("encountered invalid hex character")); 60 | auto y = Field::fromString("7b"); 61 | REQUIRE(x == y); 62 | auto z = Field::fromString("41621E"); 63 | REQUIRE(z == big); 64 | } 65 | 66 | TEST_CASE("Mersenne61 read/write", "[math][ff]") { 67 | Field x(0x7b); 68 | Field big(0x41621e); 69 | 70 | unsigned char buffer[Field::byteSize()]; 71 | x.write(buffer); 72 | auto y = Field::read(buffer); 73 | REQUIRE(x == y); 74 | big.write(buffer); 75 | auto z = Field::read(buffer); 76 | REQUIRE(z == big); 77 | } 78 | -------------------------------------------------------------------------------- /test/scl/net/test_config.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "scl/net/config.h" 24 | 25 | using namespace scl; 26 | 27 | TEST_CASE("Config read from file", "[net]") { 28 | const auto* filename = SCL_TEST_DATA_DIR "3_parties.txt"; 29 | auto cfg = net::NetworkConfig::load(0, filename); 30 | 31 | REQUIRE(cfg.networkSize() == 3); 32 | REQUIRE(cfg.id() == 0); 33 | auto parties = cfg.parties(); 34 | REQUIRE(parties[0].hostname == "1.2.3.4"); 35 | REQUIRE(parties[0].port == 8000); 36 | REQUIRE(parties[1].hostname == "2.3.4.5"); 37 | REQUIRE(parties[1].port == 5000); 38 | REQUIRE(parties[2].hostname == "5.5.5.5"); 39 | REQUIRE(parties[2].port == 3000); 40 | 41 | std::string invalid_empty = SCL_TEST_DATA_DIR "invalid_no_entries.txt"; 42 | REQUIRE_THROWS_MATCHES(net::NetworkConfig::load(0, invalid_empty), 43 | std::invalid_argument, 44 | Catch::Matchers::Message("n cannot be zero")); 45 | 46 | std::string valid = SCL_TEST_DATA_DIR "3_parties.txt"; 47 | REQUIRE_THROWS_MATCHES(net::NetworkConfig::load(4, valid), 48 | std::invalid_argument, 49 | Catch::Matchers::Message("invalid id")); 50 | 51 | std::string invalid_entry = SCL_TEST_DATA_DIR "invalid_entry.txt"; 52 | REQUIRE_THROWS_MATCHES( 53 | net::NetworkConfig::load(0, invalid_entry), 54 | std::invalid_argument, 55 | Catch::Matchers::Message("invalid entry in config file")); 56 | 57 | std::string invalid_non_existing_file; 58 | REQUIRE_THROWS_MATCHES(net::NetworkConfig::load(0, invalid_non_existing_file), 59 | std::invalid_argument, 60 | Catch::Matchers::Message("could not open file")); 61 | } 62 | 63 | TEST_CASE("Config configure all parties local", "[net]") { 64 | auto cfg = net::NetworkConfig::localhost(0, 5); 65 | REQUIRE(cfg.id() == 0); 66 | REQUIRE(cfg.networkSize() == 5); 67 | std::size_t i = 0; 68 | for (const auto& ci : cfg.parties()) { 69 | REQUIRE(ci.port == DEFAULT_PORT_OFFSET + i++); 70 | REQUIRE(ci.hostname == "127.0.0.1"); 71 | } 72 | } 73 | 74 | TEST_CASE("Config validation", "[net]") { 75 | REQUIRE_THROWS_MATCHES( 76 | net::NetworkConfig(2, {{0, "1.2.3.4", 123}, {1, "4.4.4.4", 444}}), 77 | std::invalid_argument, 78 | Catch::Matchers::Message("my ID is invalid in config")); 79 | 80 | REQUIRE_THROWS_MATCHES( 81 | net::NetworkConfig(1, {{2, "1.2.3.4", 123}, {1, "4.4.4.4", 444}}), 82 | std::invalid_argument, 83 | Catch::Matchers::Message("invalid ID in config")); 84 | 85 | REQUIRE_THROWS_MATCHES( 86 | net::NetworkConfig(1, {{0, "1.2.3.4", 123}, {0, "4.4.4.4", 444}}), 87 | std::invalid_argument, 88 | Catch::Matchers::Message("config has duplicate party ids")); 89 | } 90 | -------------------------------------------------------------------------------- /test/scl/net/test_loopback.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "scl/coro/batch.h" 25 | #include "scl/coro/coroutine.h" 26 | #include "scl/math/fp.h" 27 | #include "scl/math/vector.h" 28 | #include "scl/net/loopback.h" 29 | #include "scl/util/prg.h" 30 | #include "util.h" 31 | 32 | using namespace scl; 33 | 34 | TEST_CASE("Loopback to self close", "[net]") { 35 | auto channel = net::LoopbackChannel::create(); 36 | 37 | net::Packet p; 38 | p << 1 << 2 << 3; 39 | 40 | auto rt = coro::DefaultRuntime::create(); 41 | 42 | rt->run(channel->send(p)); 43 | auto received = rt->run(channel->recv()); 44 | 45 | REQUIRE(received.read() == 1); 46 | REQUIRE(received.read() == 2); 47 | REQUIRE(received.read() == 3); 48 | } 49 | 50 | TEST_CASE("Loopback send/recv", "[net]") { 51 | auto channels = net::LoopbackChannel::createPaired(); 52 | auto chl0 = channels[0]; 53 | auto chl1 = channels[1]; 54 | 55 | net::Packet p; 56 | p << 1 << 2 << 3; 57 | 58 | auto rt = coro::DefaultRuntime::create(); 59 | 60 | rt->run(chl0->send(p)); 61 | auto received = rt->run(chl1->recv()); 62 | 63 | REQUIRE(received.read() == 1); 64 | REQUIRE(received.read() == 2); 65 | REQUIRE(received.read() == 3); 66 | 67 | rt->run(chl1->send(std::move(p))); 68 | auto received1 = rt->run(chl0->recv()); 69 | REQUIRE(received1.read() == 1); 70 | REQUIRE(received1.read() == 2); 71 | REQUIRE(received1.read() == 3); 72 | } 73 | -------------------------------------------------------------------------------- /test/scl/net/test_network.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include "scl/coro/batch.h" 23 | #include "scl/coro/coroutine.h" 24 | #include "scl/net/config.h" 25 | #include "scl/net/network.h" 26 | #include "scl/net/tcp_channel.h" 27 | 28 | using namespace scl; 29 | 30 | TEST_CASE("Network one party", "[net]") { 31 | auto rt = coro::DefaultRuntime::create(); 32 | auto network = 33 | rt->run(net::Network::create(net::NetworkConfig::localhost(0, 1))); 34 | REQUIRE(network.size() == 1); 35 | } 36 | 37 | namespace { 38 | 39 | coro::Task> connect3() { 40 | std::vector> networks; 41 | auto conf0 = net::NetworkConfig::localhost(0, 3); 42 | networks.emplace_back(net::Network::create(conf0)); 43 | 44 | auto conf1 = net::NetworkConfig::localhost(1, 3); 45 | networks.emplace_back(net::Network::create(conf1)); 46 | 47 | auto conf2 = net::NetworkConfig::localhost(2, 3); 48 | networks.emplace_back(net::Network::create(conf2)); 49 | 50 | co_return co_await coro::batch(std::move(networks)); 51 | } 52 | 53 | coro::Task send(net::Channel* channel, int v) { 54 | net::Packet p; 55 | p << v; 56 | co_await channel->send(p); 57 | } 58 | 59 | coro::Task recv(net::Channel* channel) { 60 | net::Packet p = co_await channel->recv(); 61 | co_return p.read(); 62 | } 63 | 64 | } // namespace 65 | 66 | TEST_CASE("Network TCP", "[net]") { 67 | auto rt = coro::DefaultRuntime::create(); 68 | 69 | auto networks = rt->run(connect3()); 70 | 71 | REQUIRE(networks.size() == 3); 72 | 73 | rt->run(send(networks[0].party(1), 123)); 74 | rt->run(send(networks[2].party(0), 456)); 75 | 76 | auto v = rt->run(recv(networks[1].party(0))); 77 | REQUIRE(v == 123); 78 | 79 | auto w = rt->run(recv(networks[0].party(2))); 80 | REQUIRE(w == 456); 81 | } 82 | -------------------------------------------------------------------------------- /test/scl/net/util.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include "util.h" 19 | 20 | using namespace scl; 21 | 22 | int test_port = SCL_DEFAULT_TEST_PORT; 23 | 24 | int test::getPort() { 25 | return test_port++; 26 | } 27 | 28 | bool test::bufferEquals(const unsigned char* a, const unsigned char* b, int n) { 29 | while (n-- > 0 && *a++ == *b++) { 30 | ; 31 | } 32 | return n < 0; 33 | } 34 | -------------------------------------------------------------------------------- /test/scl/net/util.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef TEST_SCL_NET_UTIL_H 19 | #define TEST_SCL_NET_UTIL_H 20 | 21 | namespace scl::test { 22 | 23 | /** 24 | * @brief The default starting point for ports. 25 | */ 26 | #ifndef SCL_DEFAULT_TEST_PORT 27 | #define SCL_DEFAULT_TEST_PORT 14421 28 | #endif 29 | 30 | /** 31 | * @brief Get a fresh port for use in tests that require ports. 32 | * @note Not thread safe. 33 | */ 34 | int getPort(); 35 | 36 | /** 37 | * @brief Test if two buffers are equal. 38 | * @param a the first buffer 39 | * @param b the second buffer 40 | * @param n the number of bytes to check 41 | * @param true if \p a and \p b coincide on the first \p n bytes. 42 | */ 43 | bool bufferEquals(const unsigned char* a, const unsigned char* b, int n); 44 | 45 | } // namespace scl::test 46 | 47 | #endif // TEST_SCL_NET_UTIL_H 48 | -------------------------------------------------------------------------------- /test/scl/protocol/beaver.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_TESTS_PROTOCOL_BEAVER_H 19 | #define SCL_TESTS_PROTOCOL_BEAVER_H 20 | 21 | #include 22 | 23 | #include "./triple.h" 24 | #include "scl/coro/task.h" 25 | #include "scl/protocol/base.h" 26 | #include "scl/protocol/env.h" 27 | #include "scl/protocol/result.h" 28 | 29 | namespace scl::test { 30 | 31 | template 32 | class BeaverMul final : public proto::Protocol { 33 | public: 34 | BeaverMul(SHARE x, SHARE y, Triple triple) 35 | : m_x(x), m_y(y), m_triple(triple) {} 36 | 37 | coro::Task run(proto::Env& env) const override { 38 | net::Packet packet; 39 | 40 | packet << m_x - m_triple.a; // [e] = [x] - [a] 41 | packet << m_y - m_triple.b; // [d] = [y] - [b] 42 | 43 | co_await env.network.party(0)->send(packet); 44 | co_await env.network.party(1)->send(packet); 45 | 46 | net::Packet packet0 = co_await env.network.party(0)->recv(); 47 | net::Packet packet1 = co_await env.network.party(1)->recv(); 48 | 49 | const auto e0 = packet0.read(); 50 | const auto d0 = packet0.read(); 51 | const auto e1 = packet1.read(); 52 | const auto d1 = packet1.read(); 53 | 54 | const auto e = e0 + e1; 55 | const auto d = d0 + d1; 56 | 57 | // [z] = ed + e[b] + d[a] + [c]. Only party 0 adds constants. 58 | auto z = e * m_triple.b + d * m_triple.a + m_triple.c; 59 | if (env.network.myId() == 0) { 60 | z += e * d; 61 | } 62 | 63 | co_return proto::ProtocolResult::done(z); 64 | } 65 | 66 | private: 67 | SHARE m_x; 68 | SHARE m_y; 69 | Triple m_triple; 70 | }; 71 | 72 | } // namespace scl::test 73 | 74 | #endif // SCL_TESTS_PROTOCOL_BEAVER_H 75 | -------------------------------------------------------------------------------- /test/scl/protocol/test_protocol.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #include "./beaver.h" 22 | #include "./triple.h" 23 | #include "scl/coro/runtime.h" 24 | #include "scl/math/fp.h" 25 | #include "scl/net/loopback.h" 26 | #include "scl/net/network.h" 27 | #include "scl/protocol/base.h" 28 | #include "scl/protocol/env.h" 29 | #include "scl/protocol/eval.h" 30 | #include "scl/ss/additive.h" 31 | 32 | using namespace scl; 33 | 34 | using FF = math::Fp<61>; 35 | 36 | auto prg = util::PRG::create(); 37 | auto x = FF(42); 38 | auto y = FF(11); 39 | auto xs = ss::additiveShare(x, 2, prg); 40 | auto ys = ss::additiveShare(y, 2, prg); 41 | auto ts = test::randomTriple2(prg); 42 | 43 | namespace { 44 | 45 | std::array createEnvs() { 46 | auto p0p0 = net::LoopbackChannel::create(); 47 | auto p1p1 = net::LoopbackChannel::create(); 48 | auto p0p1 = net::LoopbackChannel::createPaired(); 49 | 50 | return {proto::createDefaultEnv(net::Network({p0p0, p0p1[0]}, 0)), 51 | proto::createDefaultEnv(net::Network({p1p1, p0p1[1]}, 1))}; 52 | } 53 | 54 | coro::Task runBeaverMulTwoParties() { 55 | auto envs = createEnvs(); 56 | 57 | auto beaver0 = std::make_unique>(xs[0], ys[0], ts[0]); 58 | auto beaver1 = std::make_unique>(xs[1], ys[1], ts[1]); 59 | 60 | std::vector> protocol_evaluations; 61 | protocol_evaluations.emplace_back( 62 | proto::evaluate(std::move(beaver0), envs[0])); 63 | protocol_evaluations.emplace_back( 64 | proto::evaluate(std::move(beaver1), envs[1])); 65 | 66 | std::vector shares = 67 | co_await coro::batch(std::move(protocol_evaluations)); 68 | 69 | co_return shares[0] + shares[1]; 70 | } 71 | 72 | } // namespace 73 | 74 | TEST_CASE("Beaver multiplication protocol", "[proto]") { 75 | auto rt = coro::DefaultRuntime::create(); 76 | auto z = rt->run(runBeaverMulTwoParties()); 77 | REQUIRE(z == x * y); 78 | } 79 | -------------------------------------------------------------------------------- /test/scl/protocol/triple.h: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef SCL_TESTS_PROTOCOL_TRIPLE_H 19 | #define SCL_TESTS_PROTOCOL_TRIPLE_H 20 | 21 | #include 22 | 23 | #include "scl/ss/additive.h" 24 | #include "scl/util/prg.h" 25 | 26 | namespace scl::test { 27 | 28 | template 29 | struct Triple { 30 | Triple(FIELD a, FIELD b, FIELD c) : a(a), b(b), c(c){}; 31 | 32 | FIELD a; 33 | FIELD b; 34 | FIELD c; 35 | }; 36 | 37 | template 38 | std::vector> randomTriple2(util::PRG& prg) { 39 | auto a = FIELD::random(prg); 40 | auto b = FIELD::random(prg); 41 | auto c = a * b; 42 | 43 | auto as = ss::additiveShare(a, 2, prg); 44 | auto bs = ss::additiveShare(b, 2, prg); 45 | auto cs = ss::additiveShare(c, 2, prg); 46 | 47 | return {{as[0], bs[0], cs[0]}, {as[1], bs[1], cs[1]}}; 48 | } 49 | 50 | template 51 | std::ostream& operator<<(std::ostream& os, const Triple& triple) { 52 | return os << triple.a << " " << triple.b << " " << triple.c; 53 | } 54 | 55 | } // namespace scl::test 56 | 57 | #endif // SCL_TESTS_PROTOCOL_TRIPLE_H 58 | -------------------------------------------------------------------------------- /test/scl/simulation/test_channel.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #include "scl/coro/runtime.h" 22 | #include "scl/net/loopback.h" 23 | #include "scl/net/packet.h" 24 | #include "scl/simulation/channel.h" 25 | #include "scl/simulation/config.h" 26 | #include "scl/simulation/context.h" 27 | #include "scl/simulation/event.h" 28 | #include "scl/simulation/runtime.h" 29 | 30 | using namespace scl; 31 | using namespace std::chrono_literals; 32 | 33 | namespace { 34 | 35 | std::array createChannels( 36 | sim::details::GlobalContext& gctx) { 37 | auto transport = std::make_shared(); 38 | sim::details::SimulatedChannel channel01({0, 1}, gctx.view(0), transport); 39 | sim::details::SimulatedChannel channel10({1, 0}, gctx.view(1), transport); 40 | return {channel01, channel10}; 41 | } 42 | 43 | std::size_t getChannelDataEventAmount(std::shared_ptr event_ptr) { 44 | return std::dynamic_pointer_cast(event_ptr)->amount; 45 | } 46 | 47 | } // namespace 48 | 49 | TEST_CASE("SimulatedChannel send/recv", "[sim]") { 50 | auto gctx = sim::details::GlobalContext::create( 51 | 2, 52 | std::make_unique(), 53 | {}); 54 | auto channels = createChannels(gctx); 55 | 56 | gctx.view(0).recordEvent(sim::Event::start()); 57 | gctx.view(1).recordEvent(sim::Event::start()); 58 | 59 | auto rt = sim::details::SimulatorRuntime(gctx); 60 | 61 | net::Packet p; 62 | p << 1 << 2 << 3; 63 | 64 | const std::size_t expected_size = 65 | sizeof(net::Packet::SizeType) + 3 * sizeof(int); 66 | 67 | gctx.view(0).startClock(); 68 | rt.run(channels[0].send(std::move(p))); 69 | REQUIRE(gctx.traces[0].size() == 2); 70 | REQUIRE(gctx.traces[0].back()->type == sim::EventType::SEND); 71 | REQUIRE(getChannelDataEventAmount(gctx.traces[0].back()) == expected_size); 72 | 73 | REQUIRE(gctx.sends[{0, 1}].size() == 1); 74 | auto send_ts = gctx.sends[{0, 1}].front(); 75 | REQUIRE(gctx.traces[0].back()->timestamp == send_ts); 76 | 77 | gctx.view(1).startClock(); 78 | auto pr = rt.run(channels[1].recv()); 79 | REQUIRE(pr.read() == 1); 80 | REQUIRE(pr.read() == 2); 81 | REQUIRE(pr.read() == 3); 82 | 83 | REQUIRE(gctx.traces[1].size() == 2); 84 | REQUIRE(gctx.traces[1].back()->type == sim::EventType::RECV); 85 | REQUIRE(getChannelDataEventAmount(gctx.traces[1].back()) == expected_size); 86 | 87 | REQUIRE(gctx.sends[{0, 1}].empty()); 88 | } 89 | -------------------------------------------------------------------------------- /test/scl/simulation/test_config.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "scl/simulation/config.h" 24 | #include "scl/util/time.h" 25 | 26 | using namespace scl; 27 | using namespace std::chrono_literals; 28 | 29 | namespace { 30 | 31 | template 32 | void approxDuration(util::Time::Duration d, T v, T b) { 33 | if (v > d) { 34 | REQUIRE(v - d <= b); 35 | } else { 36 | REQUIRE(d - v <= b); 37 | } 38 | } 39 | 40 | } // namespace 41 | 42 | TEST_CASE("SimulationConfig default", "[sim]") { 43 | auto cfg = sim::ChannelConfig::defaultConfig(); 44 | 45 | REQUIRE(cfg.bandwidth() == sim::ChannelConfig::DEFAULT_BANDWIDTH); 46 | REQUIRE(cfg.RTT() == sim::ChannelConfig::DEFAULT_RTT); 47 | REQUIRE(cfg.MSS() == sim::ChannelConfig::DEFAULT_MSS); 48 | REQUIRE(cfg.packetLoss() == sim::ChannelConfig::DEFAULT_PACKAGE_LOSS); 49 | REQUIRE(cfg.windowSize() == sim::ChannelConfig::DEFAULT_WINDOW_SIZE); 50 | } 51 | 52 | TEST_CASE("SimulationConfig setters", "[sim]") { 53 | auto cfg_it = sim::ChannelConfig::Builder{}.MSS(5000).build(); 54 | 55 | REQUIRE(cfg_it.MSS() == 5000); 56 | REQUIRE(cfg_it.bandwidth() == sim::ChannelConfig::DEFAULT_BANDWIDTH); 57 | // Assume rest of properties are also defaulted correctly. 58 | } 59 | 60 | TEST_CASE("SimulationConfig validation", "[sim]") { 61 | REQUIRE_THROWS_MATCHES(sim::ChannelConfig::Builder{}.bandwidth(0).build(), 62 | std::invalid_argument, 63 | Catch::Matchers::Message("bandwidth cannot be 0")); 64 | 65 | REQUIRE_THROWS_MATCHES(sim::ChannelConfig::Builder{}.MSS(0).build(), 66 | std::invalid_argument, 67 | Catch::Matchers::Message("MSS cannot be 0")); 68 | 69 | REQUIRE_THROWS_MATCHES( 70 | sim::ChannelConfig::Builder{}.packetLoss(-0.1).build(), 71 | std::invalid_argument, 72 | Catch::Matchers::Message("package loss percentage cannot be negative")); 73 | 74 | REQUIRE_THROWS_MATCHES( 75 | sim::ChannelConfig::Builder{}.packetLoss(1).build(), 76 | std::invalid_argument, 77 | Catch::Matchers::Message("package loss percentage cannot exceed 100%")); 78 | 79 | REQUIRE_THROWS_MATCHES( 80 | sim::ChannelConfig::Builder{}.windowSize(0).build(), 81 | std::invalid_argument, 82 | Catch::Matchers::Message("TCP window size cannot be 0")); 83 | } 84 | 85 | TEST_CASE("SimulationConfig to string", "[sim]") { 86 | std::stringstream ss; 87 | auto cfg = sim::ChannelConfig::Builder{} 88 | .bandwidth(2) 89 | .MSS(10) 90 | .RTT(50) 91 | .packetLoss(0.01) 92 | .windowSize(500) 93 | .build(); 94 | ss << cfg; 95 | // clang-format off 96 | REQUIRE(ss.str() == "SimulationConfig{" 97 | "Type: TCP, " 98 | "Bandwidth: 2 bits/s, " 99 | "RTT: 50 ms, " 100 | "MSS: 10 bytes, " 101 | "PackageLoss: 1%, " 102 | "WindowSize: 500 bytes}"); 103 | // clang-format on 104 | } 105 | 106 | TEST_CASE("SimulationConfig local", "[sim]") { 107 | auto cfg = sim::ChannelConfig::loopback(); 108 | REQUIRE(cfg.type() == sim::ChannelConfig::NetworkType::INSTANT); 109 | std::stringstream ss; 110 | ss << cfg; 111 | REQUIRE(ss.str() == "SimulationConfig{INSTANT}"); 112 | } 113 | -------------------------------------------------------------------------------- /test/scl/simulation/test_context.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include "scl/simulation/channel_id.h" 23 | #include "scl/simulation/config.h" 24 | #include "scl/simulation/context.h" 25 | #include "scl/simulation/event.h" 26 | 27 | using namespace scl; 28 | using namespace std::chrono_literals; 29 | 30 | TEST_CASE("Context", "[sim]") { 31 | auto gctx = sim::details::GlobalContext::create( 32 | 5, 33 | std::make_unique(), 34 | {}); 35 | 36 | REQUIRE(gctx.traces.size() == 5); 37 | 38 | auto view0 = gctx.view(0); 39 | view0.recordEvent(sim::Event::start()); 40 | view0.startClock(); 41 | REQUIRE(view0.elapsedTime() > 0ms); 42 | 43 | view0.recordEvent(sim::Event::closeChannel(100ms, {0, 0})); 44 | auto view1 = gctx.view(1); 45 | REQUIRE(view1.currentTimeOf(0) == 100ms); 46 | } 47 | 48 | TEST_CASE("Context send", "[sim]") { 49 | auto gctx = sim::details::GlobalContext::create( 50 | 5, 51 | std::make_unique(), 52 | {}); 53 | 54 | auto view0 = gctx.view(0); 55 | view0.send(1, 100ms); 56 | REQUIRE(gctx.sends[{0, 1}].front() == 100ms); 57 | 58 | view0.send(1, 150ms); 59 | REQUIRE(gctx.sends[{0, 1}].front() == 100ms); 60 | gctx.sends[{0, 1}].pop_front(); 61 | REQUIRE(gctx.sends[{0, 1}].front() == 150ms); 62 | } 63 | 64 | TEST_CASE("Context recv", "[sim]") { 65 | auto gctx = sim::details::GlobalContext::create( 66 | 5, 67 | std::make_unique(), 68 | {}); 69 | 70 | auto view0 = gctx.view(0); 71 | auto view1 = gctx.view(1); 72 | 73 | view0.send(1, 100ms); 74 | auto dur = view1.recv(0, 10, 100ms); 75 | REQUIRE(dur > 100ms); 76 | 77 | view0.send(1, 0ms); 78 | dur = view1.recv(0, 10, 1s); 79 | // data will already have arrived when recv is called. 80 | REQUIRE(dur == 1s); 81 | } 82 | -------------------------------------------------------------------------------- /test/scl/simulation/test_env.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #include "scl/simulation/config.h" 22 | #include "scl/simulation/context.h" 23 | #include "scl/simulation/env.h" 24 | #include "scl/simulation/event.h" 25 | #include "scl/simulation/mem_channel_buffer.h" 26 | 27 | using namespace scl; 28 | 29 | namespace { 30 | 31 | auto SomeEvent() { 32 | return std::make_shared(sim::Event::Type::START, 33 | util::Time::Duration::zero()); 34 | } 35 | 36 | auto SomeEvent(util::Time::Duration t) { 37 | return std::make_shared(sim::Event::Type::START, t); 38 | } 39 | 40 | auto DefaultNetworkConfig() { 41 | return std::make_shared(); 42 | } 43 | 44 | } // namespace 45 | 46 | TEST_CASE("Simulation env clock", "[sim]") { 47 | using namespace std::chrono_literals; 48 | 49 | auto ctx = sim::Context::Create( 50 | 5, 51 | DefaultNetworkConfig()); 52 | sim::Clock clock(ctx, 0); 53 | 54 | ctx->AddEvent(0, SomeEvent()); 55 | ctx->UpdateCheckpoint(); 56 | 57 | std::this_thread::sleep_for(50ms); 58 | 59 | auto t0 = clock.Read(); 60 | REQUIRE(t0 > 50ms); 61 | REQUIRE(t0 < 75ms); 62 | 63 | std::this_thread::sleep_for(50ms); 64 | auto t1 = clock.Read(); 65 | REQUIRE(t1 > 100ms); 66 | REQUIRE(t1 < 125ms); 67 | 68 | ctx->AddEvent(0, SomeEvent(10 * t1)); 69 | 70 | auto t2 = clock.Read(); 71 | REQUIRE(t2 > 1050ms); 72 | REQUIRE(t2 < 1200ms); 73 | } 74 | 75 | TEST_CASE("Simulation env clock checkpoint", "[sim]") { 76 | using namespace std::chrono_literals; 77 | 78 | auto ctx = sim::Context::Create( 79 | 5, 80 | DefaultNetworkConfig()); 81 | sim::Clock clock(ctx, 0); 82 | 83 | ctx->AddEvent(0, SomeEvent(10ms)); 84 | ctx->UpdateCheckpoint(); 85 | clock.Checkpoint("asd"); 86 | REQUIRE(ctx->Trace(0).size() == 2); 87 | REQUIRE(ctx->Trace(0).back()->EventType() == sim::Event::Type::CHECKPOINT); 88 | REQUIRE(ctx->Trace(0).back()->Timestamp() >= 10ms); 89 | 90 | sim::CheckpointEvent* e = (sim::CheckpointEvent*)ctx->Trace(0).back().get(); 91 | REQUIRE(e->Id() == "asd"); 92 | } 93 | 94 | TEST_CASE("Simulation env thread", "[sim]") { 95 | using namespace std::chrono_literals; 96 | auto ctx = sim::Context::Create( 97 | 5, 98 | DefaultNetworkConfig()); 99 | 100 | ctx->UpdateCheckpoint(); 101 | 102 | sim::ThreadCtx thread(ctx, 0); 103 | sim::Clock clock(ctx, 0); 104 | 105 | ctx->AddEvent(0, SomeEvent(util::Time::Duration(1000ms))); 106 | thread.Sleep(util::Time::Duration(400h)); 107 | 108 | auto t0 = clock.Read(); 109 | REQUIRE(t0 > 1000ms + 400h); 110 | REQUIRE(t0 < 1050ms + 400h); 111 | } 112 | -------------------------------------------------------------------------------- /test/scl/simulation/test_manager.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #include "scl/simulation/config.h" 22 | #include "scl/simulation/context.h" 23 | #include "scl/simulation/manager.h" 24 | #include "scl/simulation/mem_channel_buffer.h" 25 | 26 | using namespace scl; 27 | 28 | TEST_CASE("SingleReplicationManager", "[sim]") { 29 | sim::SingleReplicationManager m({}); 30 | 31 | auto p = m.Protocol(); 32 | REQUIRE(p.empty()); 33 | 34 | REQUIRE_THROWS_MATCHES( 35 | m.Protocol(), 36 | std::logic_error, 37 | Catch::Matchers::Message( 38 | "Protocol called twice on SingleReplicationManager")); 39 | } 40 | 41 | struct DummyManager final : public sim::Manager { 42 | DummyManager() : sim::Manager(1) {} 43 | std::vector> Protocol() override { 44 | return {}; 45 | } 46 | }; 47 | 48 | TEST_CASE("Default Manager methods", "[sim]") { 49 | DummyManager m; 50 | 51 | auto ctx = sim::Context::Create(1, nullptr); 52 | REQUIRE_FALSE(m.Terminate(0, ctx->GetView())); 53 | 54 | // checks that the config returned is of type SimpleNetworkConfig. 55 | auto p = std::dynamic_pointer_cast( 56 | m.NetworkConfiguration()); 57 | REQUIRE(p != nullptr); 58 | } 59 | -------------------------------------------------------------------------------- /test/scl/ss/test_additive.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | 20 | #include "scl/math/fp.h" 21 | #include "scl/ss/additive.h" 22 | #include "scl/util/prg.h" 23 | 24 | using namespace scl; 25 | 26 | TEST_CASE("AdditiveSS", "[ss]") { 27 | using FF = math::Fp<61>; 28 | auto prg = util::PRG::create(); 29 | 30 | auto secret = FF(12345); 31 | 32 | auto shares = ss::additiveShare(secret, 10, prg); 33 | REQUIRE(shares.size() == 10); 34 | REQUIRE(shares.sum() == secret); 35 | 36 | auto x = FF(55555); 37 | auto shr_x = ss::additiveShare(x, 10, prg); 38 | auto share_sum = shares.add(shr_x); 39 | 40 | REQUIRE(share_sum.sum() == secret + x); 41 | } 42 | -------------------------------------------------------------------------------- /test/scl/ss/test_feldman.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #include "scl/math/curves/secp256k1.h" 22 | #include "scl/math/ec.h" 23 | #include "scl/ss/feldman.h" 24 | #include "scl/ss/shamir.h" 25 | #include "scl/util/prg.h" 26 | 27 | using namespace scl; 28 | 29 | using EC = math::EC; 30 | using FF = EC::ScalarField; 31 | 32 | TEST_CASE("Feldman", "[ss]") { 33 | auto prg = util::PRG::create("feldman"); 34 | std::size_t t = 4; 35 | 36 | auto secret = FF(123); 37 | auto sb = ss::feldmanSecretShare(secret, 4, 24, prg); 38 | REQUIRE(sb.commitments[0] == secret * EC::generator()); 39 | REQUIRE(sb.shares.size() == 24); 40 | REQUIRE(sb.commitments.size() == t + 1); 41 | REQUIRE(ss::feldmanVerify({secret, sb.commitments}, 0)); 42 | REQUIRE(ss::feldmanVerify(secret, sb.commitments, 0)); 43 | REQUIRE(ss::feldmanVerify(sb.getShare(22), 23)); 44 | REQUIRE(ss::shamirRecoverP(sb.shares.subVector(5)) == secret); 45 | } 46 | 47 | TEST_CASE("Feldman hom", "[ss]") { 48 | auto prg = util::PRG::create("feldman hom"); 49 | std::size_t t = 4; 50 | 51 | auto s0 = FF(123); 52 | auto s1 = FF(44); 53 | 54 | auto ss0 = ss::feldmanSecretShare(s0, t, 10, prg); 55 | auto ss1 = ss::feldmanSecretShare(s1, t, 10, prg); 56 | 57 | auto ss2 = ss0.shares.add(ss1.shares); 58 | auto com2 = ss0.commitments.add(ss1.commitments); 59 | 60 | // Check that new commitment works for the sum of the secrets. 61 | REQUIRE(ss::feldmanVerify({s0 + s1, com2}, 0)); 62 | // Check that new commitment works for an individual share. 63 | REQUIRE(ss::feldmanVerify({ss2[5], com2}, 6)); 64 | } 65 | -------------------------------------------------------------------------------- /test/scl/util/test_ecdsa.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #include "scl/math/curves/secp256k1.h" 22 | #include "scl/util/hash.h" 23 | #include "scl/util/sign.h" 24 | 25 | using namespace scl; 26 | 27 | TEST_CASE("ECDSA derive", "[util]") { 28 | auto prg = util::PRG::create("ecdsa derive"); 29 | const auto sk = util::ECDSA::SecretKey::random(prg); 30 | const auto pk = util::ECDSA::derive(sk); 31 | REQUIRE(pk == sk * math::EC::generator()); 32 | } 33 | 34 | TEST_CASE("ECDSA sign", "[util]") { 35 | auto prg = util::PRG::create("ecdsa sign"); 36 | const auto m = util::Hash<256>{}.update("message").finalize(); 37 | const auto sk = util::ECDSA::SecretKey::random(prg); 38 | const auto sig = util::ECDSA::Sign(sk, m, prg); 39 | 40 | const auto pk = util::ECDSA::derive(sk); 41 | REQUIRE(util::ECDSA::verify(pk, sig, m)); 42 | 43 | const std::array m_small = {1, 2, 3}; 44 | const auto sig_small = util::ECDSA::Sign(sk, m_small, prg); 45 | REQUIRE(util::ECDSA::verify(pk, sig_small, m_small)); 46 | 47 | REQUIRE_FALSE(util::ECDSA::verify(pk, sig_small, m)); 48 | } 49 | -------------------------------------------------------------------------------- /test/scl/util/test_measurement.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "scl/util/measurement.h" 24 | 25 | using namespace scl; 26 | using namespace std::chrono_literals; 27 | 28 | TEST_CASE("Measurement to string", "[util]") { 29 | util::DataMeasurement dm; 30 | dm.addSample(123.45); 31 | 32 | std::stringstream ss; 33 | ss << dm; 34 | REQUIRE(ss.str() == "{\"mean\": 123.45, \"unit\": \"B\", \"std_dev\": 0}"); 35 | 36 | util::TimeMeasurement tm; 37 | tm.addSample(util::Time::Duration::zero()); 38 | 39 | ss.str(""); 40 | ss << tm; 41 | REQUIRE(ss.str() == "{\"mean\": 0, \"unit\": \"ms\", \"std_dev\": 0}"); 42 | } 43 | 44 | TEST_CASE("Measurement mean and stddev", "[util]") { 45 | util::DataMeasurement dm; 46 | dm.addSample(123.42); 47 | dm.addSample(555.21); 48 | REQUIRE_THAT(dm.mean(), Catch::Matchers::WithinRel(339.315, 0.001)); 49 | REQUIRE_THAT(dm.stddev(), Catch::Matchers::WithinRel(305.322, 0.001)); 50 | 51 | util::TimeMeasurement tm; 52 | tm.addSample(123ms); 53 | tm.addSample(444ms); 54 | REQUIRE(tm.mean() == 283.5ms); 55 | REQUIRE(tm.stddev() == 226.981276ms); 56 | } 57 | 58 | TEST_CASE("Measurement data", "[util]") { 59 | util::DataMeasurement dm; 60 | dm.addSample(2); 61 | dm.addSample(4); 62 | dm.addSample(4); 63 | dm.addSample(4); 64 | dm.addSample(5); 65 | dm.addSample(5); 66 | dm.addSample(7); 67 | dm.addSample(9); 68 | 69 | REQUIRE(dm.size() == 8); 70 | REQUIRE(dm.samples() == std::vector({2, 4, 4, 4, 5, 5, 7, 9})); 71 | } 72 | 73 | TEST_CASE("Measurement time", "[util]") { 74 | util::TimeMeasurement tm; 75 | tm.addSample(2ms); 76 | tm.addSample(4ms); 77 | tm.addSample(4ms); 78 | tm.addSample(4ms); 79 | tm.addSample(5ms); 80 | tm.addSample(5ms); 81 | tm.addSample(7ms); 82 | tm.addSample(9ms); 83 | 84 | REQUIRE(tm.size() == 8); 85 | REQUIRE(tm.samples() == std::vector( 86 | {2ms, 4ms, 4ms, 4ms, 5ms, 5ms, 7ms, 9ms})); 87 | } 88 | 89 | TEST_CASE("Measurement samples", "[util]") { 90 | util::DataMeasurement dm; 91 | REQUIRE(dm.samples().empty()); 92 | 93 | dm.addSample(42); 94 | REQUIRE(dm.size() == 1); 95 | REQUIRE(dm.samples() == std::vector{42}); 96 | 97 | dm.addSample(22); 98 | REQUIRE(dm.size() == 2); 99 | REQUIRE(dm.samples() == std::vector{42, 22}); 100 | } 101 | 102 | TEST_CASE("Measurement median", "[util]") { 103 | util::DataMeasurement dm; 104 | util::TimeMeasurement tm; 105 | 106 | REQUIRE(dm.median() == 0); 107 | REQUIRE(tm.median() == 0s); 108 | 109 | dm.addSample(123); 110 | tm.addSample(123s); 111 | 112 | REQUIRE(dm.median() == 123); 113 | REQUIRE(tm.median() == 123s); 114 | 115 | dm.addSample(442); 116 | tm.addSample(442s); 117 | 118 | REQUIRE(dm.median() == 282.5); 119 | REQUIRE(tm.median() == 282.5s); 120 | } 121 | -------------------------------------------------------------------------------- /test/scl/util/test_merkle.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | 20 | #include "scl/serialization/serializer.h" 21 | #include "scl/util/bitmap.h" 22 | #include "scl/util/hash.h" 23 | #include "scl/util/merkle.h" 24 | 25 | using namespace scl; 26 | 27 | using Mrkl = util::MerkleTree, std::string_view>; 28 | 29 | namespace { 30 | 31 | util::Hash<256>::DigestType hash(std::string_view data) { 32 | return util::Hash<256>{}.update(data).finalize(); 33 | } 34 | 35 | util::Hash<256>::DigestType hash(util::Hash<256>::DigestType left, 36 | util::Hash<256>::DigestType right) { 37 | return util::Hash<256>{}.update(left).update(right).finalize(); 38 | } 39 | 40 | } // namespace 41 | 42 | TEST_CASE("Merkle hash", "[misc]") { 43 | // clang-format off 44 | auto h_abcd = hash( 45 | hash(hash("a"), hash("b")), 46 | hash(hash("c"), hash("d"))); 47 | // clang-format on 48 | 49 | auto m_abcd = Mrkl::hash({"a", "b", "c", "d"}); 50 | REQUIRE(h_abcd == m_abcd); 51 | 52 | // clang-format off 53 | auto h_xyvu = hash( 54 | hash(hash("x"), hash("y")), 55 | hash(hash("v"), hash("u"))); 56 | // clang-format on 57 | 58 | auto h_abcdxyvu = hash(h_abcd, h_xyvu); 59 | 60 | auto m_abcdxyvu = Mrkl::hash({"a", "b", "c", "d", "x", "y", "v", "u"}); 61 | REQUIRE(h_abcdxyvu == m_abcdxyvu); 62 | } 63 | 64 | TEST_CASE("Merkle hash odd size input", "[misc]") { 65 | util::Hash<256>::DigestType z_digest; 66 | z_digest.fill(0); 67 | // clang-format off 68 | auto h_abc = hash( 69 | hash(hash("a"), hash("b")), 70 | hash(hash("c"), hash("c"))); 71 | // clang-format on 72 | 73 | auto m_abc = Mrkl::hash({"a", "b", "c"}); 74 | 75 | REQUIRE(h_abc == m_abc); 76 | } 77 | 78 | TEST_CASE("Merkle prove", "[misc]") { 79 | std::vector data = {"a", "b", "c", "d", "e"}; 80 | auto root = Mrkl::hash(data); 81 | 82 | auto h_ab = hash(hash("a"), hash("b")); 83 | auto h_cd = hash(hash("c"), hash("d")); 84 | auto h_ee = hash(hash("e"), hash("e")); 85 | auto h_abcd = hash(h_ab, h_cd); 86 | auto h_eeee = hash(h_ee, h_ee); 87 | 88 | REQUIRE(root == hash(h_abcd, h_eeee)); 89 | 90 | auto proof = Mrkl::prove(data, 3); 91 | 92 | // path = [H_c, H_ab, H_eeee] 93 | // direction = [left, left, right] (true, true, false) 94 | 95 | REQUIRE(proof.path.size() == 3); 96 | 97 | REQUIRE(proof.direction == 98 | util::Bitmap::fromStdVecBool(std::vector{true, true, false})); 99 | 100 | REQUIRE(proof.path[0] == hash("c")); 101 | REQUIRE(proof.path[1] == h_ab); 102 | REQUIRE(proof.path[2] == h_eeee); 103 | 104 | REQUIRE(Mrkl::verify("d", root, proof)); 105 | 106 | using Sr = seri::Serializer; 107 | 108 | // two vectors. One with three digests, and one with 3 bits that fit into one 109 | // byte. 110 | REQUIRE(Sr::sizeOf(proof) == 2 * sizeof(seri::StlVecSizeType) + 3L * 32 + 1); 111 | 112 | unsigned char buf[2 * sizeof(seri::StlVecSizeType) + 3L * 32 + 1]; 113 | Sr::write(proof, buf); 114 | 115 | Mrkl::Proof p; 116 | Sr::read(p, buf); 117 | 118 | REQUIRE(p.direction == proof.direction); 119 | REQUIRE(p.path.size() == proof.path.size()); 120 | for (std::size_t i = 0; i < proof.path.size(); ++i) { 121 | REQUIRE(p.path[i] == proof.path[i]); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /test/scl/util/test_prg.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "scl/util/prg.h" 27 | 28 | using namespace scl; 29 | 30 | namespace { 31 | 32 | bool looksUniform(const unsigned char* p, std::size_t len) { 33 | std::vector buckets(256, 0); 34 | for (std::size_t i = 0; i < len; ++i) { 35 | buckets[p[i]]++; 36 | } 37 | 38 | bool uniform = true; 39 | for (unsigned int& bv : buckets) { 40 | auto v = 100 * ((double)bv / (double)len); 41 | uniform &= (v >= 0.35) && (v <= 0.65); 42 | } 43 | 44 | return uniform; 45 | } 46 | 47 | } // namespace 48 | 49 | TEST_CASE("PRG construction", "[misc]") { 50 | REQUIRE(util::PRG::seedSize() == 16); 51 | 52 | auto zprg = util::PRG::create(); 53 | 54 | // Number arrived at somewhat by trial-and-error 55 | const auto n = 300000; 56 | unsigned char buffer[n] = {0}; 57 | REQUIRE_FALSE(looksUniform(buffer, n)); 58 | 59 | zprg.next(buffer, n); 60 | 61 | REQUIRE(looksUniform(buffer, n)); 62 | } 63 | 64 | TEST_CASE("PRG predictable", "[misc]") { 65 | unsigned char seed[] = "1234567890abcde"; 66 | auto prg0 = util::PRG::create(seed, 15); 67 | auto prg1 = util::PRG::create(seed, 15); 68 | 69 | REQUIRE(prg0.Seed() == prg1.Seed()); 70 | 71 | auto bytes0 = prg0.next(100); 72 | auto bytes1 = prg1.next(100); 73 | 74 | REQUIRE(bytes0 == bytes1); 75 | 76 | prg0.reset(); 77 | auto bytes00 = prg0.next(100); 78 | REQUIRE(bytes00 == bytes0); 79 | } 80 | 81 | TEST_CASE("PRG generate random bytes", "[misc]") { 82 | auto prg = util::PRG::create(); 83 | 84 | std::vector buffer(100, 0); 85 | prg.next(buffer, 50); 86 | 87 | bool zero = true; 88 | for (std::size_t i = 50; i < 100; ++i) { 89 | zero &= buffer[i] == 0; 90 | } 91 | REQUIRE(zero); 92 | 93 | // very weak check 94 | bool non_zero = false; 95 | for (std::size_t i = 0; i < 50; ++i) { 96 | non_zero |= buffer[i] != 0; 97 | } 98 | REQUIRE(non_zero); 99 | 100 | std::vector buf = {'c', 'a', 't'}; 101 | 102 | prg.next(buf, 0); 103 | REQUIRE(buf == std::vector{'c', 'a', 't'}); 104 | } 105 | 106 | TEST_CASE("PRG invalid calls", "[misc]") { 107 | auto prg = util::PRG::create(); 108 | std::vector buf(10); 109 | 110 | REQUIRE_THROWS_MATCHES(prg.next(buf, 11), 111 | std::invalid_argument, 112 | Catch::Matchers::Message("n exceeds buffer.size()")); 113 | } 114 | 115 | TEST_CASE("PRG truncate seed on create", "[misc]") { 116 | // Seeds are truncated if they exceed PRG::SeedSize() length. 117 | 118 | auto prg0 = util::PRG::create("0123456789abcdef_bar"); 119 | auto prg1 = util::PRG::create("0123456789abcdef_foo"); 120 | 121 | auto bytes0 = prg0.next(100); 122 | auto bytes1 = prg1.next(100); 123 | 124 | REQUIRE(bytes0 == bytes1); 125 | } 126 | -------------------------------------------------------------------------------- /test/scl/util/test_sha256.cc: -------------------------------------------------------------------------------- 1 | /* SCL --- Secure Computation Library 2 | * Copyright (C) 2024 Anders Dalskov 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #include "scl/math/curves/secp256k1.h" 22 | #include "scl/math/ec.h" 23 | #include "scl/util/digest.h" 24 | #include "scl/util/sha256.h" 25 | 26 | using namespace scl; 27 | 28 | TEST_CASE("Sha256 empty hash", "[misc]") { 29 | const static std::array SHA256_empty = { 30 | 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 31 | 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 32 | 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}; 33 | 34 | util::Sha256 hash; 35 | auto digest = hash.finalize(); 36 | REQUIRE(digest.size() == 32); 37 | REQUIRE(digest == SHA256_empty); 38 | } 39 | 40 | TEST_CASE("Sha256 abc hash", "[misc]") { 41 | const static std::array SHA256_abc = { 42 | 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 43 | 0xde, 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 44 | 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad}; 45 | 46 | util::Sha256 hash; 47 | hash.update({'a', 'b', 'c'}); 48 | auto digest = hash.finalize(); 49 | REQUIRE(digest.size() == 32); 50 | REQUIRE(digest == SHA256_abc); 51 | 52 | util::Sha256 hash_; 53 | hash_.update({'a', 'b'}); 54 | hash_.update({'c'}); 55 | auto digest_ = hash_.finalize(); 56 | REQUIRE(digest_.size() == 32); 57 | REQUIRE(digest_ == SHA256_abc); 58 | } 59 | 60 | TEST_CASE("Sha256 hash almost complete chunk", "[misc]") { 61 | const static std::array digest = { 62 | 0x65, 0xa1, 0x6c, 0xb7, 0x86, 0x13, 0x35, 0xd5, 0xac, 0xe3, 0xc6, 63 | 0x07, 0x18, 0xb5, 0x05, 0x2e, 0x44, 0x66, 0x07, 0x26, 0xda, 0x4c, 64 | 0xd1, 0x3b, 0xb7, 0x45, 0x38, 0x1b, 0x23, 0x5a, 0x17, 0x85}; 65 | 66 | const unsigned char data[57] = {0}; 67 | util::Sha256 hash; 68 | hash.update(data, 57); 69 | REQUIRE(hash.finalize() == digest); 70 | } 71 | 72 | TEST_CASE("Sha256 bouncycastle reference", "[misc]") { 73 | // Reference test showing that serialization + hashing is the same as 74 | // bouncycastle in Java. 75 | 76 | using Curve = math::EC; 77 | auto pk = Curve::generator() * math::Number::fromString("a"); 78 | 79 | const auto n = Curve::byteSize(false); 80 | unsigned char buf[n] = {0}; 81 | pk.write(buf, false); 82 | 83 | util::Sha256 hash; 84 | hash.update(buf, n); 85 | 86 | auto d = hash.finalize(); 87 | 88 | std::array target = { 89 | 0xde, 0xc1, 0x6a, 0xc2, 0x78, 0x99, 0xeb, 0xdf, 0x76, 0x0e, 0xaf, 90 | 0x0a, 0x9f, 0x30, 0x95, 0xd1, 0x6a, 0x55, 0xea, 0x59, 0xef, 0x2a, 91 | 0xe1, 0x8e, 0x9d, 0x22, 0x33, 0xd6, 0xbe, 0x82, 0x58, 0x38}; 92 | 93 | REQUIRE(d == target); 94 | } 95 | --------------------------------------------------------------------------------